[SCSI] advansys: Make sdtr_period_tbl a pointer
[linux-2.6/mini2440.git] / drivers / scsi / advansys.c
blob93b1a47ebaf842cbfb7829f8b2228bf5f0902b60
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 #warning this driver is still not properly converted to the DMA API
73 /* Enable driver /proc statistics. */
74 #define ADVANSYS_STATS
76 /* Enable driver tracing. */
77 #undef ADVANSYS_DEBUG
80 * Portable Data Types
82 * Any instance where a 32-bit long or pointer type is assumed
83 * for precision or HW defined structures, the following define
84 * types must be used. In Linux the char, short, and int types
85 * are all consistent at 8, 16, and 32 bits respectively. Pointers
86 * and long types are 64 bits on Alpha and UltraSPARC.
88 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
89 #define ASC_VADDR __u32 /* Virtual address data type. */
90 #define ASC_DCNT __u32 /* Unsigned Data count type. */
91 #define ASC_SDCNT __s32 /* Signed Data count type. */
94 * These macros are used to convert a virtual address to a
95 * 32-bit value. This currently can be used on Linux Alpha
96 * which uses 64-bit virtual address but a 32-bit bus address.
97 * This is likely to break in the future, but doing this now
98 * will give us time to change the HW and FW to handle 64-bit
99 * addresses.
101 #define ASC_VADDR_TO_U32 virt_to_bus
102 #define ASC_U32_TO_VADDR bus_to_virt
104 typedef unsigned char uchar;
106 #ifndef TRUE
107 #define TRUE (1)
108 #endif
109 #ifndef FALSE
110 #define FALSE (0)
111 #endif
113 #define ERR (-1)
114 #define UW_ERR (uint)(0xFFFF)
115 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
117 #define PCI_VENDOR_ID_ASP 0x10cd
118 #define PCI_DEVICE_ID_ASP_1200A 0x1100
119 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
120 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
121 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
122 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
123 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
126 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
127 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
128 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
129 * SRB structure.
131 #define CC_VERY_LONG_SG_LIST 0
132 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
134 #define PortAddr unsigned short /* port address size */
135 #define inp(port) inb(port)
136 #define outp(port, byte) outb((byte), (port))
138 #define inpw(port) inw(port)
139 #define outpw(port, word) outw((word), (port))
141 #define ASC_MAX_SG_QUEUE 7
142 #define ASC_MAX_SG_LIST 255
144 #define ASC_CS_TYPE unsigned short
146 #define ASC_IS_ISA (0x0001)
147 #define ASC_IS_ISAPNP (0x0081)
148 #define ASC_IS_EISA (0x0002)
149 #define ASC_IS_PCI (0x0004)
150 #define ASC_IS_PCI_ULTRA (0x0104)
151 #define ASC_IS_PCMCIA (0x0008)
152 #define ASC_IS_MCA (0x0020)
153 #define ASC_IS_VL (0x0040)
154 #define ASC_IS_WIDESCSI_16 (0x0100)
155 #define ASC_IS_WIDESCSI_32 (0x0200)
156 #define ASC_IS_BIG_ENDIAN (0x8000)
158 #define ASC_CHIP_MIN_VER_VL (0x01)
159 #define ASC_CHIP_MAX_VER_VL (0x07)
160 #define ASC_CHIP_MIN_VER_PCI (0x09)
161 #define ASC_CHIP_MAX_VER_PCI (0x0F)
162 #define ASC_CHIP_VER_PCI_BIT (0x08)
163 #define ASC_CHIP_MIN_VER_ISA (0x11)
164 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
165 #define ASC_CHIP_MAX_VER_ISA (0x27)
166 #define ASC_CHIP_VER_ISA_BIT (0x30)
167 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
168 #define ASC_CHIP_VER_ASYN_BUG (0x21)
169 #define ASC_CHIP_VER_PCI 0x08
170 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
171 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
172 #define ASC_CHIP_MIN_VER_EISA (0x41)
173 #define ASC_CHIP_MAX_VER_EISA (0x47)
174 #define ASC_CHIP_VER_EISA_BIT (0x40)
175 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
176 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
177 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
178 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
180 #define ASC_SCSI_ID_BITS 3
181 #define ASC_SCSI_TIX_TYPE uchar
182 #define ASC_ALL_DEVICE_BIT_SET 0xFF
183 #define ASC_SCSI_BIT_ID_TYPE uchar
184 #define ASC_MAX_TID 7
185 #define ASC_MAX_LUN 7
186 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
187 #define ASC_MAX_SENSE_LEN 32
188 #define ASC_MIN_SENSE_LEN 14
189 #define ASC_SCSI_RESET_HOLD_TIME_US 60
192 * Narrow boards only support 12-byte commands, while wide boards
193 * extend to 16-byte commands.
195 #define ASC_MAX_CDB_LEN 12
196 #define ADV_MAX_CDB_LEN 16
198 #define MS_SDTR_LEN 0x03
199 #define MS_WDTR_LEN 0x02
201 #define ASC_SG_LIST_PER_Q 7
202 #define QS_FREE 0x00
203 #define QS_READY 0x01
204 #define QS_DISC1 0x02
205 #define QS_DISC2 0x04
206 #define QS_BUSY 0x08
207 #define QS_ABORTED 0x40
208 #define QS_DONE 0x80
209 #define QC_NO_CALLBACK 0x01
210 #define QC_SG_SWAP_QUEUE 0x02
211 #define QC_SG_HEAD 0x04
212 #define QC_DATA_IN 0x08
213 #define QC_DATA_OUT 0x10
214 #define QC_URGENT 0x20
215 #define QC_MSG_OUT 0x40
216 #define QC_REQ_SENSE 0x80
217 #define QCSG_SG_XFER_LIST 0x02
218 #define QCSG_SG_XFER_MORE 0x04
219 #define QCSG_SG_XFER_END 0x08
220 #define QD_IN_PROGRESS 0x00
221 #define QD_NO_ERROR 0x01
222 #define QD_ABORTED_BY_HOST 0x02
223 #define QD_WITH_ERROR 0x04
224 #define QD_INVALID_REQUEST 0x80
225 #define QD_INVALID_HOST_NUM 0x81
226 #define QD_INVALID_DEVICE 0x82
227 #define QD_ERR_INTERNAL 0xFF
228 #define QHSTA_NO_ERROR 0x00
229 #define QHSTA_M_SEL_TIMEOUT 0x11
230 #define QHSTA_M_DATA_OVER_RUN 0x12
231 #define QHSTA_M_DATA_UNDER_RUN 0x12
232 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
233 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
234 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
235 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
236 #define QHSTA_D_HOST_ABORT_FAILED 0x23
237 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
238 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
239 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
240 #define QHSTA_M_WTM_TIMEOUT 0x41
241 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
242 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
243 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
244 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
245 #define QHSTA_M_BAD_TAG_CODE 0x46
246 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
247 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
248 #define QHSTA_D_LRAM_CMP_ERROR 0x81
249 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
250 #define ASC_FLAG_SCSIQ_REQ 0x01
251 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
252 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
253 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
254 #define ASC_FLAG_WIN16 0x10
255 #define ASC_FLAG_WIN32 0x20
256 #define ASC_FLAG_ISA_OVER_16MB 0x40
257 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
258 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
259 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
260 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
261 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
262 #define ASC_SCSIQ_CPY_BEG 4
263 #define ASC_SCSIQ_SGHD_CPY_BEG 2
264 #define ASC_SCSIQ_B_FWD 0
265 #define ASC_SCSIQ_B_BWD 1
266 #define ASC_SCSIQ_B_STATUS 2
267 #define ASC_SCSIQ_B_QNO 3
268 #define ASC_SCSIQ_B_CNTL 4
269 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
270 #define ASC_SCSIQ_D_DATA_ADDR 8
271 #define ASC_SCSIQ_D_DATA_CNT 12
272 #define ASC_SCSIQ_B_SENSE_LEN 20
273 #define ASC_SCSIQ_DONE_INFO_BEG 22
274 #define ASC_SCSIQ_D_SRBPTR 22
275 #define ASC_SCSIQ_B_TARGET_IX 26
276 #define ASC_SCSIQ_B_CDB_LEN 28
277 #define ASC_SCSIQ_B_TAG_CODE 29
278 #define ASC_SCSIQ_W_VM_ID 30
279 #define ASC_SCSIQ_DONE_STATUS 32
280 #define ASC_SCSIQ_HOST_STATUS 33
281 #define ASC_SCSIQ_SCSI_STATUS 34
282 #define ASC_SCSIQ_CDB_BEG 36
283 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
284 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
285 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
286 #define ASC_SCSIQ_B_SG_WK_QP 49
287 #define ASC_SCSIQ_B_SG_WK_IX 50
288 #define ASC_SCSIQ_W_ALT_DC1 52
289 #define ASC_SCSIQ_B_LIST_CNT 6
290 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
291 #define ASC_SGQ_B_SG_CNTL 4
292 #define ASC_SGQ_B_SG_HEAD_QP 5
293 #define ASC_SGQ_B_SG_LIST_CNT 6
294 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
295 #define ASC_SGQ_LIST_BEG 8
296 #define ASC_DEF_SCSI1_QNG 4
297 #define ASC_MAX_SCSI1_QNG 4
298 #define ASC_DEF_SCSI2_QNG 16
299 #define ASC_MAX_SCSI2_QNG 32
300 #define ASC_TAG_CODE_MASK 0x23
301 #define ASC_STOP_REQ_RISC_STOP 0x01
302 #define ASC_STOP_ACK_RISC_STOP 0x03
303 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
304 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
305 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
306 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
307 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
308 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
309 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
310 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
311 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
312 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
314 typedef struct asc_scsiq_1 {
315 uchar status;
316 uchar q_no;
317 uchar cntl;
318 uchar sg_queue_cnt;
319 uchar target_id;
320 uchar target_lun;
321 ASC_PADDR data_addr;
322 ASC_DCNT data_cnt;
323 ASC_PADDR sense_addr;
324 uchar sense_len;
325 uchar extra_bytes;
326 } ASC_SCSIQ_1;
328 typedef struct asc_scsiq_2 {
329 ASC_VADDR srb_ptr;
330 uchar target_ix;
331 uchar flag;
332 uchar cdb_len;
333 uchar tag_code;
334 ushort vm_id;
335 } ASC_SCSIQ_2;
337 typedef struct asc_scsiq_3 {
338 uchar done_stat;
339 uchar host_stat;
340 uchar scsi_stat;
341 uchar scsi_msg;
342 } ASC_SCSIQ_3;
344 typedef struct asc_scsiq_4 {
345 uchar cdb[ASC_MAX_CDB_LEN];
346 uchar y_first_sg_list_qp;
347 uchar y_working_sg_qp;
348 uchar y_working_sg_ix;
349 uchar y_res;
350 ushort x_req_count;
351 ushort x_reconnect_rtn;
352 ASC_PADDR x_saved_data_addr;
353 ASC_DCNT x_saved_data_cnt;
354 } ASC_SCSIQ_4;
356 typedef struct asc_q_done_info {
357 ASC_SCSIQ_2 d2;
358 ASC_SCSIQ_3 d3;
359 uchar q_status;
360 uchar q_no;
361 uchar cntl;
362 uchar sense_len;
363 uchar extra_bytes;
364 uchar res;
365 ASC_DCNT remain_bytes;
366 } ASC_QDONE_INFO;
368 typedef struct asc_sg_list {
369 ASC_PADDR addr;
370 ASC_DCNT bytes;
371 } ASC_SG_LIST;
373 typedef struct asc_sg_head {
374 ushort entry_cnt;
375 ushort queue_cnt;
376 ushort entry_to_copy;
377 ushort res;
378 ASC_SG_LIST sg_list[0];
379 } ASC_SG_HEAD;
381 typedef struct asc_scsi_q {
382 ASC_SCSIQ_1 q1;
383 ASC_SCSIQ_2 q2;
384 uchar *cdbptr;
385 ASC_SG_HEAD *sg_head;
386 ushort remain_sg_entry_cnt;
387 ushort next_sg_index;
388 } ASC_SCSI_Q;
390 typedef struct asc_scsi_req_q {
391 ASC_SCSIQ_1 r1;
392 ASC_SCSIQ_2 r2;
393 uchar *cdbptr;
394 ASC_SG_HEAD *sg_head;
395 uchar *sense_ptr;
396 ASC_SCSIQ_3 r3;
397 uchar cdb[ASC_MAX_CDB_LEN];
398 uchar sense[ASC_MIN_SENSE_LEN];
399 } ASC_SCSI_REQ_Q;
401 typedef struct asc_scsi_bios_req_q {
402 ASC_SCSIQ_1 r1;
403 ASC_SCSIQ_2 r2;
404 uchar *cdbptr;
405 ASC_SG_HEAD *sg_head;
406 uchar *sense_ptr;
407 ASC_SCSIQ_3 r3;
408 uchar cdb[ASC_MAX_CDB_LEN];
409 uchar sense[ASC_MIN_SENSE_LEN];
410 } ASC_SCSI_BIOS_REQ_Q;
412 typedef struct asc_risc_q {
413 uchar fwd;
414 uchar bwd;
415 ASC_SCSIQ_1 i1;
416 ASC_SCSIQ_2 i2;
417 ASC_SCSIQ_3 i3;
418 ASC_SCSIQ_4 i4;
419 } ASC_RISC_Q;
421 typedef struct asc_sg_list_q {
422 uchar seq_no;
423 uchar q_no;
424 uchar cntl;
425 uchar sg_head_qp;
426 uchar sg_list_cnt;
427 uchar sg_cur_list_cnt;
428 } ASC_SG_LIST_Q;
430 typedef struct asc_risc_sg_list_q {
431 uchar fwd;
432 uchar bwd;
433 ASC_SG_LIST_Q sg;
434 ASC_SG_LIST sg_list[7];
435 } ASC_RISC_SG_LIST_Q;
437 #define ASCQ_ERR_Q_STATUS 0x0D
438 #define ASCQ_ERR_CUR_QNG 0x17
439 #define ASCQ_ERR_SG_Q_LINKS 0x18
440 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
441 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
442 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
445 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
447 #define ASC_WARN_NO_ERROR 0x0000
448 #define ASC_WARN_IO_PORT_ROTATE 0x0001
449 #define ASC_WARN_EEPROM_CHKSUM 0x0002
450 #define ASC_WARN_IRQ_MODIFIED 0x0004
451 #define ASC_WARN_AUTO_CONFIG 0x0008
452 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
453 #define ASC_WARN_EEPROM_RECOVER 0x0020
454 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
457 * Error code values are set in {ASC/ADV}_DVC_VAR 'err_code'.
459 #define ASC_IERR_NO_CARRIER 0x0001 /* No more carrier memory */
460 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
461 #define ASC_IERR_SET_PC_ADDR 0x0004
462 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
463 #define ASC_IERR_ILLEGAL_CONNECTION 0x0010 /* Illegal cable connection */
464 #define ASC_IERR_SINGLE_END_DEVICE 0x0020 /* SE device on DIFF bus */
465 #define ASC_IERR_REVERSED_CABLE 0x0040 /* Narrow flat cable reversed */
466 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
467 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD device on LVD port */
468 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
469 #define ASC_IERR_NO_BUS_TYPE 0x0400
470 #define ASC_IERR_BIST_PRE_TEST 0x0800 /* BIST pre-test error */
471 #define ASC_IERR_BIST_RAM_TEST 0x1000 /* BIST RAM test error */
472 #define ASC_IERR_BAD_CHIPTYPE 0x2000 /* Invalid chip_type setting */
474 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
475 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
476 #define ASC_MIN_FREE_Q (0x02)
477 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
478 #define ASC_MAX_TOTAL_QNG 240
479 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
480 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
481 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
482 #define ASC_MAX_INRAM_TAG_QNG 16
483 #define ASC_IOADR_GAP 0x10
484 #define ASC_SYN_MAX_OFFSET 0x0F
485 #define ASC_DEF_SDTR_OFFSET 0x0F
486 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
487 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
489 /* The narrow chip only supports a limited selection of transfer rates.
490 * These are encoded in the range 0..7 or 0..15 depending whether the chip
491 * is Ultra-capable or not. These tables let us convert from one to the other.
493 static const unsigned char asc_syn_xfer_period[8] = {
494 25, 30, 35, 40, 50, 60, 70, 85
497 static const unsigned char asc_syn_ultra_xfer_period[16] = {
498 12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107
501 typedef struct ext_msg {
502 uchar msg_type;
503 uchar msg_len;
504 uchar msg_req;
505 union {
506 struct {
507 uchar sdtr_xfer_period;
508 uchar sdtr_req_ack_offset;
509 } sdtr;
510 struct {
511 uchar wdtr_width;
512 } wdtr;
513 struct {
514 uchar mdp_b3;
515 uchar mdp_b2;
516 uchar mdp_b1;
517 uchar mdp_b0;
518 } mdp;
519 } u_ext_msg;
520 uchar res;
521 } EXT_MSG;
523 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
524 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
525 #define wdtr_width u_ext_msg.wdtr.wdtr_width
526 #define mdp_b3 u_ext_msg.mdp_b3
527 #define mdp_b2 u_ext_msg.mdp_b2
528 #define mdp_b1 u_ext_msg.mdp_b1
529 #define mdp_b0 u_ext_msg.mdp_b0
531 typedef struct asc_dvc_cfg {
532 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
533 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
534 ASC_SCSI_BIT_ID_TYPE disc_enable;
535 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
536 uchar chip_scsi_id;
537 uchar isa_dma_speed;
538 uchar isa_dma_channel;
539 uchar chip_version;
540 ushort mcode_date;
541 ushort mcode_version;
542 uchar max_tag_qng[ASC_MAX_TID + 1];
543 uchar *overrun_buf;
544 uchar sdtr_period_offset[ASC_MAX_TID + 1];
545 uchar adapter_info[6];
546 } ASC_DVC_CFG;
548 #define ASC_DEF_DVC_CNTL 0xFFFF
549 #define ASC_DEF_CHIP_SCSI_ID 7
550 #define ASC_DEF_ISA_DMA_SPEED 4
551 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
552 #define ASC_INIT_STATE_END_GET_CFG 0x0002
553 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
554 #define ASC_INIT_STATE_END_SET_CFG 0x0008
555 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
556 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
557 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
558 #define ASC_INIT_STATE_END_INQUIRY 0x0080
559 #define ASC_INIT_RESET_SCSI_DONE 0x0100
560 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
561 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
562 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
563 #define ASC_MIN_TAGGED_CMD 7
564 #define ASC_MAX_SCSI_RESET_WAIT 30
566 struct asc_dvc_var; /* Forward Declaration. */
568 typedef struct asc_dvc_var {
569 PortAddr iop_base;
570 ushort err_code;
571 ushort dvc_cntl;
572 ushort bug_fix_cntl;
573 ushort bus_type;
574 ASC_SCSI_BIT_ID_TYPE init_sdtr;
575 ASC_SCSI_BIT_ID_TYPE sdtr_done;
576 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
577 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
578 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
579 ASC_SCSI_BIT_ID_TYPE start_motor;
580 uchar scsi_reset_wait;
581 uchar chip_no;
582 char is_in_int;
583 uchar max_total_qng;
584 uchar cur_total_qng;
585 uchar in_critical_cnt;
586 uchar last_q_shortage;
587 ushort init_state;
588 uchar cur_dvc_qng[ASC_MAX_TID + 1];
589 uchar max_dvc_qng[ASC_MAX_TID + 1];
590 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
591 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
592 const uchar *sdtr_period_tbl;
593 ASC_DVC_CFG *cfg;
594 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
595 char redo_scam;
596 ushort res2;
597 uchar dos_int13_table[ASC_MAX_TID + 1];
598 ASC_DCNT max_dma_count;
599 ASC_SCSI_BIT_ID_TYPE no_scam;
600 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
601 uchar min_sdtr_index;
602 uchar max_sdtr_index;
603 struct asc_board *drv_ptr;
604 ASC_DCNT uc_break;
605 } ASC_DVC_VAR;
607 typedef struct asc_dvc_inq_info {
608 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
609 } ASC_DVC_INQ_INFO;
611 typedef struct asc_cap_info {
612 ASC_DCNT lba;
613 ASC_DCNT blk_size;
614 } ASC_CAP_INFO;
616 typedef struct asc_cap_info_array {
617 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
618 } ASC_CAP_INFO_ARRAY;
620 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
621 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
622 #define ASC_CNTL_INITIATOR (ushort)0x0001
623 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
624 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
625 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
626 #define ASC_CNTL_NO_SCAM (ushort)0x0010
627 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
628 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
629 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
630 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
631 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
632 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
633 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
634 #define ASC_CNTL_BURST_MODE (ushort)0x2000
635 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
636 #define ASC_EEP_DVC_CFG_BEG_VL 2
637 #define ASC_EEP_MAX_DVC_ADDR_VL 15
638 #define ASC_EEP_DVC_CFG_BEG 32
639 #define ASC_EEP_MAX_DVC_ADDR 45
640 #define ASC_EEP_MAX_RETRY 20
643 * These macros keep the chip SCSI id and ISA DMA speed
644 * bitfields in board order. C bitfields aren't portable
645 * between big and little-endian platforms so they are
646 * not used.
649 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
650 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
651 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
652 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
653 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
654 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
656 typedef struct asceep_config {
657 ushort cfg_lsw;
658 ushort cfg_msw;
659 uchar init_sdtr;
660 uchar disc_enable;
661 uchar use_cmd_qng;
662 uchar start_motor;
663 uchar max_total_qng;
664 uchar max_tag_qng;
665 uchar bios_scan;
666 uchar power_up_wait;
667 uchar no_scam;
668 uchar id_speed; /* low order 4 bits is chip scsi id */
669 /* high order 4 bits is isa dma speed */
670 uchar dos_int13_table[ASC_MAX_TID + 1];
671 uchar adapter_info[6];
672 ushort cntl;
673 ushort chksum;
674 } ASCEEP_CONFIG;
676 #define ASC_EEP_CMD_READ 0x80
677 #define ASC_EEP_CMD_WRITE 0x40
678 #define ASC_EEP_CMD_WRITE_ABLE 0x30
679 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
680 #define ASC_OVERRUN_BSIZE 0x00000048UL
681 #define ASCV_MSGOUT_BEG 0x0000
682 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
683 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
684 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
685 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
686 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
687 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
688 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
689 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
690 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
691 #define ASCV_BREAK_ADDR (ushort)0x0028
692 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
693 #define ASCV_BREAK_CONTROL (ushort)0x002C
694 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
696 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
697 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
698 #define ASCV_MCODE_SIZE_W (ushort)0x0034
699 #define ASCV_STOP_CODE_B (ushort)0x0036
700 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
701 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
702 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
703 #define ASCV_HALTCODE_W (ushort)0x0040
704 #define ASCV_CHKSUM_W (ushort)0x0042
705 #define ASCV_MC_DATE_W (ushort)0x0044
706 #define ASCV_MC_VER_W (ushort)0x0046
707 #define ASCV_NEXTRDY_B (ushort)0x0048
708 #define ASCV_DONENEXT_B (ushort)0x0049
709 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
710 #define ASCV_SCSIBUSY_B (ushort)0x004B
711 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
712 #define ASCV_CURCDB_B (ushort)0x004D
713 #define ASCV_RCLUN_B (ushort)0x004E
714 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
715 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
716 #define ASCV_DISC_ENABLE_B (ushort)0x0052
717 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
718 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
719 #define ASCV_MCODE_CNTL_B (ushort)0x0056
720 #define ASCV_NULL_TARGET_B (ushort)0x0057
721 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
722 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
723 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
724 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
725 #define ASCV_HOST_FLAG_B (ushort)0x005D
726 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
727 #define ASCV_VER_SERIAL_B (ushort)0x0065
728 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
729 #define ASCV_WTM_FLAG_B (ushort)0x0068
730 #define ASCV_RISC_FLAG_B (ushort)0x006A
731 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
732 #define ASC_HOST_FLAG_IN_ISR 0x01
733 #define ASC_HOST_FLAG_ACK_INT 0x02
734 #define ASC_RISC_FLAG_GEN_INT 0x01
735 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
736 #define IOP_CTRL (0x0F)
737 #define IOP_STATUS (0x0E)
738 #define IOP_INT_ACK IOP_STATUS
739 #define IOP_REG_IFC (0x0D)
740 #define IOP_SYN_OFFSET (0x0B)
741 #define IOP_EXTRA_CONTROL (0x0D)
742 #define IOP_REG_PC (0x0C)
743 #define IOP_RAM_ADDR (0x0A)
744 #define IOP_RAM_DATA (0x08)
745 #define IOP_EEP_DATA (0x06)
746 #define IOP_EEP_CMD (0x07)
747 #define IOP_VERSION (0x03)
748 #define IOP_CONFIG_HIGH (0x04)
749 #define IOP_CONFIG_LOW (0x02)
750 #define IOP_SIG_BYTE (0x01)
751 #define IOP_SIG_WORD (0x00)
752 #define IOP_REG_DC1 (0x0E)
753 #define IOP_REG_DC0 (0x0C)
754 #define IOP_REG_SB (0x0B)
755 #define IOP_REG_DA1 (0x0A)
756 #define IOP_REG_DA0 (0x08)
757 #define IOP_REG_SC (0x09)
758 #define IOP_DMA_SPEED (0x07)
759 #define IOP_REG_FLAG (0x07)
760 #define IOP_FIFO_H (0x06)
761 #define IOP_FIFO_L (0x04)
762 #define IOP_REG_ID (0x05)
763 #define IOP_REG_QP (0x03)
764 #define IOP_REG_IH (0x02)
765 #define IOP_REG_IX (0x01)
766 #define IOP_REG_AX (0x00)
767 #define IFC_REG_LOCK (0x00)
768 #define IFC_REG_UNLOCK (0x09)
769 #define IFC_WR_EN_FILTER (0x10)
770 #define IFC_RD_NO_EEPROM (0x10)
771 #define IFC_SLEW_RATE (0x20)
772 #define IFC_ACT_NEG (0x40)
773 #define IFC_INP_FILTER (0x80)
774 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
775 #define SC_SEL (uchar)(0x80)
776 #define SC_BSY (uchar)(0x40)
777 #define SC_ACK (uchar)(0x20)
778 #define SC_REQ (uchar)(0x10)
779 #define SC_ATN (uchar)(0x08)
780 #define SC_IO (uchar)(0x04)
781 #define SC_CD (uchar)(0x02)
782 #define SC_MSG (uchar)(0x01)
783 #define SEC_SCSI_CTL (uchar)(0x80)
784 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
785 #define SEC_SLEW_RATE (uchar)(0x20)
786 #define SEC_ENABLE_FILTER (uchar)(0x10)
787 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
788 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
789 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
790 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
791 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
792 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
793 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
794 #define ASC_MAX_QNO 0xF8
795 #define ASC_DATA_SEC_BEG (ushort)0x0080
796 #define ASC_DATA_SEC_END (ushort)0x0080
797 #define ASC_CODE_SEC_BEG (ushort)0x0080
798 #define ASC_CODE_SEC_END (ushort)0x0080
799 #define ASC_QADR_BEG (0x4000)
800 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
801 #define ASC_QADR_END (ushort)0x7FFF
802 #define ASC_QLAST_ADR (ushort)0x7FC0
803 #define ASC_QBLK_SIZE 0x40
804 #define ASC_BIOS_DATA_QBEG 0xF8
805 #define ASC_MIN_ACTIVE_QNO 0x01
806 #define ASC_QLINK_END 0xFF
807 #define ASC_EEPROM_WORDS 0x10
808 #define ASC_MAX_MGS_LEN 0x10
809 #define ASC_BIOS_ADDR_DEF 0xDC00
810 #define ASC_BIOS_SIZE 0x3800
811 #define ASC_BIOS_RAM_OFF 0x3800
812 #define ASC_BIOS_RAM_SIZE 0x800
813 #define ASC_BIOS_MIN_ADDR 0xC000
814 #define ASC_BIOS_MAX_ADDR 0xEC00
815 #define ASC_BIOS_BANK_SIZE 0x0400
816 #define ASC_MCODE_START_ADDR 0x0080
817 #define ASC_CFG0_HOST_INT_ON 0x0020
818 #define ASC_CFG0_BIOS_ON 0x0040
819 #define ASC_CFG0_VERA_BURST_ON 0x0080
820 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
821 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
822 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
823 #define ASC_CFG_MSW_CLR_MASK 0x3080
824 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
825 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
826 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
827 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
828 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
829 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
830 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
831 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
832 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
833 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
834 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
835 #define CSW_HALTED (ASC_CS_TYPE)0x0010
836 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
837 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
838 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
839 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
840 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
841 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
842 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
843 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
844 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
845 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
846 #define CC_CHIP_RESET (uchar)0x80
847 #define CC_SCSI_RESET (uchar)0x40
848 #define CC_HALT (uchar)0x20
849 #define CC_SINGLE_STEP (uchar)0x10
850 #define CC_DMA_ABLE (uchar)0x08
851 #define CC_TEST (uchar)0x04
852 #define CC_BANK_ONE (uchar)0x02
853 #define CC_DIAG (uchar)0x01
854 #define ASC_1000_ID0W 0x04C1
855 #define ASC_1000_ID0W_FIX 0x00C1
856 #define ASC_1000_ID1B 0x25
857 #define ASC_EISA_REV_IOP_MASK (0x0C83)
858 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
859 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
860 #define INS_HALTINT (ushort)0x6281
861 #define INS_HALT (ushort)0x6280
862 #define INS_SINT (ushort)0x6200
863 #define INS_RFLAG_WTM (ushort)0x7380
864 #define ASC_MC_SAVE_CODE_WSIZE 0x500
865 #define ASC_MC_SAVE_DATA_WSIZE 0x40
867 typedef struct asc_mc_saved {
868 ushort data[ASC_MC_SAVE_DATA_WSIZE];
869 ushort code[ASC_MC_SAVE_CODE_WSIZE];
870 } ASC_MC_SAVED;
872 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
873 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
874 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
875 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
876 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
877 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
878 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
879 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
880 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
881 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
882 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
883 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
884 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
885 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
886 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
887 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
888 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
889 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
890 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
891 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
892 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
893 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
894 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
895 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
896 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
897 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
898 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
899 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
900 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
901 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
902 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
903 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
904 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
905 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
906 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
907 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
908 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
909 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
910 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
911 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
912 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
913 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
914 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
915 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
916 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
917 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
918 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
919 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
920 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
921 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
922 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
923 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
924 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
925 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
926 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
927 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
928 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
929 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
930 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
931 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
932 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
933 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
934 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
935 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
936 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
937 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
938 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
941 * Portable Data Types
943 * Any instance where a 32-bit long or pointer type is assumed
944 * for precision or HW defined structures, the following define
945 * types must be used. In Linux the char, short, and int types
946 * are all consistent at 8, 16, and 32 bits respectively. Pointers
947 * and long types are 64 bits on Alpha and UltraSPARC.
949 #define ADV_PADDR __u32 /* Physical address data type. */
950 #define ADV_VADDR __u32 /* Virtual address data type. */
951 #define ADV_DCNT __u32 /* Unsigned Data count type. */
952 #define ADV_SDCNT __s32 /* Signed Data count type. */
955 * These macros are used to convert a virtual address to a
956 * 32-bit value. This currently can be used on Linux Alpha
957 * which uses 64-bit virtual address but a 32-bit bus address.
958 * This is likely to break in the future, but doing this now
959 * will give us time to change the HW and FW to handle 64-bit
960 * addresses.
962 #define ADV_VADDR_TO_U32 virt_to_bus
963 #define ADV_U32_TO_VADDR bus_to_virt
965 #define AdvPortAddr void __iomem * /* Virtual memory address size */
968 * Define Adv Library required memory access macros.
970 #define ADV_MEM_READB(addr) readb(addr)
971 #define ADV_MEM_READW(addr) readw(addr)
972 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
973 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
974 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
976 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
979 * Define total number of simultaneous maximum element scatter-gather
980 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
981 * maximum number of outstanding commands per wide host adapter. Each
982 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
983 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
984 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
985 * structures or 255 scatter-gather elements.
988 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
991 * Define Adv Library required maximum number of scatter-gather
992 * elements per request.
994 #define ADV_MAX_SG_LIST 255
996 /* Number of SG blocks needed. */
997 #define ADV_NUM_SG_BLOCK \
998 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1000 /* Total contiguous memory needed for SG blocks. */
1001 #define ADV_SG_TOTAL_MEM_SIZE \
1002 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1004 #define ADV_PAGE_SIZE PAGE_SIZE
1006 #define ADV_NUM_PAGE_CROSSING \
1007 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1009 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
1010 #define ADV_EEP_DVC_CFG_END (0x15)
1011 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1012 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
1014 #define ADV_EEP_DELAY_MS 100
1016 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1017 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1019 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1020 * For later ICs Bit 13 controls whether the CIS (Card Information
1021 * Service Section) is loaded from EEPROM.
1023 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1024 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1026 * ASC38C1600 Bit 11
1028 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1029 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1030 * Function 0 will specify INT B.
1032 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1033 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1034 * Function 1 will specify INT A.
1036 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1038 typedef struct adveep_3550_config {
1039 /* Word Offset, Description */
1041 ushort cfg_lsw; /* 00 power up initialization */
1042 /* bit 13 set - Term Polarity Control */
1043 /* bit 14 set - BIOS Enable */
1044 /* bit 15 set - Big Endian Mode */
1045 ushort cfg_msw; /* 01 unused */
1046 ushort disc_enable; /* 02 disconnect enable */
1047 ushort wdtr_able; /* 03 Wide DTR able */
1048 ushort sdtr_able; /* 04 Synchronous DTR able */
1049 ushort start_motor; /* 05 send start up motor */
1050 ushort tagqng_able; /* 06 tag queuing able */
1051 ushort bios_scan; /* 07 BIOS device control */
1052 ushort scam_tolerant; /* 08 no scam */
1054 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1055 uchar bios_boot_delay; /* power up wait */
1057 uchar scsi_reset_delay; /* 10 reset delay */
1058 uchar bios_id_lun; /* first boot device scsi id & lun */
1059 /* high nibble is lun */
1060 /* low nibble is scsi id */
1062 uchar termination; /* 11 0 - automatic */
1063 /* 1 - low off / high off */
1064 /* 2 - low off / high on */
1065 /* 3 - low on / high on */
1066 /* There is no low on / high off */
1068 uchar reserved1; /* reserved byte (not used) */
1070 ushort bios_ctrl; /* 12 BIOS control bits */
1071 /* bit 0 BIOS don't act as initiator. */
1072 /* bit 1 BIOS > 1 GB support */
1073 /* bit 2 BIOS > 2 Disk Support */
1074 /* bit 3 BIOS don't support removables */
1075 /* bit 4 BIOS support bootable CD */
1076 /* bit 5 BIOS scan enabled */
1077 /* bit 6 BIOS support multiple LUNs */
1078 /* bit 7 BIOS display of message */
1079 /* bit 8 SCAM disabled */
1080 /* bit 9 Reset SCSI bus during init. */
1081 /* bit 10 */
1082 /* bit 11 No verbose initialization. */
1083 /* bit 12 SCSI parity enabled */
1084 /* bit 13 */
1085 /* bit 14 */
1086 /* bit 15 */
1087 ushort ultra_able; /* 13 ULTRA speed able */
1088 ushort reserved2; /* 14 reserved */
1089 uchar max_host_qng; /* 15 maximum host queuing */
1090 uchar max_dvc_qng; /* maximum per device queuing */
1091 ushort dvc_cntl; /* 16 control bit for driver */
1092 ushort bug_fix; /* 17 control bit for bug fix */
1093 ushort serial_number_word1; /* 18 Board serial number word 1 */
1094 ushort serial_number_word2; /* 19 Board serial number word 2 */
1095 ushort serial_number_word3; /* 20 Board serial number word 3 */
1096 ushort check_sum; /* 21 EEP check sum */
1097 uchar oem_name[16]; /* 22 OEM name */
1098 ushort dvc_err_code; /* 30 last device driver error code */
1099 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1100 ushort adv_err_addr; /* 32 last uc error address */
1101 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1102 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1103 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1104 ushort num_of_err; /* 36 number of error */
1105 } ADVEEP_3550_CONFIG;
1107 typedef struct adveep_38C0800_config {
1108 /* Word Offset, Description */
1110 ushort cfg_lsw; /* 00 power up initialization */
1111 /* bit 13 set - Load CIS */
1112 /* bit 14 set - BIOS Enable */
1113 /* bit 15 set - Big Endian Mode */
1114 ushort cfg_msw; /* 01 unused */
1115 ushort disc_enable; /* 02 disconnect enable */
1116 ushort wdtr_able; /* 03 Wide DTR able */
1117 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1118 ushort start_motor; /* 05 send start up motor */
1119 ushort tagqng_able; /* 06 tag queuing able */
1120 ushort bios_scan; /* 07 BIOS device control */
1121 ushort scam_tolerant; /* 08 no scam */
1123 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1124 uchar bios_boot_delay; /* power up wait */
1126 uchar scsi_reset_delay; /* 10 reset delay */
1127 uchar bios_id_lun; /* first boot device scsi id & lun */
1128 /* high nibble is lun */
1129 /* low nibble is scsi id */
1131 uchar termination_se; /* 11 0 - automatic */
1132 /* 1 - low off / high off */
1133 /* 2 - low off / high on */
1134 /* 3 - low on / high on */
1135 /* There is no low on / high off */
1137 uchar termination_lvd; /* 11 0 - automatic */
1138 /* 1 - low off / high off */
1139 /* 2 - low off / high on */
1140 /* 3 - low on / high on */
1141 /* There is no low on / high off */
1143 ushort bios_ctrl; /* 12 BIOS control bits */
1144 /* bit 0 BIOS don't act as initiator. */
1145 /* bit 1 BIOS > 1 GB support */
1146 /* bit 2 BIOS > 2 Disk Support */
1147 /* bit 3 BIOS don't support removables */
1148 /* bit 4 BIOS support bootable CD */
1149 /* bit 5 BIOS scan enabled */
1150 /* bit 6 BIOS support multiple LUNs */
1151 /* bit 7 BIOS display of message */
1152 /* bit 8 SCAM disabled */
1153 /* bit 9 Reset SCSI bus during init. */
1154 /* bit 10 */
1155 /* bit 11 No verbose initialization. */
1156 /* bit 12 SCSI parity enabled */
1157 /* bit 13 */
1158 /* bit 14 */
1159 /* bit 15 */
1160 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1161 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1162 uchar max_host_qng; /* 15 maximum host queueing */
1163 uchar max_dvc_qng; /* maximum per device queuing */
1164 ushort dvc_cntl; /* 16 control bit for driver */
1165 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1166 ushort serial_number_word1; /* 18 Board serial number word 1 */
1167 ushort serial_number_word2; /* 19 Board serial number word 2 */
1168 ushort serial_number_word3; /* 20 Board serial number word 3 */
1169 ushort check_sum; /* 21 EEP check sum */
1170 uchar oem_name[16]; /* 22 OEM name */
1171 ushort dvc_err_code; /* 30 last device driver error code */
1172 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1173 ushort adv_err_addr; /* 32 last uc error address */
1174 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1175 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1176 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1177 ushort reserved36; /* 36 reserved */
1178 ushort reserved37; /* 37 reserved */
1179 ushort reserved38; /* 38 reserved */
1180 ushort reserved39; /* 39 reserved */
1181 ushort reserved40; /* 40 reserved */
1182 ushort reserved41; /* 41 reserved */
1183 ushort reserved42; /* 42 reserved */
1184 ushort reserved43; /* 43 reserved */
1185 ushort reserved44; /* 44 reserved */
1186 ushort reserved45; /* 45 reserved */
1187 ushort reserved46; /* 46 reserved */
1188 ushort reserved47; /* 47 reserved */
1189 ushort reserved48; /* 48 reserved */
1190 ushort reserved49; /* 49 reserved */
1191 ushort reserved50; /* 50 reserved */
1192 ushort reserved51; /* 51 reserved */
1193 ushort reserved52; /* 52 reserved */
1194 ushort reserved53; /* 53 reserved */
1195 ushort reserved54; /* 54 reserved */
1196 ushort reserved55; /* 55 reserved */
1197 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1198 ushort cisprt_msw; /* 57 CIS PTR MSW */
1199 ushort subsysvid; /* 58 SubSystem Vendor ID */
1200 ushort subsysid; /* 59 SubSystem ID */
1201 ushort reserved60; /* 60 reserved */
1202 ushort reserved61; /* 61 reserved */
1203 ushort reserved62; /* 62 reserved */
1204 ushort reserved63; /* 63 reserved */
1205 } ADVEEP_38C0800_CONFIG;
1207 typedef struct adveep_38C1600_config {
1208 /* Word Offset, Description */
1210 ushort cfg_lsw; /* 00 power up initialization */
1211 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1212 /* clear - Func. 0 INTA, Func. 1 INTB */
1213 /* bit 13 set - Load CIS */
1214 /* bit 14 set - BIOS Enable */
1215 /* bit 15 set - Big Endian Mode */
1216 ushort cfg_msw; /* 01 unused */
1217 ushort disc_enable; /* 02 disconnect enable */
1218 ushort wdtr_able; /* 03 Wide DTR able */
1219 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1220 ushort start_motor; /* 05 send start up motor */
1221 ushort tagqng_able; /* 06 tag queuing able */
1222 ushort bios_scan; /* 07 BIOS device control */
1223 ushort scam_tolerant; /* 08 no scam */
1225 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1226 uchar bios_boot_delay; /* power up wait */
1228 uchar scsi_reset_delay; /* 10 reset delay */
1229 uchar bios_id_lun; /* first boot device scsi id & lun */
1230 /* high nibble is lun */
1231 /* low nibble is scsi id */
1233 uchar termination_se; /* 11 0 - automatic */
1234 /* 1 - low off / high off */
1235 /* 2 - low off / high on */
1236 /* 3 - low on / high on */
1237 /* There is no low on / high off */
1239 uchar termination_lvd; /* 11 0 - automatic */
1240 /* 1 - low off / high off */
1241 /* 2 - low off / high on */
1242 /* 3 - low on / high on */
1243 /* There is no low on / high off */
1245 ushort bios_ctrl; /* 12 BIOS control bits */
1246 /* bit 0 BIOS don't act as initiator. */
1247 /* bit 1 BIOS > 1 GB support */
1248 /* bit 2 BIOS > 2 Disk Support */
1249 /* bit 3 BIOS don't support removables */
1250 /* bit 4 BIOS support bootable CD */
1251 /* bit 5 BIOS scan enabled */
1252 /* bit 6 BIOS support multiple LUNs */
1253 /* bit 7 BIOS display of message */
1254 /* bit 8 SCAM disabled */
1255 /* bit 9 Reset SCSI bus during init. */
1256 /* bit 10 Basic Integrity Checking disabled */
1257 /* bit 11 No verbose initialization. */
1258 /* bit 12 SCSI parity enabled */
1259 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1260 /* bit 14 */
1261 /* bit 15 */
1262 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1263 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1264 uchar max_host_qng; /* 15 maximum host queueing */
1265 uchar max_dvc_qng; /* maximum per device queuing */
1266 ushort dvc_cntl; /* 16 control bit for driver */
1267 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1268 ushort serial_number_word1; /* 18 Board serial number word 1 */
1269 ushort serial_number_word2; /* 19 Board serial number word 2 */
1270 ushort serial_number_word3; /* 20 Board serial number word 3 */
1271 ushort check_sum; /* 21 EEP check sum */
1272 uchar oem_name[16]; /* 22 OEM name */
1273 ushort dvc_err_code; /* 30 last device driver error code */
1274 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1275 ushort adv_err_addr; /* 32 last uc error address */
1276 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1277 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1278 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1279 ushort reserved36; /* 36 reserved */
1280 ushort reserved37; /* 37 reserved */
1281 ushort reserved38; /* 38 reserved */
1282 ushort reserved39; /* 39 reserved */
1283 ushort reserved40; /* 40 reserved */
1284 ushort reserved41; /* 41 reserved */
1285 ushort reserved42; /* 42 reserved */
1286 ushort reserved43; /* 43 reserved */
1287 ushort reserved44; /* 44 reserved */
1288 ushort reserved45; /* 45 reserved */
1289 ushort reserved46; /* 46 reserved */
1290 ushort reserved47; /* 47 reserved */
1291 ushort reserved48; /* 48 reserved */
1292 ushort reserved49; /* 49 reserved */
1293 ushort reserved50; /* 50 reserved */
1294 ushort reserved51; /* 51 reserved */
1295 ushort reserved52; /* 52 reserved */
1296 ushort reserved53; /* 53 reserved */
1297 ushort reserved54; /* 54 reserved */
1298 ushort reserved55; /* 55 reserved */
1299 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1300 ushort cisprt_msw; /* 57 CIS PTR MSW */
1301 ushort subsysvid; /* 58 SubSystem Vendor ID */
1302 ushort subsysid; /* 59 SubSystem ID */
1303 ushort reserved60; /* 60 reserved */
1304 ushort reserved61; /* 61 reserved */
1305 ushort reserved62; /* 62 reserved */
1306 ushort reserved63; /* 63 reserved */
1307 } ADVEEP_38C1600_CONFIG;
1310 * EEPROM Commands
1312 #define ASC_EEP_CMD_DONE 0x0200
1314 /* bios_ctrl */
1315 #define BIOS_CTRL_BIOS 0x0001
1316 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
1317 #define BIOS_CTRL_GT_2_DISK 0x0004
1318 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1319 #define BIOS_CTRL_BOOTABLE_CD 0x0010
1320 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
1321 #define BIOS_CTRL_DISPLAY_MSG 0x0080
1322 #define BIOS_CTRL_NO_SCAM 0x0100
1323 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1324 #define BIOS_CTRL_INIT_VERBOSE 0x0800
1325 #define BIOS_CTRL_SCSI_PARITY 0x1000
1326 #define BIOS_CTRL_AIPP_DIS 0x2000
1328 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1330 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1333 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1334 * a special 16K Adv Library and Microcode version. After the issue is
1335 * resolved, should restore 32K support.
1337 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1339 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1342 * Byte I/O register address from base of 'iop_base'.
1344 #define IOPB_INTR_STATUS_REG 0x00
1345 #define IOPB_CHIP_ID_1 0x01
1346 #define IOPB_INTR_ENABLES 0x02
1347 #define IOPB_CHIP_TYPE_REV 0x03
1348 #define IOPB_RES_ADDR_4 0x04
1349 #define IOPB_RES_ADDR_5 0x05
1350 #define IOPB_RAM_DATA 0x06
1351 #define IOPB_RES_ADDR_7 0x07
1352 #define IOPB_FLAG_REG 0x08
1353 #define IOPB_RES_ADDR_9 0x09
1354 #define IOPB_RISC_CSR 0x0A
1355 #define IOPB_RES_ADDR_B 0x0B
1356 #define IOPB_RES_ADDR_C 0x0C
1357 #define IOPB_RES_ADDR_D 0x0D
1358 #define IOPB_SOFT_OVER_WR 0x0E
1359 #define IOPB_RES_ADDR_F 0x0F
1360 #define IOPB_MEM_CFG 0x10
1361 #define IOPB_RES_ADDR_11 0x11
1362 #define IOPB_GPIO_DATA 0x12
1363 #define IOPB_RES_ADDR_13 0x13
1364 #define IOPB_FLASH_PAGE 0x14
1365 #define IOPB_RES_ADDR_15 0x15
1366 #define IOPB_GPIO_CNTL 0x16
1367 #define IOPB_RES_ADDR_17 0x17
1368 #define IOPB_FLASH_DATA 0x18
1369 #define IOPB_RES_ADDR_19 0x19
1370 #define IOPB_RES_ADDR_1A 0x1A
1371 #define IOPB_RES_ADDR_1B 0x1B
1372 #define IOPB_RES_ADDR_1C 0x1C
1373 #define IOPB_RES_ADDR_1D 0x1D
1374 #define IOPB_RES_ADDR_1E 0x1E
1375 #define IOPB_RES_ADDR_1F 0x1F
1376 #define IOPB_DMA_CFG0 0x20
1377 #define IOPB_DMA_CFG1 0x21
1378 #define IOPB_TICKLE 0x22
1379 #define IOPB_DMA_REG_WR 0x23
1380 #define IOPB_SDMA_STATUS 0x24
1381 #define IOPB_SCSI_BYTE_CNT 0x25
1382 #define IOPB_HOST_BYTE_CNT 0x26
1383 #define IOPB_BYTE_LEFT_TO_XFER 0x27
1384 #define IOPB_BYTE_TO_XFER_0 0x28
1385 #define IOPB_BYTE_TO_XFER_1 0x29
1386 #define IOPB_BYTE_TO_XFER_2 0x2A
1387 #define IOPB_BYTE_TO_XFER_3 0x2B
1388 #define IOPB_ACC_GRP 0x2C
1389 #define IOPB_RES_ADDR_2D 0x2D
1390 #define IOPB_DEV_ID 0x2E
1391 #define IOPB_RES_ADDR_2F 0x2F
1392 #define IOPB_SCSI_DATA 0x30
1393 #define IOPB_RES_ADDR_31 0x31
1394 #define IOPB_RES_ADDR_32 0x32
1395 #define IOPB_SCSI_DATA_HSHK 0x33
1396 #define IOPB_SCSI_CTRL 0x34
1397 #define IOPB_RES_ADDR_35 0x35
1398 #define IOPB_RES_ADDR_36 0x36
1399 #define IOPB_RES_ADDR_37 0x37
1400 #define IOPB_RAM_BIST 0x38
1401 #define IOPB_PLL_TEST 0x39
1402 #define IOPB_PCI_INT_CFG 0x3A
1403 #define IOPB_RES_ADDR_3B 0x3B
1404 #define IOPB_RFIFO_CNT 0x3C
1405 #define IOPB_RES_ADDR_3D 0x3D
1406 #define IOPB_RES_ADDR_3E 0x3E
1407 #define IOPB_RES_ADDR_3F 0x3F
1410 * Word I/O register address from base of 'iop_base'.
1412 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
1413 #define IOPW_CTRL_REG 0x02 /* CC */
1414 #define IOPW_RAM_ADDR 0x04 /* LA */
1415 #define IOPW_RAM_DATA 0x06 /* LD */
1416 #define IOPW_RES_ADDR_08 0x08
1417 #define IOPW_RISC_CSR 0x0A /* CSR */
1418 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1419 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1420 #define IOPW_RES_ADDR_10 0x10
1421 #define IOPW_SEL_MASK 0x12 /* SM */
1422 #define IOPW_RES_ADDR_14 0x14
1423 #define IOPW_FLASH_ADDR 0x16 /* FA */
1424 #define IOPW_RES_ADDR_18 0x18
1425 #define IOPW_EE_CMD 0x1A /* EC */
1426 #define IOPW_EE_DATA 0x1C /* ED */
1427 #define IOPW_SFIFO_CNT 0x1E /* SFC */
1428 #define IOPW_RES_ADDR_20 0x20
1429 #define IOPW_Q_BASE 0x22 /* QB */
1430 #define IOPW_QP 0x24 /* QP */
1431 #define IOPW_IX 0x26 /* IX */
1432 #define IOPW_SP 0x28 /* SP */
1433 #define IOPW_PC 0x2A /* PC */
1434 #define IOPW_RES_ADDR_2C 0x2C
1435 #define IOPW_RES_ADDR_2E 0x2E
1436 #define IOPW_SCSI_DATA 0x30 /* SD */
1437 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1438 #define IOPW_SCSI_CTRL 0x34 /* SC */
1439 #define IOPW_HSHK_CFG 0x36 /* HCFG */
1440 #define IOPW_SXFR_STATUS 0x36 /* SXS */
1441 #define IOPW_SXFR_CNTL 0x38 /* SXL */
1442 #define IOPW_SXFR_CNTH 0x3A /* SXH */
1443 #define IOPW_RES_ADDR_3C 0x3C
1444 #define IOPW_RFIFO_DATA 0x3E /* RFD */
1447 * Doubleword I/O register address from base of 'iop_base'.
1449 #define IOPDW_RES_ADDR_0 0x00
1450 #define IOPDW_RAM_DATA 0x04
1451 #define IOPDW_RES_ADDR_8 0x08
1452 #define IOPDW_RES_ADDR_C 0x0C
1453 #define IOPDW_RES_ADDR_10 0x10
1454 #define IOPDW_COMMA 0x14
1455 #define IOPDW_COMMB 0x18
1456 #define IOPDW_RES_ADDR_1C 0x1C
1457 #define IOPDW_SDMA_ADDR0 0x20
1458 #define IOPDW_SDMA_ADDR1 0x24
1459 #define IOPDW_SDMA_COUNT 0x28
1460 #define IOPDW_SDMA_ERROR 0x2C
1461 #define IOPDW_RDMA_ADDR0 0x30
1462 #define IOPDW_RDMA_ADDR1 0x34
1463 #define IOPDW_RDMA_COUNT 0x38
1464 #define IOPDW_RDMA_ERROR 0x3C
1466 #define ADV_CHIP_ID_BYTE 0x25
1467 #define ADV_CHIP_ID_WORD 0x04C1
1469 #define ADV_INTR_ENABLE_HOST_INTR 0x01
1470 #define ADV_INTR_ENABLE_SEL_INTR 0x02
1471 #define ADV_INTR_ENABLE_DPR_INTR 0x04
1472 #define ADV_INTR_ENABLE_RTA_INTR 0x08
1473 #define ADV_INTR_ENABLE_RMA_INTR 0x10
1474 #define ADV_INTR_ENABLE_RST_INTR 0x20
1475 #define ADV_INTR_ENABLE_DPE_INTR 0x40
1476 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1478 #define ADV_INTR_STATUS_INTRA 0x01
1479 #define ADV_INTR_STATUS_INTRB 0x02
1480 #define ADV_INTR_STATUS_INTRC 0x04
1482 #define ADV_RISC_CSR_STOP (0x0000)
1483 #define ADV_RISC_TEST_COND (0x2000)
1484 #define ADV_RISC_CSR_RUN (0x4000)
1485 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1487 #define ADV_CTRL_REG_HOST_INTR 0x0100
1488 #define ADV_CTRL_REG_SEL_INTR 0x0200
1489 #define ADV_CTRL_REG_DPR_INTR 0x0400
1490 #define ADV_CTRL_REG_RTA_INTR 0x0800
1491 #define ADV_CTRL_REG_RMA_INTR 0x1000
1492 #define ADV_CTRL_REG_RES_BIT14 0x2000
1493 #define ADV_CTRL_REG_DPE_INTR 0x4000
1494 #define ADV_CTRL_REG_POWER_DONE 0x8000
1495 #define ADV_CTRL_REG_ANY_INTR 0xFF00
1497 #define ADV_CTRL_REG_CMD_RESET 0x00C6
1498 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1499 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1500 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1501 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1503 #define ADV_TICKLE_NOP 0x00
1504 #define ADV_TICKLE_A 0x01
1505 #define ADV_TICKLE_B 0x02
1506 #define ADV_TICKLE_C 0x03
1508 #define AdvIsIntPending(port) \
1509 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1512 * SCSI_CFG0 Register bit definitions
1514 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1515 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1516 #define EVEN_PARITY 0x1000 /* Select Even Parity */
1517 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1518 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1519 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1520 #define SCAM_EN 0x0080 /* Enable SCAM selection */
1521 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1522 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1523 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1524 #define OUR_ID 0x000F /* SCSI ID */
1527 * SCSI_CFG1 Register bit definitions
1529 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1530 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1531 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1532 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
1533 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1534 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1535 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1536 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1537 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1538 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1539 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1540 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1541 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1542 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1543 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1546 * Addendum for ASC-38C0800 Chip
1548 * The ASC-38C1600 Chip uses the same definitions except that the
1549 * bus mode override bits [12:10] have been moved to byte register
1550 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1551 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1552 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1553 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1554 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1556 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1557 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1558 #define HVD 0x1000 /* HVD Device Detect */
1559 #define LVD 0x0800 /* LVD Device Detect */
1560 #define SE 0x0400 /* SE Device Detect */
1561 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
1562 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1563 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1564 #define TERM_SE 0x0030 /* SE Termination Bits */
1565 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1566 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1567 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1568 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1569 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1570 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1571 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1572 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1574 #define CABLE_ILLEGAL_A 0x7
1575 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1577 #define CABLE_ILLEGAL_B 0xB
1578 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1581 * MEM_CFG Register bit definitions
1583 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1584 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1585 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1586 #define RAM_SZ_2KB 0x00 /* 2 KB */
1587 #define RAM_SZ_4KB 0x04 /* 4 KB */
1588 #define RAM_SZ_8KB 0x08 /* 8 KB */
1589 #define RAM_SZ_16KB 0x0C /* 16 KB */
1590 #define RAM_SZ_32KB 0x10 /* 32 KB */
1591 #define RAM_SZ_64KB 0x14 /* 64 KB */
1594 * DMA_CFG0 Register bit definitions
1596 * This register is only accessible to the host.
1598 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1599 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1600 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
1601 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
1602 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
1603 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
1604 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1605 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
1606 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
1607 #define START_CTL 0x0C /* DMA start conditions */
1608 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
1609 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1610 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1611 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1612 #define READ_CMD 0x03 /* Memory Read Method */
1613 #define READ_CMD_MR 0x00 /* Memory Read */
1614 #define READ_CMD_MRL 0x02 /* Memory Read Long */
1615 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1618 * ASC-38C0800 RAM BIST Register bit definitions
1620 #define RAM_TEST_MODE 0x80
1621 #define PRE_TEST_MODE 0x40
1622 #define NORMAL_MODE 0x00
1623 #define RAM_TEST_DONE 0x10
1624 #define RAM_TEST_STATUS 0x0F
1625 #define RAM_TEST_HOST_ERROR 0x08
1626 #define RAM_TEST_INTRAM_ERROR 0x04
1627 #define RAM_TEST_RISC_ERROR 0x02
1628 #define RAM_TEST_SCSI_ERROR 0x01
1629 #define RAM_TEST_SUCCESS 0x00
1630 #define PRE_TEST_VALUE 0x05
1631 #define NORMAL_VALUE 0x00
1634 * ASC38C1600 Definitions
1636 * IOPB_PCI_INT_CFG Bit Field Definitions
1639 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1642 * Bit 1 can be set to change the interrupt for the Function to operate in
1643 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1644 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1645 * mode, otherwise the operating mode is undefined.
1647 #define TOTEMPOLE 0x02
1650 * Bit 0 can be used to change the Int Pin for the Function. The value is
1651 * 0 by default for both Functions with Function 0 using INT A and Function
1652 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1653 * INT A is used.
1655 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1656 * value specified in the PCI Configuration Space.
1658 #define INTAB 0x01
1661 * Adv Library Status Definitions
1663 #define ADV_TRUE 1
1664 #define ADV_FALSE 0
1665 #define ADV_SUCCESS 1
1666 #define ADV_BUSY 0
1667 #define ADV_ERROR (-1)
1670 * ADV_DVC_VAR 'warn_code' values
1672 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1673 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1674 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
1675 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1677 #define ADV_MAX_TID 15 /* max. target identifier */
1678 #define ADV_MAX_LUN 7 /* max. logical unit number */
1681 * Fixed locations of microcode operating variables.
1683 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1684 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1685 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1686 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1687 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1688 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1689 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1690 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1691 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1692 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1693 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1694 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1695 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1696 #define ASC_MC_CHIP_TYPE 0x009A
1697 #define ASC_MC_INTRB_CODE 0x009B
1698 #define ASC_MC_WDTR_ABLE 0x009C
1699 #define ASC_MC_SDTR_ABLE 0x009E
1700 #define ASC_MC_TAGQNG_ABLE 0x00A0
1701 #define ASC_MC_DISC_ENABLE 0x00A2
1702 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
1703 #define ASC_MC_IDLE_CMD 0x00A6
1704 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1705 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1706 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1707 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1708 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1709 #define ASC_MC_SDTR_DONE 0x00B6
1710 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1711 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1712 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
1713 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1714 #define ASC_MC_WDTR_DONE 0x0124
1715 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1716 #define ASC_MC_ICQ 0x0160
1717 #define ASC_MC_IRQ 0x0164
1718 #define ASC_MC_PPR_ABLE 0x017A
1721 * BIOS LRAM variable absolute offsets.
1723 #define BIOS_CODESEG 0x54
1724 #define BIOS_CODELEN 0x56
1725 #define BIOS_SIGNATURE 0x58
1726 #define BIOS_VERSION 0x5A
1729 * Microcode Control Flags
1731 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1732 * and handled by the microcode.
1734 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1735 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1738 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1740 #define HSHK_CFG_WIDE_XFR 0x8000
1741 #define HSHK_CFG_RATE 0x0F00
1742 #define HSHK_CFG_OFFSET 0x001F
1744 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1745 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1746 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1747 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1749 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1750 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1751 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1752 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1753 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1755 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1756 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1757 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
1758 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
1759 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1761 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1762 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1764 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
1765 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1768 * All fields here are accessed by the board microcode and need to be
1769 * little-endian.
1771 typedef struct adv_carr_t {
1772 ADV_VADDR carr_va; /* Carrier Virtual Address */
1773 ADV_PADDR carr_pa; /* Carrier Physical Address */
1774 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1776 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
1778 * next_vpa [3:1] Reserved Bits
1779 * next_vpa [0] Done Flag set in Response Queue.
1781 ADV_VADDR next_vpa;
1782 } ADV_CARR_T;
1785 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1787 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
1789 #define ASC_RQ_DONE 0x00000001
1790 #define ASC_RQ_GOOD 0x00000002
1791 #define ASC_CQ_STOPPER 0x00000000
1793 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1795 #define ADV_CARRIER_NUM_PAGE_CROSSING \
1796 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
1797 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1799 #define ADV_CARRIER_BUFSIZE \
1800 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1803 * ASC_SCSI_REQ_Q 'a_flag' definitions
1805 * The Adv Library should limit use to the lower nibble (4 bits) of
1806 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1808 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
1809 #define ADV_SCSIQ_DONE 0x02 /* request done */
1810 #define ADV_DONT_RETRY 0x08 /* don't do retry */
1812 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
1813 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
1814 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1817 * Adapter temporary configuration structure
1819 * This structure can be discarded after initialization. Don't add
1820 * fields here needed after initialization.
1822 * Field naming convention:
1824 * *_enable indicates the field enables or disables a feature. The
1825 * value of the field is never reset.
1827 typedef struct adv_dvc_cfg {
1828 ushort disc_enable; /* enable disconnection */
1829 uchar chip_version; /* chip version */
1830 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1831 ushort control_flag; /* Microcode Control Flag */
1832 ushort mcode_date; /* Microcode date */
1833 ushort mcode_version; /* Microcode version */
1834 ushort serial1; /* EEPROM serial number word 1 */
1835 ushort serial2; /* EEPROM serial number word 2 */
1836 ushort serial3; /* EEPROM serial number word 3 */
1837 } ADV_DVC_CFG;
1839 struct adv_dvc_var;
1840 struct adv_scsi_req_q;
1843 * Adapter operation variable structure.
1845 * One structure is required per host adapter.
1847 * Field naming convention:
1849 * *_able indicates both whether a feature should be enabled or disabled
1850 * and whether a device isi capable of the feature. At initialization
1851 * this field may be set, but later if a device is found to be incapable
1852 * of the feature, the field is cleared.
1854 typedef struct adv_dvc_var {
1855 AdvPortAddr iop_base; /* I/O port address */
1856 ushort err_code; /* fatal error code */
1857 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
1858 ushort wdtr_able; /* try WDTR for a device */
1859 ushort sdtr_able; /* try SDTR for a device */
1860 ushort ultra_able; /* try SDTR Ultra speed for a device */
1861 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
1862 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
1863 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
1864 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
1865 ushort tagqng_able; /* try tagged queuing with a device */
1866 ushort ppr_able; /* PPR message capable per TID bitmask. */
1867 uchar max_dvc_qng; /* maximum number of tagged commands per device */
1868 ushort start_motor; /* start motor command allowed */
1869 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
1870 uchar chip_no; /* should be assigned by caller */
1871 uchar max_host_qng; /* maximum number of Q'ed command allowed */
1872 ushort no_scam; /* scam_tolerant of EEPROM */
1873 struct asc_board *drv_ptr; /* driver pointer to private structure */
1874 uchar chip_scsi_id; /* chip SCSI target ID */
1875 uchar chip_type;
1876 uchar bist_err_code;
1877 ADV_CARR_T *carrier_buf;
1878 ADV_CARR_T *carr_freelist; /* Carrier free list. */
1879 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
1880 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
1881 ushort carr_pending_cnt; /* Count of pending carriers. */
1883 * Note: The following fields will not be used after initialization. The
1884 * driver may discard the buffer after initialization is done.
1886 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1887 } ADV_DVC_VAR;
1889 #define NO_OF_SG_PER_BLOCK 15
1891 typedef struct asc_sg_block {
1892 uchar reserved1;
1893 uchar reserved2;
1894 uchar reserved3;
1895 uchar sg_cnt; /* Valid entries in block. */
1896 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
1897 struct {
1898 ADV_PADDR sg_addr; /* SG element address. */
1899 ADV_DCNT sg_count; /* SG element count. */
1900 } sg_list[NO_OF_SG_PER_BLOCK];
1901 } ADV_SG_BLOCK;
1904 * ADV_SCSI_REQ_Q - microcode request structure
1906 * All fields in this structure up to byte 60 are used by the microcode.
1907 * The microcode makes assumptions about the size and ordering of fields
1908 * in this structure. Do not change the structure definition here without
1909 * coordinating the change with the microcode.
1911 * All fields accessed by microcode must be maintained in little_endian
1912 * order.
1914 typedef struct adv_scsi_req_q {
1915 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
1916 uchar target_cmd;
1917 uchar target_id; /* Device target identifier. */
1918 uchar target_lun; /* Device target logical unit number. */
1919 ADV_PADDR data_addr; /* Data buffer physical address. */
1920 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
1921 ADV_PADDR sense_addr;
1922 ADV_PADDR carr_pa;
1923 uchar mflag;
1924 uchar sense_len;
1925 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
1926 uchar scsi_cntl;
1927 uchar done_status; /* Completion status. */
1928 uchar scsi_status; /* SCSI status byte. */
1929 uchar host_status; /* Ucode host status. */
1930 uchar sg_working_ix;
1931 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
1932 ADV_PADDR sg_real_addr; /* SG list physical address. */
1933 ADV_PADDR scsiq_rptr;
1934 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
1935 ADV_VADDR scsiq_ptr;
1936 ADV_VADDR carr_va;
1938 * End of microcode structure - 60 bytes. The rest of the structure
1939 * is used by the Adv Library and ignored by the microcode.
1941 ADV_VADDR srb_ptr;
1942 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
1943 char *vdata_addr; /* Data buffer virtual address. */
1944 uchar a_flag;
1945 uchar pad[2]; /* Pad out to a word boundary. */
1946 } ADV_SCSI_REQ_Q;
1949 * Microcode idle loop commands
1951 #define IDLE_CMD_COMPLETED 0
1952 #define IDLE_CMD_STOP_CHIP 0x0001
1953 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
1954 #define IDLE_CMD_SEND_INT 0x0004
1955 #define IDLE_CMD_ABORT 0x0008
1956 #define IDLE_CMD_DEVICE_RESET 0x0010
1957 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
1958 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1959 #define IDLE_CMD_SCSIREQ 0x0080
1961 #define IDLE_CMD_STATUS_SUCCESS 0x0001
1962 #define IDLE_CMD_STATUS_FAILURE 0x0002
1965 * AdvSendIdleCmd() flag definitions.
1967 #define ADV_NOWAIT 0x01
1970 * Wait loop time out values.
1972 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
1973 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
1974 #define SCSI_MAX_RETRY 10 /* retry count */
1976 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
1977 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
1978 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
1979 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1981 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1983 /* Read byte from a register. */
1984 #define AdvReadByteRegister(iop_base, reg_off) \
1985 (ADV_MEM_READB((iop_base) + (reg_off)))
1987 /* Write byte to a register. */
1988 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
1989 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
1991 /* Read word (2 bytes) from a register. */
1992 #define AdvReadWordRegister(iop_base, reg_off) \
1993 (ADV_MEM_READW((iop_base) + (reg_off)))
1995 /* Write word (2 bytes) to a register. */
1996 #define AdvWriteWordRegister(iop_base, reg_off, word) \
1997 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
1999 /* Write dword (4 bytes) to a register. */
2000 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2001 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2003 /* Read byte from LRAM. */
2004 #define AdvReadByteLram(iop_base, addr, byte) \
2005 do { \
2006 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2007 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2008 } while (0)
2010 /* Write byte to LRAM. */
2011 #define AdvWriteByteLram(iop_base, addr, byte) \
2012 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2013 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2015 /* Read word (2 bytes) from LRAM. */
2016 #define AdvReadWordLram(iop_base, addr, word) \
2017 do { \
2018 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2019 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2020 } while (0)
2022 /* Write word (2 bytes) to LRAM. */
2023 #define AdvWriteWordLram(iop_base, addr, word) \
2024 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2025 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2027 /* Write little-endian double word (4 bytes) to LRAM */
2028 /* Because of unspecified C language ordering don't use auto-increment. */
2029 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2030 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2031 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2032 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2033 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2034 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2035 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2037 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
2038 #define AdvReadWordAutoIncLram(iop_base) \
2039 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2041 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
2042 #define AdvWriteWordAutoIncLram(iop_base, word) \
2043 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2046 * Define macro to check for Condor signature.
2048 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2049 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2051 #define AdvFindSignature(iop_base) \
2052 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2053 ADV_CHIP_ID_BYTE) && \
2054 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2055 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2058 * Define macro to Return the version number of the chip at 'iop_base'.
2060 * The second parameter 'bus_type' is currently unused.
2062 #define AdvGetChipVersion(iop_base, bus_type) \
2063 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2066 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2067 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2069 * If the request has not yet been sent to the device it will simply be
2070 * aborted from RISC memory. If the request is disconnected it will be
2071 * aborted on reselection by sending an Abort Message to the target ID.
2073 * Return value:
2074 * ADV_TRUE(1) - Queue was successfully aborted.
2075 * ADV_FALSE(0) - Queue was not found on the active queue list.
2077 #define AdvAbortQueue(asc_dvc, scsiq) \
2078 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2079 (ADV_DCNT) (scsiq))
2082 * Send a Bus Device Reset Message to the specified target ID.
2084 * All outstanding commands will be purged if sending the
2085 * Bus Device Reset Message is successful.
2087 * Return Value:
2088 * ADV_TRUE(1) - All requests on the target are purged.
2089 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2090 * are not purged.
2092 #define AdvResetDevice(asc_dvc, target_id) \
2093 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2094 (ADV_DCNT) (target_id))
2097 * SCSI Wide Type definition.
2099 #define ADV_SCSI_BIT_ID_TYPE ushort
2102 * AdvInitScsiTarget() 'cntl_flag' options.
2104 #define ADV_SCAN_LUN 0x01
2105 #define ADV_CAPINFO_NOLUN 0x02
2108 * Convert target id to target id bit mask.
2110 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2113 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2116 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
2117 #define QD_NO_ERROR 0x01
2118 #define QD_ABORTED_BY_HOST 0x02
2119 #define QD_WITH_ERROR 0x04
2121 #define QHSTA_NO_ERROR 0x00
2122 #define QHSTA_M_SEL_TIMEOUT 0x11
2123 #define QHSTA_M_DATA_OVER_RUN 0x12
2124 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2125 #define QHSTA_M_QUEUE_ABORTED 0x15
2126 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2127 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2128 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2129 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2130 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2131 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2132 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
2133 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
2134 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2135 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2136 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2137 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2138 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2139 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2140 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2141 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
2142 #define QHSTA_M_WTM_TIMEOUT 0x41
2143 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2144 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2145 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2146 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2147 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2148 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
2151 * DvcGetPhyAddr() flag arguments
2153 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2154 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2155 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2156 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2157 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2158 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
2160 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
2161 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2162 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2163 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2166 * Total contiguous memory needed for driver SG blocks.
2168 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2169 * number of scatter-gather elements the driver supports in a
2170 * single request.
2173 #define ADV_SG_LIST_MAX_BYTE_SIZE \
2174 (sizeof(ADV_SG_BLOCK) * \
2175 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2177 /* struct asc_board flags */
2178 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
2180 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2182 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
2184 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
2186 #ifdef CONFIG_PROC_FS
2187 /* /proc/scsi/advansys/[0...] related definitions */
2188 #define ASC_PRTBUF_SIZE 2048
2189 #define ASC_PRTLINE_SIZE 160
2191 #define ASC_PRT_NEXT() \
2192 if (cp) { \
2193 totlen += len; \
2194 leftlen -= len; \
2195 if (leftlen == 0) { \
2196 return totlen; \
2198 cp += len; \
2200 #endif /* CONFIG_PROC_FS */
2202 /* Asc Library return codes */
2203 #define ASC_TRUE 1
2204 #define ASC_FALSE 0
2205 #define ASC_NOERROR 1
2206 #define ASC_BUSY 0
2207 #define ASC_ERROR (-1)
2209 /* struct scsi_cmnd function return codes */
2210 #define STATUS_BYTE(byte) (byte)
2211 #define MSG_BYTE(byte) ((byte) << 8)
2212 #define HOST_BYTE(byte) ((byte) << 16)
2213 #define DRIVER_BYTE(byte) ((byte) << 24)
2215 #define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
2216 #ifndef ADVANSYS_STATS
2217 #define ASC_STATS_ADD(shost, counter, count)
2218 #else /* ADVANSYS_STATS */
2219 #define ASC_STATS_ADD(shost, counter, count) \
2220 (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
2221 #endif /* ADVANSYS_STATS */
2223 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2225 /* If the result wraps when calculating tenths, return 0. */
2226 #define ASC_TENTHS(num, den) \
2227 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2228 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2231 * Display a message to the console.
2233 #define ASC_PRINT(s) \
2235 printk("advansys: "); \
2236 printk(s); \
2239 #define ASC_PRINT1(s, a1) \
2241 printk("advansys: "); \
2242 printk((s), (a1)); \
2245 #define ASC_PRINT2(s, a1, a2) \
2247 printk("advansys: "); \
2248 printk((s), (a1), (a2)); \
2251 #define ASC_PRINT3(s, a1, a2, a3) \
2253 printk("advansys: "); \
2254 printk((s), (a1), (a2), (a3)); \
2257 #define ASC_PRINT4(s, a1, a2, a3, a4) \
2259 printk("advansys: "); \
2260 printk((s), (a1), (a2), (a3), (a4)); \
2263 #ifndef ADVANSYS_DEBUG
2265 #define ASC_DBG(lvl, s...)
2266 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2267 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2268 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2269 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2270 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2271 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2272 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2273 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2274 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2276 #else /* ADVANSYS_DEBUG */
2279 * Debugging Message Levels:
2280 * 0: Errors Only
2281 * 1: High-Level Tracing
2282 * 2-N: Verbose Tracing
2285 #define ASC_DBG(lvl, format, arg...) { \
2286 if (asc_dbglvl >= (lvl)) \
2287 printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \
2288 __FUNCTION__ , ## arg); \
2291 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2293 if (asc_dbglvl >= (lvl)) { \
2294 asc_prt_scsi_host(s); \
2298 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2300 if (asc_dbglvl >= (lvl)) { \
2301 asc_prt_asc_scsi_q(scsiqp); \
2305 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2307 if (asc_dbglvl >= (lvl)) { \
2308 asc_prt_asc_qdone_info(qdone); \
2312 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2314 if (asc_dbglvl >= (lvl)) { \
2315 asc_prt_adv_scsi_req_q(scsiqp); \
2319 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2321 if (asc_dbglvl >= (lvl)) { \
2322 asc_prt_hex((name), (start), (length)); \
2326 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2327 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2329 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2330 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2332 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2333 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2334 #endif /* ADVANSYS_DEBUG */
2336 #ifdef ADVANSYS_STATS
2338 /* Per board statistics structure */
2339 struct asc_stats {
2340 /* Driver Entrypoint Statistics */
2341 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2342 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2343 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2344 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2345 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2346 ADV_DCNT done; /* # calls to request's scsi_done function */
2347 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2348 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2349 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2350 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2351 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2352 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2353 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2354 ADV_DCNT exe_unknown; /* # unknown returns. */
2355 /* Data Transfer Statistics */
2356 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2357 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2358 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2359 ADV_DCNT sg_elem; /* # scatter-gather elements */
2360 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
2362 #endif /* ADVANSYS_STATS */
2365 * Adv Library Request Structures
2367 * The following two structures are used to process Wide Board requests.
2369 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2370 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2371 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2372 * Mid-Level SCSI request structure.
2374 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2375 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2376 * up to 255 scatter-gather elements may be used per request or
2377 * ADV_SCSI_REQ_Q.
2379 * Both structures must be 32 byte aligned.
2381 typedef struct adv_sgblk {
2382 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2383 uchar align[32]; /* Sgblock structure padding. */
2384 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
2385 } adv_sgblk_t;
2387 typedef struct adv_req {
2388 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2389 uchar align[32]; /* Request structure padding. */
2390 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2391 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2392 struct adv_req *next_reqp; /* Next Request Structure. */
2393 } adv_req_t;
2396 * Structure allocated for each board.
2398 * This structure is allocated by scsi_host_alloc() at the end
2399 * of the 'Scsi_Host' structure starting at the 'hostdata'
2400 * field. It is guaranteed to be allocated from DMA-able memory.
2402 struct asc_board {
2403 struct device *dev;
2404 uint flags; /* Board flags */
2405 unsigned int irq;
2406 union {
2407 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2408 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2409 } dvc_var;
2410 union {
2411 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2412 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2413 } dvc_cfg;
2414 ushort asc_n_io_port; /* Number I/O ports. */
2415 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2416 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2417 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2418 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2419 union {
2420 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2421 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2422 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2423 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2424 } eep_config;
2425 ulong last_reset; /* Saved last reset time */
2426 /* /proc/scsi/advansys/[0...] */
2427 char *prtbuf; /* /proc print buffer */
2428 #ifdef ADVANSYS_STATS
2429 struct asc_stats asc_stats; /* Board statistics */
2430 #endif /* ADVANSYS_STATS */
2432 * The following fields are used only for Narrow Boards.
2434 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2436 * The following fields are used only for Wide Boards.
2438 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2439 ushort ioport; /* I/O Port address. */
2440 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
2441 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2442 adv_req_t *adv_reqp; /* Request structures. */
2443 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2444 ushort bios_signature; /* BIOS Signature. */
2445 ushort bios_version; /* BIOS Version. */
2446 ushort bios_codeseg; /* BIOS Code Segment. */
2447 ushort bios_codelen; /* BIOS Code Segment Length. */
2450 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2451 dvc_var.adv_dvc_var)
2452 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2454 /* Overrun buffer used by all narrow boards. */
2455 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
2457 #ifdef ADVANSYS_DEBUG
2458 static int asc_dbglvl = 3;
2461 * asc_prt_asc_dvc_var()
2463 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2465 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
2467 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2468 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2470 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2471 (unsigned)h->init_sdtr);
2473 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2474 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2475 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2476 (unsigned)h->chip_no);
2478 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2479 "%u,\n", (unsigned)h->queue_full_or_busy,
2480 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2482 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2483 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2484 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2485 (unsigned)h->in_critical_cnt);
2487 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2488 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2489 (unsigned)h->init_state, (unsigned)h->no_scam,
2490 (unsigned)h->pci_fix_asyn_xfer);
2492 printk(" cfg 0x%lx\n", (ulong)h->cfg);
2496 * asc_prt_asc_dvc_cfg()
2498 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
2500 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
2502 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2503 h->can_tagged_qng, h->cmd_qng_enabled);
2504 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2505 h->disc_enable, h->sdtr_enable);
2507 printk(" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, "
2508 "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed,
2509 h->isa_dma_channel, h->chip_version);
2511 printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n",
2512 h->mcode_date, h->mcode_version, h->overrun_buf);
2516 * asc_prt_adv_dvc_var()
2518 * Display an ADV_DVC_VAR structure.
2520 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2522 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
2524 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2525 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
2527 printk(" sdtr_able 0x%x, wdtr_able 0x%x\n",
2528 (unsigned)h->sdtr_able, (unsigned)h->wdtr_able);
2530 printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n",
2531 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2533 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2534 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2535 (ulong)h->carr_freelist);
2537 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
2538 (ulong)h->icq_sp, (ulong)h->irq_sp);
2540 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
2541 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
2543 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
2544 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2548 * asc_prt_adv_dvc_cfg()
2550 * Display an ADV_DVC_CFG structure.
2552 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2554 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
2556 printk(" disc_enable 0x%x, termination 0x%x\n",
2557 h->disc_enable, h->termination);
2559 printk(" chip_version 0x%x, mcode_date 0x%x\n",
2560 h->chip_version, h->mcode_date);
2562 printk(" mcode_version 0x%x, control_flag 0x%x\n",
2563 h->mcode_version, h->control_flag);
2567 * asc_prt_scsi_host()
2569 static void asc_prt_scsi_host(struct Scsi_Host *s)
2571 struct asc_board *boardp = shost_priv(s);
2573 printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id);
2574 printk(" host_busy %u, host_no %d, last_reset %d,\n",
2575 s->host_busy, s->host_no, (unsigned)s->last_reset);
2577 printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
2578 (ulong)s->base, (ulong)s->io_port, boardp->irq);
2580 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2581 s->dma_channel, s->this_id, s->can_queue);
2583 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
2584 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
2586 if (ASC_NARROW_BOARD(boardp)) {
2587 asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var);
2588 asc_prt_asc_dvc_cfg(&boardp->dvc_cfg.asc_dvc_cfg);
2589 } else {
2590 asc_prt_adv_dvc_var(&boardp->dvc_var.adv_dvc_var);
2591 asc_prt_adv_dvc_cfg(&boardp->dvc_cfg.adv_dvc_cfg);
2596 * asc_prt_hex()
2598 * Print hexadecimal output in 4 byte groupings 32 bytes
2599 * or 8 double-words per line.
2601 static void asc_prt_hex(char *f, uchar *s, int l)
2603 int i;
2604 int j;
2605 int k;
2606 int m;
2608 printk("%s: (%d bytes)\n", f, l);
2610 for (i = 0; i < l; i += 32) {
2612 /* Display a maximum of 8 double-words per line. */
2613 if ((k = (l - i) / 4) >= 8) {
2614 k = 8;
2615 m = 0;
2616 } else {
2617 m = (l - i) % 4;
2620 for (j = 0; j < k; j++) {
2621 printk(" %2.2X%2.2X%2.2X%2.2X",
2622 (unsigned)s[i + (j * 4)],
2623 (unsigned)s[i + (j * 4) + 1],
2624 (unsigned)s[i + (j * 4) + 2],
2625 (unsigned)s[i + (j * 4) + 3]);
2628 switch (m) {
2629 case 0:
2630 default:
2631 break;
2632 case 1:
2633 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2634 break;
2635 case 2:
2636 printk(" %2.2X%2.2X",
2637 (unsigned)s[i + (j * 4)],
2638 (unsigned)s[i + (j * 4) + 1]);
2639 break;
2640 case 3:
2641 printk(" %2.2X%2.2X%2.2X",
2642 (unsigned)s[i + (j * 4) + 1],
2643 (unsigned)s[i + (j * 4) + 2],
2644 (unsigned)s[i + (j * 4) + 3]);
2645 break;
2648 printk("\n");
2653 * asc_prt_asc_scsi_q()
2655 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2657 ASC_SG_HEAD *sgp;
2658 int i;
2660 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2662 printk
2663 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
2664 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
2665 q->q2.tag_code);
2667 printk
2668 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2669 (ulong)le32_to_cpu(q->q1.data_addr),
2670 (ulong)le32_to_cpu(q->q1.data_cnt),
2671 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2673 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2674 (ulong)q->cdbptr, q->q2.cdb_len,
2675 (ulong)q->sg_head, q->q1.sg_queue_cnt);
2677 if (q->sg_head) {
2678 sgp = q->sg_head;
2679 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2680 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2681 sgp->queue_cnt);
2682 for (i = 0; i < sgp->entry_cnt; i++) {
2683 printk(" [%u]: addr 0x%lx, bytes %lu\n",
2684 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2685 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2692 * asc_prt_asc_qdone_info()
2694 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2696 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2697 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
2698 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
2699 q->d2.tag_code);
2700 printk
2701 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2702 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
2706 * asc_prt_adv_sgblock()
2708 * Display an ADV_SG_BLOCK structure.
2710 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2712 int i;
2714 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2715 (ulong)b, sgblockno);
2716 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
2717 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
2718 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2719 if (b->sg_ptr != 0)
2720 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2721 for (i = 0; i < b->sg_cnt; i++) {
2722 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
2723 i, (ulong)b->sg_list[i].sg_addr,
2724 (ulong)b->sg_list[i].sg_count);
2729 * asc_prt_adv_scsi_req_q()
2731 * Display an ADV_SCSI_REQ_Q structure.
2733 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2735 int sg_blk_cnt;
2736 struct asc_sg_block *sg_ptr;
2738 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2740 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
2741 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
2743 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
2744 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
2746 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2747 (ulong)le32_to_cpu(q->data_cnt),
2748 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2750 printk
2751 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2752 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2754 printk(" sg_working_ix 0x%x, target_cmd %u\n",
2755 q->sg_working_ix, q->target_cmd);
2757 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2758 (ulong)le32_to_cpu(q->scsiq_rptr),
2759 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2761 /* Display the request's ADV_SG_BLOCK structures. */
2762 if (q->sg_list_ptr != NULL) {
2763 sg_blk_cnt = 0;
2764 while (1) {
2766 * 'sg_ptr' is a physical address. Convert it to a virtual
2767 * address by indexing 'sg_blk_cnt' into the virtual address
2768 * array 'sg_list_ptr'.
2770 * XXX - Assumes all SG physical blocks are virtually contiguous.
2772 sg_ptr =
2773 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
2774 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2775 if (sg_ptr->sg_ptr == 0) {
2776 break;
2778 sg_blk_cnt++;
2782 #endif /* ADVANSYS_DEBUG */
2785 * advansys_info()
2787 * Return suitable for printing on the console with the argument
2788 * adapter's configuration information.
2790 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2791 * otherwise the static 'info' array will be overrun.
2793 static const char *advansys_info(struct Scsi_Host *shost)
2795 static char info[ASC_INFO_SIZE];
2796 struct asc_board *boardp = shost_priv(shost);
2797 ASC_DVC_VAR *asc_dvc_varp;
2798 ADV_DVC_VAR *adv_dvc_varp;
2799 char *busname;
2800 char *widename = NULL;
2802 if (ASC_NARROW_BOARD(boardp)) {
2803 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2804 ASC_DBG(1, "begin\n");
2805 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2806 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2807 ASC_IS_ISAPNP) {
2808 busname = "ISA PnP";
2809 } else {
2810 busname = "ISA";
2812 sprintf(info,
2813 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2814 ASC_VERSION, busname,
2815 (ulong)shost->io_port,
2816 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2817 boardp->irq, shost->dma_channel);
2818 } else {
2819 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2820 busname = "VL";
2821 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2822 busname = "EISA";
2823 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2824 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2825 == ASC_IS_PCI_ULTRA) {
2826 busname = "PCI Ultra";
2827 } else {
2828 busname = "PCI";
2830 } else {
2831 busname = "?";
2832 shost_printk(KERN_ERR, shost, "unknown bus "
2833 "type %d\n", asc_dvc_varp->bus_type);
2835 sprintf(info,
2836 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2837 ASC_VERSION, busname, (ulong)shost->io_port,
2838 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2839 boardp->irq);
2841 } else {
2843 * Wide Adapter Information
2845 * Memory-mapped I/O is used instead of I/O space to access
2846 * the adapter, but display the I/O Port range. The Memory
2847 * I/O address is displayed through the driver /proc file.
2849 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2850 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2851 widename = "Ultra-Wide";
2852 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2853 widename = "Ultra2-Wide";
2854 } else {
2855 widename = "Ultra3-Wide";
2857 sprintf(info,
2858 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2859 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
2860 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
2862 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
2863 ASC_DBG(1, "end\n");
2864 return info;
2867 #ifdef CONFIG_PROC_FS
2869 * asc_prt_line()
2871 * If 'cp' is NULL print to the console, otherwise print to a buffer.
2873 * Return 0 if printing to the console, otherwise return the number of
2874 * bytes written to the buffer.
2876 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
2877 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
2879 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
2881 va_list args;
2882 int ret;
2883 char s[ASC_PRTLINE_SIZE];
2885 va_start(args, fmt);
2886 ret = vsprintf(s, fmt, args);
2887 BUG_ON(ret >= ASC_PRTLINE_SIZE);
2888 if (buf == NULL) {
2889 (void)printk(s);
2890 ret = 0;
2891 } else {
2892 ret = min(buflen, ret);
2893 memcpy(buf, s, ret);
2895 va_end(args);
2896 return ret;
2900 * asc_prt_board_devices()
2902 * Print driver information for devices attached to the board.
2904 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
2905 * cf. asc_prt_line().
2907 * Return the number of characters copied into 'cp'. No more than
2908 * 'cplen' characters will be copied to 'cp'.
2910 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
2912 struct asc_board *boardp = shost_priv(shost);
2913 int leftlen;
2914 int totlen;
2915 int len;
2916 int chip_scsi_id;
2917 int i;
2919 leftlen = cplen;
2920 totlen = len = 0;
2922 len = asc_prt_line(cp, leftlen,
2923 "\nDevice Information for AdvanSys SCSI Host %d:\n",
2924 shost->host_no);
2925 ASC_PRT_NEXT();
2927 if (ASC_NARROW_BOARD(boardp)) {
2928 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
2929 } else {
2930 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
2933 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
2934 ASC_PRT_NEXT();
2935 for (i = 0; i <= ADV_MAX_TID; i++) {
2936 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
2937 len = asc_prt_line(cp, leftlen, " %X,", i);
2938 ASC_PRT_NEXT();
2941 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
2942 ASC_PRT_NEXT();
2944 return totlen;
2948 * Display Wide Board BIOS Information.
2950 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
2952 struct asc_board *boardp = shost_priv(shost);
2953 int leftlen;
2954 int totlen;
2955 int len;
2956 ushort major, minor, letter;
2958 leftlen = cplen;
2959 totlen = len = 0;
2961 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
2962 ASC_PRT_NEXT();
2965 * If the BIOS saved a valid signature, then fill in
2966 * the BIOS code segment base address.
2968 if (boardp->bios_signature != 0x55AA) {
2969 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
2970 ASC_PRT_NEXT();
2971 len = asc_prt_line(cp, leftlen,
2972 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
2973 ASC_PRT_NEXT();
2974 len = asc_prt_line(cp, leftlen,
2975 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
2976 ASC_PRT_NEXT();
2977 } else {
2978 major = (boardp->bios_version >> 12) & 0xF;
2979 minor = (boardp->bios_version >> 8) & 0xF;
2980 letter = (boardp->bios_version & 0xFF);
2982 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
2983 major, minor,
2984 letter >= 26 ? '?' : letter + 'A');
2985 ASC_PRT_NEXT();
2988 * Current available ROM BIOS release is 3.1I for UW
2989 * and 3.2I for U2W. This code doesn't differentiate
2990 * UW and U2W boards.
2992 if (major < 3 || (major <= 3 && minor < 1) ||
2993 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
2994 len = asc_prt_line(cp, leftlen,
2995 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
2996 ASC_PRT_NEXT();
2997 len = asc_prt_line(cp, leftlen,
2998 "ftp://ftp.connectcom.net/pub\n");
2999 ASC_PRT_NEXT();
3003 return totlen;
3007 * Add serial number to information bar if signature AAh
3008 * is found in at bit 15-9 (7 bits) of word 1.
3010 * Serial Number consists fo 12 alpha-numeric digits.
3012 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
3013 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
3014 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
3015 * 5 - Product revision (A-J) Word0: " "
3017 * Signature Word1: 15-9 (7 bits)
3018 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
3019 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
3021 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
3023 * Note 1: Only production cards will have a serial number.
3025 * Note 2: Signature is most significant 7 bits (0xFE).
3027 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
3029 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
3031 ushort w, num;
3033 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3034 return ASC_FALSE;
3035 } else {
3037 * First word - 6 digits.
3039 w = serialnum[0];
3041 /* Product type - 1st digit. */
3042 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3043 /* Product type is P=Prototype */
3044 *cp += 0x8;
3046 cp++;
3048 /* Manufacturing location - 2nd digit. */
3049 *cp++ = 'A' + ((w & 0x1C00) >> 10);
3051 /* Product ID - 3rd, 4th digits. */
3052 num = w & 0x3FF;
3053 *cp++ = '0' + (num / 100);
3054 num %= 100;
3055 *cp++ = '0' + (num / 10);
3057 /* Product revision - 5th digit. */
3058 *cp++ = 'A' + (num % 10);
3061 * Second word
3063 w = serialnum[1];
3066 * Year - 6th digit.
3068 * If bit 15 of third word is set, then the
3069 * last digit of the year is greater than 7.
3071 if (serialnum[2] & 0x8000) {
3072 *cp++ = '8' + ((w & 0x1C0) >> 6);
3073 } else {
3074 *cp++ = '0' + ((w & 0x1C0) >> 6);
3077 /* Week of year - 7th, 8th digits. */
3078 num = w & 0x003F;
3079 *cp++ = '0' + num / 10;
3080 num %= 10;
3081 *cp++ = '0' + num;
3084 * Third word
3086 w = serialnum[2] & 0x7FFF;
3088 /* Serial number - 9th digit. */
3089 *cp++ = 'A' + (w / 1000);
3091 /* 10th, 11th, 12th digits. */
3092 num = w % 1000;
3093 *cp++ = '0' + num / 100;
3094 num %= 100;
3095 *cp++ = '0' + num / 10;
3096 num %= 10;
3097 *cp++ = '0' + num;
3099 *cp = '\0'; /* Null Terminate the string. */
3100 return ASC_TRUE;
3105 * asc_prt_asc_board_eeprom()
3107 * Print board EEPROM configuration.
3109 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3110 * cf. asc_prt_line().
3112 * Return the number of characters copied into 'cp'. No more than
3113 * 'cplen' characters will be copied to 'cp'.
3115 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3117 struct asc_board *boardp = shost_priv(shost);
3118 ASC_DVC_VAR *asc_dvc_varp;
3119 int leftlen;
3120 int totlen;
3121 int len;
3122 ASCEEP_CONFIG *ep;
3123 int i;
3124 #ifdef CONFIG_ISA
3125 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
3126 #endif /* CONFIG_ISA */
3127 uchar serialstr[13];
3129 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3130 ep = &boardp->eep_config.asc_eep;
3132 leftlen = cplen;
3133 totlen = len = 0;
3135 len = asc_prt_line(cp, leftlen,
3136 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3137 shost->host_no);
3138 ASC_PRT_NEXT();
3140 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
3141 == ASC_TRUE) {
3142 len =
3143 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3144 serialstr);
3145 ASC_PRT_NEXT();
3146 } else {
3147 if (ep->adapter_info[5] == 0xBB) {
3148 len = asc_prt_line(cp, leftlen,
3149 " Default Settings Used for EEPROM-less Adapter.\n");
3150 ASC_PRT_NEXT();
3151 } else {
3152 len = asc_prt_line(cp, leftlen,
3153 " Serial Number Signature Not Present.\n");
3154 ASC_PRT_NEXT();
3158 len = asc_prt_line(cp, leftlen,
3159 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3160 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
3161 ep->max_tag_qng);
3162 ASC_PRT_NEXT();
3164 len = asc_prt_line(cp, leftlen,
3165 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
3166 ASC_PRT_NEXT();
3168 len = asc_prt_line(cp, leftlen, " Target ID: ");
3169 ASC_PRT_NEXT();
3170 for (i = 0; i <= ASC_MAX_TID; i++) {
3171 len = asc_prt_line(cp, leftlen, " %d", i);
3172 ASC_PRT_NEXT();
3174 len = asc_prt_line(cp, leftlen, "\n");
3175 ASC_PRT_NEXT();
3177 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3178 ASC_PRT_NEXT();
3179 for (i = 0; i <= ASC_MAX_TID; i++) {
3180 len = asc_prt_line(cp, leftlen, " %c",
3181 (ep->
3182 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3183 'N');
3184 ASC_PRT_NEXT();
3186 len = asc_prt_line(cp, leftlen, "\n");
3187 ASC_PRT_NEXT();
3189 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3190 ASC_PRT_NEXT();
3191 for (i = 0; i <= ASC_MAX_TID; i++) {
3192 len = asc_prt_line(cp, leftlen, " %c",
3193 (ep->
3194 use_cmd_qng & 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, " Start Motor: ");
3202 ASC_PRT_NEXT();
3203 for (i = 0; i <= ASC_MAX_TID; i++) {
3204 len = asc_prt_line(cp, leftlen, " %c",
3205 (ep->
3206 start_motor & 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, " Synchronous Transfer:");
3214 ASC_PRT_NEXT();
3215 for (i = 0; i <= ASC_MAX_TID; i++) {
3216 len = asc_prt_line(cp, leftlen, " %c",
3217 (ep->
3218 init_sdtr & 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 #ifdef CONFIG_ISA
3226 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3227 len = asc_prt_line(cp, leftlen,
3228 " Host ISA DMA speed: %d MB/S\n",
3229 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
3230 ASC_PRT_NEXT();
3232 #endif /* CONFIG_ISA */
3234 return totlen;
3238 * asc_prt_adv_board_eeprom()
3240 * Print board EEPROM configuration.
3242 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3243 * cf. asc_prt_line().
3245 * Return the number of characters copied into 'cp'. No more than
3246 * 'cplen' characters will be copied to 'cp'.
3248 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3250 struct asc_board *boardp = shost_priv(shost);
3251 ADV_DVC_VAR *adv_dvc_varp;
3252 int leftlen;
3253 int totlen;
3254 int len;
3255 int i;
3256 char *termstr;
3257 uchar serialstr[13];
3258 ADVEEP_3550_CONFIG *ep_3550 = NULL;
3259 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
3260 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
3261 ushort word;
3262 ushort *wordp;
3263 ushort sdtr_speed = 0;
3265 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3266 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3267 ep_3550 = &boardp->eep_config.adv_3550_eep;
3268 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3269 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
3270 } else {
3271 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
3274 leftlen = cplen;
3275 totlen = len = 0;
3277 len = asc_prt_line(cp, leftlen,
3278 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3279 shost->host_no);
3280 ASC_PRT_NEXT();
3282 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3283 wordp = &ep_3550->serial_number_word1;
3284 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3285 wordp = &ep_38C0800->serial_number_word1;
3286 } else {
3287 wordp = &ep_38C1600->serial_number_word1;
3290 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
3291 len =
3292 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3293 serialstr);
3294 ASC_PRT_NEXT();
3295 } else {
3296 len = asc_prt_line(cp, leftlen,
3297 " Serial Number Signature Not Present.\n");
3298 ASC_PRT_NEXT();
3301 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3302 len = asc_prt_line(cp, leftlen,
3303 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3304 ep_3550->adapter_scsi_id,
3305 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
3306 ASC_PRT_NEXT();
3307 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3308 len = asc_prt_line(cp, leftlen,
3309 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3310 ep_38C0800->adapter_scsi_id,
3311 ep_38C0800->max_host_qng,
3312 ep_38C0800->max_dvc_qng);
3313 ASC_PRT_NEXT();
3314 } else {
3315 len = asc_prt_line(cp, leftlen,
3316 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3317 ep_38C1600->adapter_scsi_id,
3318 ep_38C1600->max_host_qng,
3319 ep_38C1600->max_dvc_qng);
3320 ASC_PRT_NEXT();
3322 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3323 word = ep_3550->termination;
3324 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3325 word = ep_38C0800->termination_lvd;
3326 } else {
3327 word = ep_38C1600->termination_lvd;
3329 switch (word) {
3330 case 1:
3331 termstr = "Low Off/High Off";
3332 break;
3333 case 2:
3334 termstr = "Low Off/High On";
3335 break;
3336 case 3:
3337 termstr = "Low On/High On";
3338 break;
3339 default:
3340 case 0:
3341 termstr = "Automatic";
3342 break;
3345 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3346 len = asc_prt_line(cp, leftlen,
3347 " termination: %u (%s), bios_ctrl: 0x%x\n",
3348 ep_3550->termination, termstr,
3349 ep_3550->bios_ctrl);
3350 ASC_PRT_NEXT();
3351 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3352 len = asc_prt_line(cp, leftlen,
3353 " termination: %u (%s), bios_ctrl: 0x%x\n",
3354 ep_38C0800->termination_lvd, termstr,
3355 ep_38C0800->bios_ctrl);
3356 ASC_PRT_NEXT();
3357 } else {
3358 len = asc_prt_line(cp, leftlen,
3359 " termination: %u (%s), bios_ctrl: 0x%x\n",
3360 ep_38C1600->termination_lvd, termstr,
3361 ep_38C1600->bios_ctrl);
3362 ASC_PRT_NEXT();
3365 len = asc_prt_line(cp, leftlen, " Target ID: ");
3366 ASC_PRT_NEXT();
3367 for (i = 0; i <= ADV_MAX_TID; i++) {
3368 len = asc_prt_line(cp, leftlen, " %X", i);
3369 ASC_PRT_NEXT();
3371 len = asc_prt_line(cp, leftlen, "\n");
3372 ASC_PRT_NEXT();
3374 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3375 word = ep_3550->disc_enable;
3376 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3377 word = ep_38C0800->disc_enable;
3378 } else {
3379 word = ep_38C1600->disc_enable;
3381 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3382 ASC_PRT_NEXT();
3383 for (i = 0; i <= ADV_MAX_TID; i++) {
3384 len = asc_prt_line(cp, leftlen, " %c",
3385 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3386 ASC_PRT_NEXT();
3388 len = asc_prt_line(cp, leftlen, "\n");
3389 ASC_PRT_NEXT();
3391 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3392 word = ep_3550->tagqng_able;
3393 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3394 word = ep_38C0800->tagqng_able;
3395 } else {
3396 word = ep_38C1600->tagqng_able;
3398 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3399 ASC_PRT_NEXT();
3400 for (i = 0; i <= ADV_MAX_TID; i++) {
3401 len = asc_prt_line(cp, leftlen, " %c",
3402 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3403 ASC_PRT_NEXT();
3405 len = asc_prt_line(cp, leftlen, "\n");
3406 ASC_PRT_NEXT();
3408 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3409 word = ep_3550->start_motor;
3410 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3411 word = ep_38C0800->start_motor;
3412 } else {
3413 word = ep_38C1600->start_motor;
3415 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3416 ASC_PRT_NEXT();
3417 for (i = 0; i <= ADV_MAX_TID; i++) {
3418 len = asc_prt_line(cp, leftlen, " %c",
3419 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3420 ASC_PRT_NEXT();
3422 len = asc_prt_line(cp, leftlen, "\n");
3423 ASC_PRT_NEXT();
3425 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3426 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3427 ASC_PRT_NEXT();
3428 for (i = 0; i <= ADV_MAX_TID; i++) {
3429 len = asc_prt_line(cp, leftlen, " %c",
3430 (ep_3550->
3431 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3432 'Y' : 'N');
3433 ASC_PRT_NEXT();
3435 len = asc_prt_line(cp, leftlen, "\n");
3436 ASC_PRT_NEXT();
3439 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3440 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
3441 ASC_PRT_NEXT();
3442 for (i = 0; i <= ADV_MAX_TID; i++) {
3443 len = asc_prt_line(cp, leftlen, " %c",
3444 (ep_3550->
3445 ultra_able & ADV_TID_TO_TIDMASK(i))
3446 ? 'Y' : 'N');
3447 ASC_PRT_NEXT();
3449 len = asc_prt_line(cp, leftlen, "\n");
3450 ASC_PRT_NEXT();
3453 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3454 word = ep_3550->wdtr_able;
3455 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3456 word = ep_38C0800->wdtr_able;
3457 } else {
3458 word = ep_38C1600->wdtr_able;
3460 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
3461 ASC_PRT_NEXT();
3462 for (i = 0; i <= ADV_MAX_TID; i++) {
3463 len = asc_prt_line(cp, leftlen, " %c",
3464 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3465 ASC_PRT_NEXT();
3467 len = asc_prt_line(cp, leftlen, "\n");
3468 ASC_PRT_NEXT();
3470 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3471 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3472 len = asc_prt_line(cp, leftlen,
3473 " Synchronous Transfer Speed (Mhz):\n ");
3474 ASC_PRT_NEXT();
3475 for (i = 0; i <= ADV_MAX_TID; i++) {
3476 char *speed_str;
3478 if (i == 0) {
3479 sdtr_speed = adv_dvc_varp->sdtr_speed1;
3480 } else if (i == 4) {
3481 sdtr_speed = adv_dvc_varp->sdtr_speed2;
3482 } else if (i == 8) {
3483 sdtr_speed = adv_dvc_varp->sdtr_speed3;
3484 } else if (i == 12) {
3485 sdtr_speed = adv_dvc_varp->sdtr_speed4;
3487 switch (sdtr_speed & ADV_MAX_TID) {
3488 case 0:
3489 speed_str = "Off";
3490 break;
3491 case 1:
3492 speed_str = " 5";
3493 break;
3494 case 2:
3495 speed_str = " 10";
3496 break;
3497 case 3:
3498 speed_str = " 20";
3499 break;
3500 case 4:
3501 speed_str = " 40";
3502 break;
3503 case 5:
3504 speed_str = " 80";
3505 break;
3506 default:
3507 speed_str = "Unk";
3508 break;
3510 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
3511 ASC_PRT_NEXT();
3512 if (i == 7) {
3513 len = asc_prt_line(cp, leftlen, "\n ");
3514 ASC_PRT_NEXT();
3516 sdtr_speed >>= 4;
3518 len = asc_prt_line(cp, leftlen, "\n");
3519 ASC_PRT_NEXT();
3522 return totlen;
3526 * asc_prt_driver_conf()
3528 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3529 * cf. asc_prt_line().
3531 * Return the number of characters copied into 'cp'. No more than
3532 * 'cplen' characters will be copied to 'cp'.
3534 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
3536 struct asc_board *boardp = shost_priv(shost);
3537 int leftlen;
3538 int totlen;
3539 int len;
3540 int chip_scsi_id;
3542 leftlen = cplen;
3543 totlen = len = 0;
3545 len = asc_prt_line(cp, leftlen,
3546 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3547 shost->host_no);
3548 ASC_PRT_NEXT();
3550 len = asc_prt_line(cp, leftlen,
3551 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
3552 shost->host_busy, shost->last_reset, shost->max_id,
3553 shost->max_lun, shost->max_channel);
3554 ASC_PRT_NEXT();
3556 len = asc_prt_line(cp, leftlen,
3557 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3558 shost->unique_id, shost->can_queue, shost->this_id,
3559 shost->sg_tablesize, shost->cmd_per_lun);
3560 ASC_PRT_NEXT();
3562 len = asc_prt_line(cp, leftlen,
3563 " unchecked_isa_dma %d, use_clustering %d\n",
3564 shost->unchecked_isa_dma, shost->use_clustering);
3565 ASC_PRT_NEXT();
3567 len = asc_prt_line(cp, leftlen,
3568 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
3569 boardp->flags, boardp->last_reset, jiffies,
3570 boardp->asc_n_io_port);
3571 ASC_PRT_NEXT();
3573 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3574 ASC_PRT_NEXT();
3576 if (ASC_NARROW_BOARD(boardp)) {
3577 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3578 } else {
3579 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3582 return totlen;
3586 * asc_prt_asc_board_info()
3588 * Print dynamic board configuration information.
3590 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3591 * cf. asc_prt_line().
3593 * Return the number of characters copied into 'cp'. No more than
3594 * 'cplen' characters will be copied to 'cp'.
3596 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3598 struct asc_board *boardp = shost_priv(shost);
3599 int chip_scsi_id;
3600 int leftlen;
3601 int totlen;
3602 int len;
3603 ASC_DVC_VAR *v;
3604 ASC_DVC_CFG *c;
3605 int i;
3606 int renegotiate = 0;
3608 v = &boardp->dvc_var.asc_dvc_var;
3609 c = &boardp->dvc_cfg.asc_dvc_cfg;
3610 chip_scsi_id = c->chip_scsi_id;
3612 leftlen = cplen;
3613 totlen = len = 0;
3615 len = asc_prt_line(cp, leftlen,
3616 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3617 shost->host_no);
3618 ASC_PRT_NEXT();
3620 len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3621 "mcode_version 0x%x, err_code %u\n",
3622 c->chip_version, c->mcode_date, c->mcode_version,
3623 v->err_code);
3624 ASC_PRT_NEXT();
3626 /* Current number of commands waiting for the host. */
3627 len = asc_prt_line(cp, leftlen,
3628 " Total Command Pending: %d\n", v->cur_total_qng);
3629 ASC_PRT_NEXT();
3631 len = asc_prt_line(cp, leftlen, " Command Queuing:");
3632 ASC_PRT_NEXT();
3633 for (i = 0; i <= ASC_MAX_TID; i++) {
3634 if ((chip_scsi_id == i) ||
3635 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3636 continue;
3638 len = asc_prt_line(cp, leftlen, " %X:%c",
3640 (v->
3641 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3642 'Y' : 'N');
3643 ASC_PRT_NEXT();
3645 len = asc_prt_line(cp, leftlen, "\n");
3646 ASC_PRT_NEXT();
3648 /* Current number of commands waiting for a device. */
3649 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
3650 ASC_PRT_NEXT();
3651 for (i = 0; i <= ASC_MAX_TID; i++) {
3652 if ((chip_scsi_id == i) ||
3653 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3654 continue;
3656 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3657 ASC_PRT_NEXT();
3659 len = asc_prt_line(cp, leftlen, "\n");
3660 ASC_PRT_NEXT();
3662 /* Current limit on number of commands that can be sent to a device. */
3663 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
3664 ASC_PRT_NEXT();
3665 for (i = 0; i <= ASC_MAX_TID; i++) {
3666 if ((chip_scsi_id == i) ||
3667 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3668 continue;
3670 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3671 ASC_PRT_NEXT();
3673 len = asc_prt_line(cp, leftlen, "\n");
3674 ASC_PRT_NEXT();
3676 /* Indicate whether the device has returned queue full status. */
3677 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
3678 ASC_PRT_NEXT();
3679 for (i = 0; i <= ASC_MAX_TID; i++) {
3680 if ((chip_scsi_id == i) ||
3681 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3682 continue;
3684 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
3685 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
3686 i, boardp->queue_full_cnt[i]);
3687 } else {
3688 len = asc_prt_line(cp, leftlen, " %X:N", i);
3690 ASC_PRT_NEXT();
3692 len = asc_prt_line(cp, leftlen, "\n");
3693 ASC_PRT_NEXT();
3695 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3696 ASC_PRT_NEXT();
3697 for (i = 0; i <= ASC_MAX_TID; i++) {
3698 if ((chip_scsi_id == i) ||
3699 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3700 continue;
3702 len = asc_prt_line(cp, leftlen, " %X:%c",
3704 (v->
3705 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3706 'N');
3707 ASC_PRT_NEXT();
3709 len = asc_prt_line(cp, leftlen, "\n");
3710 ASC_PRT_NEXT();
3712 for (i = 0; i <= ASC_MAX_TID; i++) {
3713 uchar syn_period_ix;
3715 if ((chip_scsi_id == i) ||
3716 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3717 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3718 continue;
3721 len = asc_prt_line(cp, leftlen, " %X:", i);
3722 ASC_PRT_NEXT();
3724 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3725 len = asc_prt_line(cp, leftlen, " Asynchronous");
3726 ASC_PRT_NEXT();
3727 } else {
3728 syn_period_ix =
3729 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3732 len = asc_prt_line(cp, leftlen,
3733 " Transfer Period Factor: %d (%d.%d Mhz),",
3734 v->sdtr_period_tbl[syn_period_ix],
3735 250 /
3736 v->sdtr_period_tbl[syn_period_ix],
3737 ASC_TENTHS(250,
3739 sdtr_period_tbl
3740 [syn_period_ix]));
3741 ASC_PRT_NEXT();
3743 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3744 boardp->
3745 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3746 ASC_PRT_NEXT();
3749 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3750 len = asc_prt_line(cp, leftlen, "*\n");
3751 renegotiate = 1;
3752 } else {
3753 len = asc_prt_line(cp, leftlen, "\n");
3755 ASC_PRT_NEXT();
3758 if (renegotiate) {
3759 len = asc_prt_line(cp, leftlen,
3760 " * = Re-negotiation pending before next command.\n");
3761 ASC_PRT_NEXT();
3764 return totlen;
3768 * asc_prt_adv_board_info()
3770 * Print dynamic board configuration information.
3772 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3773 * cf. asc_prt_line().
3775 * Return the number of characters copied into 'cp'. No more than
3776 * 'cplen' characters will be copied to 'cp'.
3778 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3780 struct asc_board *boardp = shost_priv(shost);
3781 int leftlen;
3782 int totlen;
3783 int len;
3784 int i;
3785 ADV_DVC_VAR *v;
3786 ADV_DVC_CFG *c;
3787 AdvPortAddr iop_base;
3788 ushort chip_scsi_id;
3789 ushort lramword;
3790 uchar lrambyte;
3791 ushort tagqng_able;
3792 ushort sdtr_able, wdtr_able;
3793 ushort wdtr_done, sdtr_done;
3794 ushort period = 0;
3795 int renegotiate = 0;
3797 v = &boardp->dvc_var.adv_dvc_var;
3798 c = &boardp->dvc_cfg.adv_dvc_cfg;
3799 iop_base = v->iop_base;
3800 chip_scsi_id = v->chip_scsi_id;
3802 leftlen = cplen;
3803 totlen = len = 0;
3805 len = asc_prt_line(cp, leftlen,
3806 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3807 shost->host_no);
3808 ASC_PRT_NEXT();
3810 len = asc_prt_line(cp, leftlen,
3811 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3812 v->iop_base,
3813 AdvReadWordRegister(iop_base,
3814 IOPW_SCSI_CFG1) & CABLE_DETECT,
3815 v->err_code);
3816 ASC_PRT_NEXT();
3818 len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3819 "mcode_version 0x%x\n", c->chip_version,
3820 c->mcode_date, c->mcode_version);
3821 ASC_PRT_NEXT();
3823 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3824 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
3825 ASC_PRT_NEXT();
3826 for (i = 0; i <= ADV_MAX_TID; i++) {
3827 if ((chip_scsi_id == i) ||
3828 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3829 continue;
3832 len = asc_prt_line(cp, leftlen, " %X:%c",
3834 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3835 'N');
3836 ASC_PRT_NEXT();
3838 len = asc_prt_line(cp, leftlen, "\n");
3839 ASC_PRT_NEXT();
3841 len = asc_prt_line(cp, leftlen, " Queue Limit:");
3842 ASC_PRT_NEXT();
3843 for (i = 0; i <= ADV_MAX_TID; i++) {
3844 if ((chip_scsi_id == i) ||
3845 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3846 continue;
3849 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3850 lrambyte);
3852 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3853 ASC_PRT_NEXT();
3855 len = asc_prt_line(cp, leftlen, "\n");
3856 ASC_PRT_NEXT();
3858 len = asc_prt_line(cp, leftlen, " Command Pending:");
3859 ASC_PRT_NEXT();
3860 for (i = 0; i <= ADV_MAX_TID; i++) {
3861 if ((chip_scsi_id == i) ||
3862 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3863 continue;
3866 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
3867 lrambyte);
3869 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3870 ASC_PRT_NEXT();
3872 len = asc_prt_line(cp, leftlen, "\n");
3873 ASC_PRT_NEXT();
3875 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
3876 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
3877 ASC_PRT_NEXT();
3878 for (i = 0; i <= ADV_MAX_TID; i++) {
3879 if ((chip_scsi_id == i) ||
3880 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3881 continue;
3884 len = asc_prt_line(cp, leftlen, " %X:%c",
3886 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3887 'N');
3888 ASC_PRT_NEXT();
3890 len = asc_prt_line(cp, leftlen, "\n");
3891 ASC_PRT_NEXT();
3893 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
3894 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
3895 ASC_PRT_NEXT();
3896 for (i = 0; i <= ADV_MAX_TID; i++) {
3897 if ((chip_scsi_id == i) ||
3898 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3899 continue;
3902 AdvReadWordLram(iop_base,
3903 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3904 lramword);
3906 len = asc_prt_line(cp, leftlen, " %X:%d",
3907 i, (lramword & 0x8000) ? 16 : 8);
3908 ASC_PRT_NEXT();
3910 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
3911 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3912 len = asc_prt_line(cp, leftlen, "*");
3913 ASC_PRT_NEXT();
3914 renegotiate = 1;
3917 len = asc_prt_line(cp, leftlen, "\n");
3918 ASC_PRT_NEXT();
3920 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
3921 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
3922 ASC_PRT_NEXT();
3923 for (i = 0; i <= ADV_MAX_TID; i++) {
3924 if ((chip_scsi_id == i) ||
3925 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3926 continue;
3929 len = asc_prt_line(cp, leftlen, " %X:%c",
3931 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3932 'N');
3933 ASC_PRT_NEXT();
3935 len = asc_prt_line(cp, leftlen, "\n");
3936 ASC_PRT_NEXT();
3938 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
3939 for (i = 0; i <= ADV_MAX_TID; i++) {
3941 AdvReadWordLram(iop_base,
3942 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3943 lramword);
3944 lramword &= ~0x8000;
3946 if ((chip_scsi_id == i) ||
3947 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3948 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
3949 continue;
3952 len = asc_prt_line(cp, leftlen, " %X:", i);
3953 ASC_PRT_NEXT();
3955 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
3956 len = asc_prt_line(cp, leftlen, " Asynchronous");
3957 ASC_PRT_NEXT();
3958 } else {
3959 len =
3960 asc_prt_line(cp, leftlen,
3961 " Transfer Period Factor: ");
3962 ASC_PRT_NEXT();
3964 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
3965 len =
3966 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
3967 ASC_PRT_NEXT();
3968 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
3969 len =
3970 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
3971 ASC_PRT_NEXT();
3972 } else { /* 20 Mhz or below. */
3974 period = (((lramword >> 8) * 25) + 50) / 4;
3976 if (period == 0) { /* Should never happen. */
3977 len =
3978 asc_prt_line(cp, leftlen,
3979 "%d (? Mhz), ");
3980 ASC_PRT_NEXT();
3981 } else {
3982 len = asc_prt_line(cp, leftlen,
3983 "%d (%d.%d Mhz),",
3984 period, 250 / period,
3985 ASC_TENTHS(250,
3986 period));
3987 ASC_PRT_NEXT();
3991 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3992 lramword & 0x1F);
3993 ASC_PRT_NEXT();
3996 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3997 len = asc_prt_line(cp, leftlen, "*\n");
3998 renegotiate = 1;
3999 } else {
4000 len = asc_prt_line(cp, leftlen, "\n");
4002 ASC_PRT_NEXT();
4005 if (renegotiate) {
4006 len = asc_prt_line(cp, leftlen,
4007 " * = Re-negotiation pending before next command.\n");
4008 ASC_PRT_NEXT();
4011 return totlen;
4015 * asc_proc_copy()
4017 * Copy proc information to a read buffer taking into account the current
4018 * read offset in the file and the remaining space in the read buffer.
4020 static int
4021 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4022 char *cp, int cplen)
4024 int cnt = 0;
4026 ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n",
4027 (unsigned)offset, (unsigned)advoffset, cplen);
4028 if (offset <= advoffset) {
4029 /* Read offset below current offset, copy everything. */
4030 cnt = min(cplen, leftlen);
4031 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4032 (ulong)curbuf, (ulong)cp, cnt);
4033 memcpy(curbuf, cp, cnt);
4034 } else if (offset < advoffset + cplen) {
4035 /* Read offset within current range, partial copy. */
4036 cnt = (advoffset + cplen) - offset;
4037 cp = (cp + cplen) - cnt;
4038 cnt = min(cnt, leftlen);
4039 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4040 (ulong)curbuf, (ulong)cp, cnt);
4041 memcpy(curbuf, cp, cnt);
4043 return cnt;
4046 #ifdef ADVANSYS_STATS
4048 * asc_prt_board_stats()
4050 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4051 * cf. asc_prt_line().
4053 * Return the number of characters copied into 'cp'. No more than
4054 * 'cplen' characters will be copied to 'cp'.
4056 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
4058 struct asc_board *boardp = shost_priv(shost);
4059 struct asc_stats *s = &boardp->asc_stats;
4061 int leftlen = cplen;
4062 int len, totlen = 0;
4064 len = asc_prt_line(cp, leftlen,
4065 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
4066 shost->host_no);
4067 ASC_PRT_NEXT();
4069 len = asc_prt_line(cp, leftlen,
4070 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4071 s->queuecommand, s->reset, s->biosparam,
4072 s->interrupt);
4073 ASC_PRT_NEXT();
4075 len = asc_prt_line(cp, leftlen,
4076 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
4077 s->callback, s->done, s->build_error,
4078 s->adv_build_noreq, s->adv_build_nosg);
4079 ASC_PRT_NEXT();
4081 len = asc_prt_line(cp, leftlen,
4082 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
4083 s->exe_noerror, s->exe_busy, s->exe_error,
4084 s->exe_unknown);
4085 ASC_PRT_NEXT();
4088 * Display data transfer statistics.
4090 if (s->cont_cnt > 0) {
4091 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
4092 ASC_PRT_NEXT();
4094 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
4095 s->cont_xfer / 2,
4096 ASC_TENTHS(s->cont_xfer, 2));
4097 ASC_PRT_NEXT();
4099 /* Contiguous transfer average size */
4100 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
4101 (s->cont_xfer / 2) / s->cont_cnt,
4102 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
4103 ASC_PRT_NEXT();
4106 if (s->sg_cnt > 0) {
4108 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
4109 s->sg_cnt, s->sg_elem);
4110 ASC_PRT_NEXT();
4112 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
4113 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
4114 ASC_PRT_NEXT();
4116 /* Scatter gather transfer statistics */
4117 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
4118 s->sg_elem / s->sg_cnt,
4119 ASC_TENTHS(s->sg_elem, s->sg_cnt));
4120 ASC_PRT_NEXT();
4122 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
4123 (s->sg_xfer / 2) / s->sg_elem,
4124 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
4125 ASC_PRT_NEXT();
4127 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
4128 (s->sg_xfer / 2) / s->sg_cnt,
4129 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
4130 ASC_PRT_NEXT();
4134 * Display request queuing statistics.
4136 len = asc_prt_line(cp, leftlen,
4137 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
4138 HZ);
4139 ASC_PRT_NEXT();
4141 return totlen;
4143 #endif /* ADVANSYS_STATS */
4146 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
4148 * *buffer: I/O buffer
4149 * **start: if inout == FALSE pointer into buffer where user read should start
4150 * offset: current offset into a /proc/scsi/advansys/[0...] file
4151 * length: length of buffer
4152 * hostno: Scsi_Host host_no
4153 * inout: TRUE - user is writing; FALSE - user is reading
4155 * Return the number of bytes read from or written to a
4156 * /proc/scsi/advansys/[0...] file.
4158 * Note: This function uses the per board buffer 'prtbuf' which is
4159 * allocated when the board is initialized in advansys_detect(). The
4160 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4161 * used to write to the buffer. The way asc_proc_copy() is written
4162 * if 'prtbuf' is too small it will not be overwritten. Instead the
4163 * user just won't get all the available statistics.
4165 static int
4166 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4167 off_t offset, int length, int inout)
4169 struct asc_board *boardp = shost_priv(shost);
4170 char *cp;
4171 int cplen;
4172 int cnt;
4173 int totcnt;
4174 int leftlen;
4175 char *curbuf;
4176 off_t advoffset;
4178 ASC_DBG(1, "begin\n");
4181 * User write not supported.
4183 if (inout == TRUE)
4184 return -ENOSYS;
4187 * User read of /proc/scsi/advansys/[0...] file.
4190 /* Copy read data starting at the beginning of the buffer. */
4191 *start = buffer;
4192 curbuf = buffer;
4193 advoffset = 0;
4194 totcnt = 0;
4195 leftlen = length;
4198 * Get board configuration information.
4200 * advansys_info() returns the board string from its own static buffer.
4202 cp = (char *)advansys_info(shost);
4203 strcat(cp, "\n");
4204 cplen = strlen(cp);
4205 /* Copy board information. */
4206 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4207 totcnt += cnt;
4208 leftlen -= cnt;
4209 if (leftlen == 0) {
4210 ASC_DBG(1, "totcnt %d\n", totcnt);
4211 return totcnt;
4213 advoffset += cplen;
4214 curbuf += cnt;
4217 * Display Wide Board BIOS Information.
4219 if (!ASC_NARROW_BOARD(boardp)) {
4220 cp = boardp->prtbuf;
4221 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4222 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4223 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4224 cplen);
4225 totcnt += cnt;
4226 leftlen -= cnt;
4227 if (leftlen == 0) {
4228 ASC_DBG(1, "totcnt %d\n", totcnt);
4229 return totcnt;
4231 advoffset += cplen;
4232 curbuf += cnt;
4236 * Display driver information for each device attached to the board.
4238 cp = boardp->prtbuf;
4239 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4240 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4241 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4242 totcnt += cnt;
4243 leftlen -= cnt;
4244 if (leftlen == 0) {
4245 ASC_DBG(1, "totcnt %d\n", totcnt);
4246 return totcnt;
4248 advoffset += cplen;
4249 curbuf += cnt;
4252 * Display EEPROM configuration for the board.
4254 cp = boardp->prtbuf;
4255 if (ASC_NARROW_BOARD(boardp)) {
4256 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4257 } else {
4258 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4260 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4261 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4262 totcnt += cnt;
4263 leftlen -= cnt;
4264 if (leftlen == 0) {
4265 ASC_DBG(1, "totcnt %d\n", totcnt);
4266 return totcnt;
4268 advoffset += cplen;
4269 curbuf += cnt;
4272 * Display driver configuration and information for the board.
4274 cp = boardp->prtbuf;
4275 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4276 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4277 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4278 totcnt += cnt;
4279 leftlen -= cnt;
4280 if (leftlen == 0) {
4281 ASC_DBG(1, "totcnt %d\n", totcnt);
4282 return totcnt;
4284 advoffset += cplen;
4285 curbuf += cnt;
4287 #ifdef ADVANSYS_STATS
4289 * Display driver statistics for the board.
4291 cp = boardp->prtbuf;
4292 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4293 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4294 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4295 totcnt += cnt;
4296 leftlen -= cnt;
4297 if (leftlen == 0) {
4298 ASC_DBG(1, "totcnt %d\n", totcnt);
4299 return totcnt;
4301 advoffset += cplen;
4302 curbuf += cnt;
4303 #endif /* ADVANSYS_STATS */
4306 * Display Asc Library dynamic configuration information
4307 * for the board.
4309 cp = boardp->prtbuf;
4310 if (ASC_NARROW_BOARD(boardp)) {
4311 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4312 } else {
4313 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4315 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4316 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4317 totcnt += cnt;
4318 leftlen -= cnt;
4319 if (leftlen == 0) {
4320 ASC_DBG(1, "totcnt %d\n", totcnt);
4321 return totcnt;
4323 advoffset += cplen;
4324 curbuf += cnt;
4326 ASC_DBG(1, "totcnt %d\n", totcnt);
4328 return totcnt;
4330 #endif /* CONFIG_PROC_FS */
4332 static void asc_scsi_done(struct scsi_cmnd *scp)
4334 struct asc_board *boardp = shost_priv(scp->device->host);
4336 if (scp->use_sg)
4337 dma_unmap_sg(boardp->dev,
4338 (struct scatterlist *)scp->request_buffer,
4339 scp->use_sg, scp->sc_data_direction);
4340 else if (scp->request_bufflen)
4341 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
4342 scp->request_bufflen, scp->sc_data_direction);
4344 ASC_STATS(scp->device->host, done);
4346 scp->scsi_done(scp);
4349 static void AscSetBank(PortAddr iop_base, uchar bank)
4351 uchar val;
4353 val = AscGetChipControl(iop_base) &
4355 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
4356 CC_CHIP_RESET));
4357 if (bank == 1) {
4358 val |= CC_BANK_ONE;
4359 } else if (bank == 2) {
4360 val |= CC_DIAG | CC_BANK_ONE;
4361 } else {
4362 val &= ~CC_BANK_ONE;
4364 AscSetChipControl(iop_base, val);
4367 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4369 AscSetBank(iop_base, 1);
4370 AscWriteChipIH(iop_base, ins_code);
4371 AscSetBank(iop_base, 0);
4374 static int AscStartChip(PortAddr iop_base)
4376 AscSetChipControl(iop_base, 0);
4377 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4378 return (0);
4380 return (1);
4383 static int AscStopChip(PortAddr iop_base)
4385 uchar cc_val;
4387 cc_val =
4388 AscGetChipControl(iop_base) &
4389 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
4390 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
4391 AscSetChipIH(iop_base, INS_HALT);
4392 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4393 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
4394 return (0);
4396 return (1);
4399 static int AscIsChipHalted(PortAddr iop_base)
4401 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4402 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4403 return (1);
4406 return (0);
4409 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4411 PortAddr iop_base;
4412 int i = 10;
4414 iop_base = asc_dvc->iop_base;
4415 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4416 && (i-- > 0)) {
4417 mdelay(100);
4419 AscStopChip(iop_base);
4420 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
4421 udelay(60);
4422 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4423 AscSetChipIH(iop_base, INS_HALT);
4424 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
4425 AscSetChipControl(iop_base, CC_HALT);
4426 mdelay(200);
4427 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
4428 AscSetChipStatus(iop_base, 0);
4429 return (AscIsChipHalted(iop_base));
4432 static int AscFindSignature(PortAddr iop_base)
4434 ushort sig_word;
4436 ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n",
4437 iop_base, AscGetChipSignatureByte(iop_base));
4438 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
4439 ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n",
4440 iop_base, AscGetChipSignatureWord(iop_base));
4441 sig_word = AscGetChipSignatureWord(iop_base);
4442 if ((sig_word == (ushort)ASC_1000_ID0W) ||
4443 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
4444 return (1);
4447 return (0);
4450 static void AscEnableInterrupt(PortAddr iop_base)
4452 ushort cfg;
4454 cfg = AscGetChipCfgLsw(iop_base);
4455 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
4458 static void AscDisableInterrupt(PortAddr iop_base)
4460 ushort cfg;
4462 cfg = AscGetChipCfgLsw(iop_base);
4463 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
4466 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4468 unsigned char byte_data;
4469 unsigned short word_data;
4471 if (isodd_word(addr)) {
4472 AscSetChipLramAddr(iop_base, addr - 1);
4473 word_data = AscGetChipLramData(iop_base);
4474 byte_data = (word_data >> 8) & 0xFF;
4475 } else {
4476 AscSetChipLramAddr(iop_base, addr);
4477 word_data = AscGetChipLramData(iop_base);
4478 byte_data = word_data & 0xFF;
4480 return byte_data;
4483 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4485 ushort word_data;
4487 AscSetChipLramAddr(iop_base, addr);
4488 word_data = AscGetChipLramData(iop_base);
4489 return (word_data);
4492 #if CC_VERY_LONG_SG_LIST
4493 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4495 ushort val_low, val_high;
4496 ASC_DCNT dword_data;
4498 AscSetChipLramAddr(iop_base, addr);
4499 val_low = AscGetChipLramData(iop_base);
4500 val_high = AscGetChipLramData(iop_base);
4501 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
4502 return (dword_data);
4504 #endif /* CC_VERY_LONG_SG_LIST */
4506 static void
4507 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4509 int i;
4511 AscSetChipLramAddr(iop_base, s_addr);
4512 for (i = 0; i < words; i++) {
4513 AscSetChipLramData(iop_base, set_wval);
4517 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4519 AscSetChipLramAddr(iop_base, addr);
4520 AscSetChipLramData(iop_base, word_val);
4523 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4525 ushort word_data;
4527 if (isodd_word(addr)) {
4528 addr--;
4529 word_data = AscReadLramWord(iop_base, addr);
4530 word_data &= 0x00FF;
4531 word_data |= (((ushort)byte_val << 8) & 0xFF00);
4532 } else {
4533 word_data = AscReadLramWord(iop_base, addr);
4534 word_data &= 0xFF00;
4535 word_data |= ((ushort)byte_val & 0x00FF);
4537 AscWriteLramWord(iop_base, addr, word_data);
4541 * Copy 2 bytes to LRAM.
4543 * The source data is assumed to be in little-endian order in memory
4544 * and is maintained in little-endian order when written to LRAM.
4546 static void
4547 AscMemWordCopyPtrToLram(PortAddr iop_base,
4548 ushort s_addr, uchar *s_buffer, int words)
4550 int i;
4552 AscSetChipLramAddr(iop_base, s_addr);
4553 for (i = 0; i < 2 * words; i += 2) {
4555 * On a little-endian system the second argument below
4556 * produces a little-endian ushort which is written to
4557 * LRAM in little-endian order. On a big-endian system
4558 * the second argument produces a big-endian ushort which
4559 * is "transparently" byte-swapped by outpw() and written
4560 * in little-endian order to LRAM.
4562 outpw(iop_base + IOP_RAM_DATA,
4563 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4568 * Copy 4 bytes to LRAM.
4570 * The source data is assumed to be in little-endian order in memory
4571 * and is maintained in little-endian order when writen to LRAM.
4573 static void
4574 AscMemDWordCopyPtrToLram(PortAddr iop_base,
4575 ushort s_addr, uchar *s_buffer, int dwords)
4577 int i;
4579 AscSetChipLramAddr(iop_base, s_addr);
4580 for (i = 0; i < 4 * dwords; i += 4) {
4581 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
4582 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
4587 * Copy 2 bytes from LRAM.
4589 * The source data is assumed to be in little-endian order in LRAM
4590 * and is maintained in little-endian order when written to memory.
4592 static void
4593 AscMemWordCopyPtrFromLram(PortAddr iop_base,
4594 ushort s_addr, uchar *d_buffer, int words)
4596 int i;
4597 ushort word;
4599 AscSetChipLramAddr(iop_base, s_addr);
4600 for (i = 0; i < 2 * words; i += 2) {
4601 word = inpw(iop_base + IOP_RAM_DATA);
4602 d_buffer[i] = word & 0xff;
4603 d_buffer[i + 1] = (word >> 8) & 0xff;
4607 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4609 ASC_DCNT sum;
4610 int i;
4612 sum = 0L;
4613 for (i = 0; i < words; i++, s_addr += 2) {
4614 sum += AscReadLramWord(iop_base, s_addr);
4616 return (sum);
4619 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4621 uchar i;
4622 ushort s_addr;
4623 PortAddr iop_base;
4624 ushort warn_code;
4626 iop_base = asc_dvc->iop_base;
4627 warn_code = 0;
4628 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
4629 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
4630 64) >> 1));
4631 i = ASC_MIN_ACTIVE_QNO;
4632 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
4633 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4634 (uchar)(i + 1));
4635 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4636 (uchar)(asc_dvc->max_total_qng));
4637 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4638 (uchar)i);
4639 i++;
4640 s_addr += ASC_QBLK_SIZE;
4641 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
4642 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4643 (uchar)(i + 1));
4644 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4645 (uchar)(i - 1));
4646 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4647 (uchar)i);
4649 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4650 (uchar)ASC_QLINK_END);
4651 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4652 (uchar)(asc_dvc->max_total_qng - 1));
4653 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4654 (uchar)asc_dvc->max_total_qng);
4655 i++;
4656 s_addr += ASC_QBLK_SIZE;
4657 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
4658 i++, s_addr += ASC_QBLK_SIZE) {
4659 AscWriteLramByte(iop_base,
4660 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
4661 AscWriteLramByte(iop_base,
4662 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
4663 AscWriteLramByte(iop_base,
4664 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
4666 return warn_code;
4669 static ASC_DCNT
4670 AscLoadMicroCode(PortAddr iop_base,
4671 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
4673 ASC_DCNT chksum;
4674 ushort mcode_word_size;
4675 ushort mcode_chksum;
4677 /* Write the microcode buffer starting at LRAM address 0. */
4678 mcode_word_size = (ushort)(mcode_size >> 1);
4679 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
4680 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
4682 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
4683 ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum);
4684 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
4685 (ushort)ASC_CODE_SEC_BEG,
4686 (ushort)((mcode_size -
4687 s_addr - (ushort)
4688 ASC_CODE_SEC_BEG) /
4689 2));
4690 ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum);
4691 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4692 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
4693 return chksum;
4696 /* Microcode buffer is kept after initialization for error recovery. */
4697 static uchar _asc_mcode_buf[] = {
4698 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4699 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
4700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
4704 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4705 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4706 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
4707 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
4708 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
4709 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
4710 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
4711 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
4712 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
4713 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
4714 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
4715 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
4716 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
4717 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
4718 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
4719 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
4720 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
4721 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
4722 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
4723 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
4724 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
4725 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
4726 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
4727 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
4728 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
4729 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
4730 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
4731 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
4732 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
4733 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
4734 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
4735 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
4736 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
4737 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
4738 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
4739 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
4740 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
4741 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
4742 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
4743 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
4744 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
4745 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
4746 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
4747 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
4748 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
4749 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
4750 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
4751 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
4752 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
4753 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
4754 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
4755 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
4756 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
4757 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
4758 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
4759 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
4760 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
4761 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
4762 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
4763 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
4764 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
4765 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
4766 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
4767 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
4768 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
4769 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
4770 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
4771 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
4772 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
4773 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
4774 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
4775 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
4776 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4777 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
4778 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4779 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
4780 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
4781 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
4782 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
4783 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
4784 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
4785 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
4786 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
4787 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
4788 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
4789 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
4790 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
4791 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
4792 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
4793 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
4794 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
4795 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
4796 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
4797 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
4798 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
4799 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
4800 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
4801 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
4802 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
4803 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
4804 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
4805 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
4806 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
4807 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
4808 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
4809 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
4810 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
4811 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
4812 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
4813 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
4814 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
4815 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
4816 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
4817 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
4818 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
4819 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
4820 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
4821 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
4822 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
4823 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
4824 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
4825 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
4826 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
4827 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
4828 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
4829 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
4830 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
4831 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
4832 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
4833 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
4834 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
4835 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
4836 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
4837 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
4838 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
4839 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
4840 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
4841 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
4842 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
4843 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
4844 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
4845 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
4846 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
4847 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
4848 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
4849 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
4850 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
4851 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
4852 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
4853 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
4854 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
4855 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
4856 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
4857 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
4858 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
4859 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
4860 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
4861 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
4862 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
4863 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
4864 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
4865 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
4866 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
4867 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
4868 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
4869 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
4870 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
4871 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
4872 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
4873 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
4874 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
4875 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
4876 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
4877 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
4878 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
4879 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
4880 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
4881 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
4882 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
4883 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
4884 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
4885 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
4886 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
4887 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
4888 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
4889 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
4892 static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
4893 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
4895 /* Microcode buffer is kept after initialization for error recovery. */
4896 static unsigned char _adv_asc3550_buf[] = {
4897 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
4898 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
4899 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
4900 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
4901 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
4902 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
4903 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
4904 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
4905 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
4906 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
4907 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
4908 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
4909 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
4910 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
4911 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
4912 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
4913 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
4914 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
4915 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
4916 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
4917 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
4918 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
4919 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
4920 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
4921 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
4922 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
4923 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
4924 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
4925 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
4926 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
4927 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
4928 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
4929 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
4930 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
4931 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
4932 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
4933 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
4934 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
4935 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
4936 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
4937 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
4938 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
4939 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
4940 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
4941 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
4942 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
4943 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
4944 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
4945 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
4946 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
4947 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
4948 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
4949 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
4950 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
4951 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
4952 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
4953 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
4954 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
4955 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
4956 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
4957 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
4958 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
4959 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
4960 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
4961 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
4962 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
4963 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
4964 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
4965 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
4966 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
4967 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
4968 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
4969 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
4970 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
4971 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
4972 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
4973 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
4974 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
4975 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
4976 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
4977 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
4978 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
4979 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
4980 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
4981 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
4982 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
4983 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
4984 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
4985 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
4986 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
4987 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
4988 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
4989 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
4990 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
4991 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
4992 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
4993 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
4994 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
4995 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
4996 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
4997 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
4998 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
4999 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
5000 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
5001 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
5002 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
5003 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
5004 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
5005 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
5006 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
5007 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
5008 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
5009 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
5010 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
5011 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
5012 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
5013 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
5014 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
5015 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
5016 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
5017 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
5018 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
5019 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
5020 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
5021 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
5022 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
5023 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
5024 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
5025 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
5026 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
5027 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
5028 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
5029 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
5030 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
5031 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
5032 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
5033 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
5034 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
5035 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
5036 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
5037 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
5038 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
5039 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
5040 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
5041 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
5042 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5043 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
5044 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
5045 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
5046 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
5047 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
5048 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
5049 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
5050 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
5051 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
5052 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
5053 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
5054 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
5055 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
5056 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
5057 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
5058 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
5059 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
5060 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
5061 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
5062 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5063 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
5064 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
5065 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
5066 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
5067 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
5068 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
5069 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
5070 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
5071 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
5072 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
5073 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
5074 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
5075 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
5076 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
5077 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
5078 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
5079 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
5080 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
5081 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
5082 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
5083 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
5084 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
5085 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
5086 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
5087 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
5088 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
5089 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5090 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
5091 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
5092 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
5093 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
5094 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
5095 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
5096 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
5097 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
5098 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
5099 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
5100 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
5101 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
5102 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
5103 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
5104 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
5105 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
5106 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
5107 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
5108 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
5109 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
5110 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
5111 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
5112 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
5113 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
5114 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
5115 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
5116 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
5117 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
5118 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
5119 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
5120 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
5121 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
5122 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
5123 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
5124 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
5125 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
5126 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
5127 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
5128 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
5129 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
5130 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
5131 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
5132 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
5133 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
5134 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
5135 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
5136 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
5137 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
5138 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
5139 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
5140 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
5141 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
5142 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
5143 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
5144 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5145 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
5146 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
5147 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
5148 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
5149 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5150 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
5151 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5152 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
5153 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
5154 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
5155 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5156 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
5157 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5158 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
5159 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5160 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
5161 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5162 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
5163 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
5164 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
5165 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
5166 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
5167 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5168 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
5169 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
5170 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
5171 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
5172 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
5173 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
5174 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
5175 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
5176 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
5177 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
5178 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
5179 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
5180 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
5181 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
5182 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
5183 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
5184 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
5185 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
5186 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
5187 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
5188 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
5189 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
5190 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
5191 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
5192 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
5193 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
5194 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
5195 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
5196 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
5197 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
5198 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
5199 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
5200 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
5201 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
5202 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
5203 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
5204 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
5205 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
5206 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
5207 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
5208 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
5209 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
5210 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
5211 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
5212 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
5213 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
5214 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
5215 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
5216 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
5217 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
5218 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
5219 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
5220 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
5221 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5222 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
5223 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
5224 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5225 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
5226 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
5227 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
5228 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
5229 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
5230 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
5231 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
5232 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
5233 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
5234 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
5235 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
5236 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
5237 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
5238 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
5239 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
5240 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
5241 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
5242 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
5243 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
5244 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
5245 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
5246 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
5247 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
5248 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
5249 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
5250 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
5251 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
5252 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
5253 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
5254 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
5255 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
5256 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
5257 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
5258 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
5259 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
5260 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
5261 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
5262 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
5263 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
5264 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
5265 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
5266 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
5267 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
5268 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
5269 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
5270 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
5271 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
5272 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
5273 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
5274 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
5275 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
5276 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
5277 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
5278 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
5279 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
5280 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
5281 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
5282 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
5283 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
5284 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
5285 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
5286 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
5287 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
5288 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
5289 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
5290 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
5291 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
5292 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
5293 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
5294 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
5295 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
5296 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
5297 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
5298 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
5299 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
5300 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
5301 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
5302 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
5303 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
5304 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
5305 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
5306 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
5307 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
5308 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
5309 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
5310 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
5311 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
5312 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
5313 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
5314 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5315 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
5318 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
5319 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
5321 /* Microcode buffer is kept after initialization for error recovery. */
5322 static unsigned char _adv_asc38C0800_buf[] = {
5323 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
5324 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
5325 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
5326 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
5327 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
5328 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
5329 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
5330 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
5331 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
5332 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
5333 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
5334 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5335 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
5336 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
5337 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
5338 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5339 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
5340 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
5341 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
5342 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
5343 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
5344 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
5345 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
5346 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
5347 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
5348 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
5349 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
5350 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
5351 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
5352 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
5353 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
5354 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
5355 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
5356 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
5357 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
5358 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
5359 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
5360 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
5361 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
5362 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
5363 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
5364 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
5365 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
5366 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
5367 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5368 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
5369 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5370 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
5371 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5372 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
5373 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
5374 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
5375 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
5376 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
5377 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5378 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
5379 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
5380 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
5381 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
5382 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
5383 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
5384 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
5385 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
5386 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
5387 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5388 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
5389 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
5390 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
5391 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
5392 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
5393 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
5394 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
5395 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
5396 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
5397 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
5398 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
5399 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
5400 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
5401 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
5402 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
5403 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
5404 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
5405 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
5406 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
5407 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
5408 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
5409 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
5410 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
5411 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
5412 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
5413 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
5414 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
5415 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
5416 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5417 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
5418 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
5419 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
5420 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
5421 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
5422 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
5423 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5424 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5425 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
5426 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
5427 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
5428 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
5429 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
5430 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
5431 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
5432 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
5433 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
5434 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
5435 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
5436 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
5437 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
5438 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
5439 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
5440 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
5441 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
5442 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
5443 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
5444 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
5445 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
5446 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
5447 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
5448 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
5449 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
5450 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
5451 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
5452 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
5453 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
5454 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
5455 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
5456 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
5457 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
5458 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
5459 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
5460 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
5461 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
5462 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
5463 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
5464 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
5465 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
5466 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
5467 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
5468 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
5469 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
5470 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
5471 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
5472 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
5473 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
5474 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
5475 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
5476 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
5477 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
5478 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
5479 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
5480 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
5481 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
5482 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
5483 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
5484 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
5485 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
5486 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
5487 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
5488 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
5489 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
5490 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
5491 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
5492 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
5493 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
5494 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
5495 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
5496 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
5497 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
5498 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
5499 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
5500 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
5501 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
5502 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
5503 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
5504 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
5505 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
5506 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
5507 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
5508 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
5509 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
5510 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
5511 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
5512 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
5513 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
5514 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
5515 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
5516 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
5517 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
5518 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
5519 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
5520 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
5521 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
5522 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
5523 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
5524 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
5525 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
5526 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
5527 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
5528 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
5529 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
5530 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
5531 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
5532 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
5533 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
5534 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
5535 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
5536 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
5537 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
5538 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
5539 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
5540 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
5541 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
5542 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
5543 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
5544 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
5545 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
5546 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
5547 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
5548 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
5549 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
5550 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
5551 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
5552 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
5553 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
5554 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
5555 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
5556 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
5557 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
5558 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
5559 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
5560 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
5561 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
5562 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
5563 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
5564 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
5565 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
5566 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
5567 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
5568 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
5569 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
5570 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
5571 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
5572 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
5573 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
5574 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
5575 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
5576 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
5577 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
5578 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
5579 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
5580 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
5581 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
5582 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
5583 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
5584 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
5585 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
5586 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
5587 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
5588 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
5589 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
5590 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
5591 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
5592 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5593 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
5594 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
5595 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
5596 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
5597 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5598 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
5599 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5600 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
5601 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
5602 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
5603 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5604 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
5605 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5606 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
5607 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5608 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
5609 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5610 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
5611 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
5612 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
5613 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
5614 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
5615 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5616 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
5617 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
5618 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
5619 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
5620 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
5621 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
5622 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
5623 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
5624 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
5625 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
5626 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
5627 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
5628 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
5629 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
5630 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
5631 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
5632 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
5633 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
5634 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
5635 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
5636 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
5637 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
5638 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
5639 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
5640 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
5641 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
5642 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
5643 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
5644 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
5645 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
5646 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
5647 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
5648 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
5649 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
5650 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
5651 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
5652 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
5653 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
5654 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
5655 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
5656 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
5657 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
5658 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
5659 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
5660 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
5661 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
5662 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
5663 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
5664 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
5665 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
5666 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
5667 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
5668 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
5669 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5670 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
5671 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
5672 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5673 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
5674 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
5675 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
5676 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
5677 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
5678 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
5679 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
5680 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
5681 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
5682 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
5683 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
5684 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
5685 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
5686 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
5687 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
5688 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
5689 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
5690 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
5691 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
5692 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
5693 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
5694 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
5695 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
5696 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
5697 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
5698 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
5699 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5700 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5701 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
5702 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
5703 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
5704 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
5705 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
5706 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
5707 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
5708 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
5709 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
5710 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
5711 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
5712 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
5713 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
5714 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
5715 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
5716 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
5717 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
5718 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
5719 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
5720 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
5721 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
5722 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
5723 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
5724 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
5725 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
5726 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
5727 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
5728 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
5729 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
5730 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
5731 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
5732 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
5733 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
5734 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
5735 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
5736 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
5737 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
5738 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
5739 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
5740 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
5741 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
5742 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
5743 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
5744 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
5745 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
5746 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
5747 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
5748 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
5749 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
5750 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
5751 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
5752 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
5753 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
5754 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
5755 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
5756 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
5757 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
5758 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
5759 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
5760 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
5761 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
5762 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
5763 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
5764 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
5765 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
5766 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
5767 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
5770 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
5771 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
5773 /* Microcode buffer is kept after initialization for error recovery. */
5774 static unsigned char _adv_asc38C1600_buf[] = {
5775 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
5776 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
5777 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
5778 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
5779 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
5780 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
5781 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
5782 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
5783 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
5784 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
5785 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
5786 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
5787 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5788 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
5789 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
5790 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
5791 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
5792 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
5793 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
5794 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
5795 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
5796 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
5797 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
5798 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
5799 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
5800 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
5801 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
5802 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
5803 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
5804 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
5805 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
5806 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
5807 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
5808 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
5809 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
5810 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
5811 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
5812 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
5813 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
5814 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
5815 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
5816 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
5817 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
5818 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
5819 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5820 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
5821 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5822 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
5823 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5824 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
5825 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
5826 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
5827 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
5828 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
5829 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
5830 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
5831 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
5832 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
5833 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
5834 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
5835 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
5836 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
5837 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
5838 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
5839 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
5840 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
5841 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
5842 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
5843 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
5844 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
5845 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
5846 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
5847 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
5848 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
5849 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
5850 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
5851 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
5852 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
5853 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
5854 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
5855 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
5856 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
5857 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
5858 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
5859 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
5860 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
5861 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
5862 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
5863 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
5864 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
5865 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
5866 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
5867 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
5868 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
5869 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
5870 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
5871 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
5872 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
5873 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
5874 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
5875 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
5876 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
5877 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
5878 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
5879 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
5880 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
5881 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
5882 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
5883 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
5884 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
5885 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
5886 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
5887 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
5888 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
5889 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
5890 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
5891 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
5892 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
5893 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
5894 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
5895 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
5896 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
5897 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
5898 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
5899 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
5900 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
5901 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
5902 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
5903 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
5904 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
5905 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
5906 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
5907 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
5908 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
5909 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
5910 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
5911 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
5912 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
5913 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
5914 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
5915 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
5916 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
5917 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
5918 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
5919 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
5920 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
5921 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
5922 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
5923 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
5924 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
5925 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
5926 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
5927 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
5928 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
5929 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
5930 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
5931 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
5932 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
5933 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
5934 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
5935 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
5936 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
5937 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
5938 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
5939 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
5940 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
5941 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5942 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
5943 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
5944 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
5945 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
5946 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
5947 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
5948 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
5949 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
5950 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
5951 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
5952 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
5953 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
5954 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
5955 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
5956 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
5957 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
5958 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
5959 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
5960 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
5961 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
5962 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
5963 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
5964 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
5965 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
5966 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
5967 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
5968 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
5969 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
5970 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
5971 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
5972 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
5973 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
5974 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
5975 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
5976 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
5977 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
5978 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
5979 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
5980 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
5981 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
5982 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
5983 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
5984 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
5985 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
5986 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
5987 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
5988 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
5989 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
5990 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
5991 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
5992 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
5993 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
5994 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
5995 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
5996 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
5997 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
5998 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
5999 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
6000 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
6001 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
6002 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
6003 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
6004 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
6005 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
6006 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
6007 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
6008 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
6009 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
6010 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
6011 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
6012 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
6013 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
6014 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
6015 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
6016 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
6017 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
6018 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
6019 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
6020 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
6021 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
6022 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
6023 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
6024 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
6025 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
6026 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
6027 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
6028 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
6029 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
6030 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
6031 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
6032 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
6033 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
6034 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
6035 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
6036 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
6037 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
6038 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
6039 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
6040 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
6041 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
6042 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
6043 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
6044 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
6045 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
6046 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
6047 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
6048 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
6049 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
6050 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
6051 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
6052 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
6053 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
6054 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
6055 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
6056 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
6057 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
6058 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
6059 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
6060 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
6061 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
6062 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
6063 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
6064 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
6065 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
6066 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
6067 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
6068 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
6069 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
6070 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
6071 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
6072 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
6073 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
6074 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
6075 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
6076 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
6077 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
6078 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
6079 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
6080 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
6081 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
6082 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
6083 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
6084 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
6085 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
6086 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
6087 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
6088 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
6089 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
6090 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
6091 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
6092 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
6093 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
6094 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
6095 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
6096 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
6097 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
6098 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
6099 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
6100 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
6101 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
6102 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
6103 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
6104 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
6105 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
6106 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
6107 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
6108 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
6109 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
6110 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
6111 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
6112 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6113 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
6114 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
6115 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6116 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
6117 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
6118 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
6119 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
6120 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
6121 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
6122 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
6123 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
6124 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
6125 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
6126 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
6127 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
6128 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
6129 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
6130 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
6131 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
6132 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
6133 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
6134 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
6135 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
6136 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
6137 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
6138 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
6139 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
6140 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
6141 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
6142 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
6143 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
6144 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
6145 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
6146 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
6147 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
6148 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
6149 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
6150 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
6151 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6152 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
6153 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
6154 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6155 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
6156 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
6157 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
6158 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
6159 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
6160 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
6161 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
6162 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
6163 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
6164 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
6165 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
6166 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
6167 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
6168 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
6169 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
6170 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
6171 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
6172 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
6173 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
6174 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
6175 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
6176 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
6177 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
6178 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
6179 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
6180 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
6181 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
6182 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
6183 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
6184 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
6185 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
6186 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
6187 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
6188 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
6189 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
6190 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
6191 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
6192 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
6193 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
6194 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
6195 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
6196 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
6197 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
6198 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
6199 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
6200 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
6201 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
6202 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
6203 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
6204 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
6205 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
6206 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
6207 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
6208 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
6209 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6210 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6211 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
6212 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
6213 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
6214 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
6215 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
6216 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
6217 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
6218 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
6219 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
6220 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
6221 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
6222 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
6223 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
6224 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
6225 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
6226 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
6227 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
6228 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
6229 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
6230 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
6231 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
6232 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
6233 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
6234 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
6235 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
6236 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
6237 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
6238 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
6239 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
6240 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
6241 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
6242 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
6243 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
6244 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
6245 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
6246 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
6247 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
6248 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
6249 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
6250 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
6251 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
6252 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
6253 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
6254 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
6255 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
6256 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
6257 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
6258 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
6259 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
6260 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
6261 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
6262 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
6263 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
6264 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
6265 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
6266 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
6267 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
6268 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
6269 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
6270 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
6271 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
6272 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
6273 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
6274 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
6275 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
6276 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
6277 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
6278 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
6279 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
6280 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
6281 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
6282 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
6283 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
6284 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
6285 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
6286 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
6287 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
6288 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
6289 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
6290 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
6291 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
6292 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
6293 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
6294 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6295 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6296 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6297 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6298 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6299 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6300 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
6301 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
6302 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
6305 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
6306 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
6308 static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6310 PortAddr iop_base;
6311 int i;
6312 ushort lram_addr;
6314 iop_base = asc_dvc->iop_base;
6315 AscPutRiscVarFreeQHead(iop_base, 1);
6316 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6317 AscPutVarFreeQHead(iop_base, 1);
6318 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6319 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6320 (uchar)((int)asc_dvc->max_total_qng + 1));
6321 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6322 (uchar)((int)asc_dvc->max_total_qng + 2));
6323 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
6324 asc_dvc->max_total_qng);
6325 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6326 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6327 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6328 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6329 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6330 AscPutQDoneInProgress(iop_base, 0);
6331 lram_addr = ASC_QADR_BEG;
6332 for (i = 0; i < 32; i++, lram_addr += 2) {
6333 AscWriteLramWord(iop_base, lram_addr, 0);
6337 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6339 int i;
6340 ushort warn_code;
6341 PortAddr iop_base;
6342 ASC_PADDR phy_addr;
6343 ASC_DCNT phy_size;
6345 iop_base = asc_dvc->iop_base;
6346 warn_code = 0;
6347 for (i = 0; i <= ASC_MAX_TID; i++) {
6348 AscPutMCodeInitSDTRAtID(iop_base, i,
6349 asc_dvc->cfg->sdtr_period_offset[i]);
6352 AscInitQLinkVar(asc_dvc);
6353 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
6354 asc_dvc->cfg->disc_enable);
6355 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
6356 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
6358 /* Align overrun buffer on an 8 byte boundary. */
6359 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
6360 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
6361 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
6362 (uchar *)&phy_addr, 1);
6363 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
6364 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
6365 (uchar *)&phy_size, 1);
6367 asc_dvc->cfg->mcode_date =
6368 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
6369 asc_dvc->cfg->mcode_version =
6370 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
6372 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6373 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6374 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
6375 return warn_code;
6377 if (AscStartChip(iop_base) != 1) {
6378 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6379 return warn_code;
6382 return warn_code;
6385 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6387 ushort warn_code;
6388 PortAddr iop_base;
6390 iop_base = asc_dvc->iop_base;
6391 warn_code = 0;
6392 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
6393 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
6394 AscResetChipAndScsiBus(asc_dvc);
6395 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6397 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
6398 if (asc_dvc->err_code != 0)
6399 return UW_ERR;
6400 if (!AscFindSignature(asc_dvc->iop_base)) {
6401 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
6402 return warn_code;
6404 AscDisableInterrupt(iop_base);
6405 warn_code |= AscInitLram(asc_dvc);
6406 if (asc_dvc->err_code != 0)
6407 return UW_ERR;
6408 ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
6409 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
6410 _asc_mcode_size) != _asc_mcode_chksum) {
6411 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
6412 return warn_code;
6414 warn_code |= AscInitMicroCodeVar(asc_dvc);
6415 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
6416 AscEnableInterrupt(iop_base);
6417 return warn_code;
6421 * Load the Microcode
6423 * Write the microcode image to RISC memory starting at address 0.
6425 * The microcode is stored compressed in the following format:
6427 * 254 word (508 byte) table indexed by byte code followed
6428 * by the following byte codes:
6430 * 1-Byte Code:
6431 * 00: Emit word 0 in table.
6432 * 01: Emit word 1 in table.
6434 * FD: Emit word 253 in table.
6436 * Multi-Byte Code:
6437 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
6438 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
6440 * Returns 0 or an error if the checksum doesn't match
6442 static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6443 int memsize, int chksum)
6445 int i, j, end, len = 0;
6446 ADV_DCNT sum;
6448 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6450 for (i = 253 * 2; i < size; i++) {
6451 if (buf[i] == 0xff) {
6452 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
6453 for (j = 0; j < buf[i + 1]; j++) {
6454 AdvWriteWordAutoIncLram(iop_base, word);
6455 len += 2;
6457 i += 3;
6458 } else if (buf[i] == 0xfe) {
6459 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
6460 AdvWriteWordAutoIncLram(iop_base, word);
6461 i += 2;
6462 len += 2;
6463 } else {
6464 unsigned char off = buf[i] * 2;
6465 unsigned short word = (buf[off + 1] << 8) | buf[off];
6466 AdvWriteWordAutoIncLram(iop_base, word);
6467 len += 2;
6471 end = len;
6473 while (len < memsize) {
6474 AdvWriteWordAutoIncLram(iop_base, 0);
6475 len += 2;
6478 /* Verify the microcode checksum. */
6479 sum = 0;
6480 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6482 for (len = 0; len < end; len += 2) {
6483 sum += AdvReadWordAutoIncLram(iop_base);
6486 if (sum != chksum)
6487 return ASC_IERR_MCODE_CHKSUM;
6489 return 0;
6493 * DvcGetPhyAddr()
6495 * Return the physical address of 'vaddr' and set '*lenp' to the
6496 * number of physically contiguous bytes that follow 'vaddr'.
6497 * 'flag' indicates the type of structure whose physical address
6498 * is being translated.
6500 * Note: Because Linux currently doesn't page the kernel and all
6501 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6503 ADV_PADDR
6504 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
6505 uchar *vaddr, ADV_SDCNT *lenp, int flag)
6507 ADV_PADDR paddr = virt_to_bus(vaddr);
6509 ASC_DBG(4, "vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n",
6510 vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr);
6512 return paddr;
6515 static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6517 ADV_CARR_T *carrp;
6518 ADV_SDCNT buf_size;
6519 ADV_PADDR carr_paddr;
6521 BUG_ON(!asc_dvc->carrier_buf);
6523 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
6524 asc_dvc->carr_freelist = NULL;
6525 if (carrp == asc_dvc->carrier_buf) {
6526 buf_size = ADV_CARRIER_BUFSIZE;
6527 } else {
6528 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
6531 do {
6532 /* Get physical address of the carrier 'carrp'. */
6533 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
6534 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
6535 (uchar *)carrp,
6536 (ADV_SDCNT *)&contig_len,
6537 ADV_IS_CARRIER_FLAG));
6539 buf_size -= sizeof(ADV_CARR_T);
6542 * If the current carrier is not physically contiguous, then
6543 * maybe there was a page crossing. Try the next carrier
6544 * aligned start address.
6546 if (contig_len < sizeof(ADV_CARR_T)) {
6547 carrp++;
6548 continue;
6551 carrp->carr_pa = carr_paddr;
6552 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6555 * Insert the carrier at the beginning of the freelist.
6557 carrp->next_vpa =
6558 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6559 asc_dvc->carr_freelist = carrp;
6561 carrp++;
6562 } while (buf_size > 0);
6566 * Send an idle command to the chip and wait for completion.
6568 * Command completion is polled for once per microsecond.
6570 * The function can be called from anywhere including an interrupt handler.
6571 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
6572 * functions to prevent reentrancy.
6574 * Return Values:
6575 * ADV_TRUE - command completed successfully
6576 * ADV_FALSE - command failed
6577 * ADV_ERROR - command timed out
6579 static int
6580 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6581 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6583 int result;
6584 ADV_DCNT i, j;
6585 AdvPortAddr iop_base;
6587 iop_base = asc_dvc->iop_base;
6590 * Clear the idle command status which is set by the microcode
6591 * to a non-zero value to indicate when the command is completed.
6592 * The non-zero result is one of the IDLE_CMD_STATUS_* values
6594 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6597 * Write the idle command value after the idle command parameter
6598 * has been written to avoid a race condition. If the order is not
6599 * followed, the microcode may process the idle command before the
6600 * parameters have been written to LRAM.
6602 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
6603 cpu_to_le32(idle_cmd_parameter));
6604 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
6607 * Tickle the RISC to tell it to process the idle command.
6609 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6610 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6612 * Clear the tickle value. In the ASC-3550 the RISC flag
6613 * command 'clr_tickle_b' does not work unless the host
6614 * value is cleared.
6616 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6619 /* Wait for up to 100 millisecond for the idle command to timeout. */
6620 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
6621 /* Poll once each microsecond for command completion. */
6622 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
6623 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
6624 result);
6625 if (result != 0)
6626 return result;
6627 udelay(1);
6631 BUG(); /* The idle command should never timeout. */
6632 return ADV_ERROR;
6636 * Reset SCSI Bus and purge all outstanding requests.
6638 * Return Value:
6639 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
6640 * ADV_FALSE(0) - Microcode command failed.
6641 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
6642 * may be hung which requires driver recovery.
6644 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6646 int status;
6649 * Send the SCSI Bus Reset idle start idle command which asserts
6650 * the SCSI Bus Reset signal.
6652 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6653 if (status != ADV_TRUE) {
6654 return status;
6658 * Delay for the specified SCSI Bus Reset hold time.
6660 * The hold time delay is done on the host because the RISC has no
6661 * microsecond accurate timer.
6663 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6666 * Send the SCSI Bus Reset end idle command which de-asserts
6667 * the SCSI Bus Reset signal and purges any pending requests.
6669 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6670 if (status != ADV_TRUE) {
6671 return status;
6674 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6676 return status;
6680 * Initialize the ASC-3550.
6682 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6684 * For a non-fatal error return a warning code. If there are no warnings
6685 * then 0 is returned.
6687 * Needed after initialization for error recovery.
6689 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6691 AdvPortAddr iop_base;
6692 ushort warn_code;
6693 int begin_addr;
6694 int end_addr;
6695 ushort code_sum;
6696 int word;
6697 int i;
6698 ushort scsi_cfg1;
6699 uchar tid;
6700 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
6701 ushort wdtr_able = 0, sdtr_able, tagqng_able;
6702 uchar max_cmd[ADV_MAX_TID + 1];
6704 /* If there is already an error, don't continue. */
6705 if (asc_dvc->err_code != 0)
6706 return ADV_ERROR;
6709 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6711 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6712 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6713 return ADV_ERROR;
6716 warn_code = 0;
6717 iop_base = asc_dvc->iop_base;
6720 * Save the RISC memory BIOS region before writing the microcode.
6721 * The BIOS may already be loaded and using its RISC LRAM region
6722 * so its region must be saved and restored.
6724 * Note: This code makes the assumption, which is currently true,
6725 * that a chip reset does not clear RISC LRAM.
6727 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6728 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6729 bios_mem[i]);
6733 * Save current per TID negotiated values.
6735 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6736 ushort bios_version, major, minor;
6738 bios_version =
6739 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
6740 major = (bios_version >> 12) & 0xF;
6741 minor = (bios_version >> 8) & 0xF;
6742 if (major < 3 || (major == 3 && minor == 1)) {
6743 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
6744 AdvReadWordLram(iop_base, 0x120, wdtr_able);
6745 } else {
6746 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6749 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6750 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6751 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6752 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
6753 max_cmd[tid]);
6756 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
6757 _adv_asc3550_size, ADV_3550_MEMSIZE,
6758 _adv_asc3550_chksum);
6759 if (asc_dvc->err_code)
6760 return ADV_ERROR;
6763 * Restore the RISC memory BIOS region.
6765 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6766 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6767 bios_mem[i]);
6771 * Calculate and write the microcode code checksum to the microcode
6772 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6774 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
6775 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
6776 code_sum = 0;
6777 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
6778 for (word = begin_addr; word < end_addr; word += 2) {
6779 code_sum += AdvReadWordAutoIncLram(iop_base);
6781 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6784 * Read and save microcode version and date.
6786 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
6787 asc_dvc->cfg->mcode_date);
6788 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
6789 asc_dvc->cfg->mcode_version);
6792 * Set the chip type to indicate the ASC3550.
6794 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6797 * If the PCI Configuration Command Register "Parity Error Response
6798 * Control" Bit was clear (0), then set the microcode variable
6799 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
6800 * to ignore DMA parity errors.
6802 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
6803 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6804 word |= CONTROL_FLAG_IGNORE_PERR;
6805 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6809 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
6810 * threshold of 128 bytes. This register is only accessible to the host.
6812 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6813 START_CTL_EMFU | READ_CMD_MRM);
6816 * Microcode operating variables for WDTR, SDTR, and command tag
6817 * queuing will be set in slave_configure() based on what a
6818 * device reports it is capable of in Inquiry byte 7.
6820 * If SCSI Bus Resets have been disabled, then directly set
6821 * SDTR and WDTR from the EEPROM configuration. This will allow
6822 * the BIOS and warm boot to work without a SCSI bus hang on
6823 * the Inquiry caused by host and target mismatched DTR values.
6824 * Without the SCSI Bus Reset, before an Inquiry a device can't
6825 * be assumed to be in Asynchronous, Narrow mode.
6827 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
6828 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
6829 asc_dvc->wdtr_able);
6830 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
6831 asc_dvc->sdtr_able);
6835 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
6836 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
6837 * bitmask. These values determine the maximum SDTR speed negotiated
6838 * with a device.
6840 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
6841 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
6842 * without determining here whether the device supports SDTR.
6844 * 4-bit speed SDTR speed name
6845 * =========== ===============
6846 * 0000b (0x0) SDTR disabled
6847 * 0001b (0x1) 5 Mhz
6848 * 0010b (0x2) 10 Mhz
6849 * 0011b (0x3) 20 Mhz (Ultra)
6850 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
6851 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
6852 * 0110b (0x6) Undefined
6854 * 1111b (0xF) Undefined
6856 word = 0;
6857 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6858 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
6859 /* Set Ultra speed for TID 'tid'. */
6860 word |= (0x3 << (4 * (tid % 4)));
6861 } else {
6862 /* Set Fast speed for TID 'tid'. */
6863 word |= (0x2 << (4 * (tid % 4)));
6865 if (tid == 3) { /* Check if done with sdtr_speed1. */
6866 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
6867 word = 0;
6868 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
6869 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
6870 word = 0;
6871 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
6872 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
6873 word = 0;
6874 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
6875 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
6876 /* End of loop. */
6881 * Set microcode operating variable for the disconnect per TID bitmask.
6883 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
6884 asc_dvc->cfg->disc_enable);
6887 * Set SCSI_CFG0 Microcode Default Value.
6889 * The microcode will set the SCSI_CFG0 register using this value
6890 * after it is started below.
6892 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
6893 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
6894 asc_dvc->chip_scsi_id);
6897 * Determine SCSI_CFG1 Microcode Default Value.
6899 * The microcode will set the SCSI_CFG1 register using this value
6900 * after it is started below.
6903 /* Read current SCSI_CFG1 Register value. */
6904 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
6907 * If all three connectors are in use, return an error.
6909 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
6910 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
6911 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
6912 return ADV_ERROR;
6916 * If the internal narrow cable is reversed all of the SCSI_CTRL
6917 * register signals will be set. Check for and return an error if
6918 * this condition is found.
6920 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
6921 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
6922 return ADV_ERROR;
6926 * If this is a differential board and a single-ended device
6927 * is attached to one of the connectors, return an error.
6929 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
6930 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
6931 return ADV_ERROR;
6935 * If automatic termination control is enabled, then set the
6936 * termination value based on a table listed in a_condor.h.
6938 * If manual termination was specified with an EEPROM setting
6939 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
6940 * is ready to be 'ored' into SCSI_CFG1.
6942 if (asc_dvc->cfg->termination == 0) {
6944 * The software always controls termination by setting TERM_CTL_SEL.
6945 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
6947 asc_dvc->cfg->termination |= TERM_CTL_SEL;
6949 switch (scsi_cfg1 & CABLE_DETECT) {
6950 /* TERM_CTL_H: on, TERM_CTL_L: on */
6951 case 0x3:
6952 case 0x7:
6953 case 0xB:
6954 case 0xD:
6955 case 0xE:
6956 case 0xF:
6957 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
6958 break;
6960 /* TERM_CTL_H: on, TERM_CTL_L: off */
6961 case 0x1:
6962 case 0x5:
6963 case 0x9:
6964 case 0xA:
6965 case 0xC:
6966 asc_dvc->cfg->termination |= TERM_CTL_H;
6967 break;
6969 /* TERM_CTL_H: off, TERM_CTL_L: off */
6970 case 0x2:
6971 case 0x6:
6972 break;
6977 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
6979 scsi_cfg1 &= ~TERM_CTL;
6982 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
6983 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
6984 * referenced, because the hardware internally inverts
6985 * the Termination High and Low bits if TERM_POL is set.
6987 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
6990 * Set SCSI_CFG1 Microcode Default Value
6992 * Set filter value and possibly modified termination control
6993 * bits in the Microcode SCSI_CFG1 Register Value.
6995 * The microcode will set the SCSI_CFG1 register using this value
6996 * after it is started below.
6998 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
6999 FLTR_DISABLE | scsi_cfg1);
7002 * Set MEM_CFG Microcode Default Value
7004 * The microcode will set the MEM_CFG register using this value
7005 * after it is started below.
7007 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7008 * are defined.
7010 * ASC-3550 has 8KB internal memory.
7012 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7013 BIOS_EN | RAM_SZ_8KB);
7016 * Set SEL_MASK Microcode Default Value
7018 * The microcode will set the SEL_MASK register using this value
7019 * after it is started below.
7021 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7022 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7024 AdvBuildCarrierFreelist(asc_dvc);
7027 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7030 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7031 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7032 return ADV_ERROR;
7034 asc_dvc->carr_freelist = (ADV_CARR_T *)
7035 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7038 * The first command issued will be placed in the stopper carrier.
7040 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7043 * Set RISC ICQ physical address start value.
7045 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7048 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7050 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7051 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7052 return ADV_ERROR;
7054 asc_dvc->carr_freelist = (ADV_CARR_T *)
7055 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7058 * The first command completed by the RISC will be placed in
7059 * the stopper.
7061 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7062 * completed the RISC will set the ASC_RQ_STOPPER bit.
7064 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7067 * Set RISC IRQ physical address start value.
7069 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7070 asc_dvc->carr_pending_cnt = 0;
7072 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7073 (ADV_INTR_ENABLE_HOST_INTR |
7074 ADV_INTR_ENABLE_GLOBAL_INTR));
7076 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7077 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7079 /* finally, finally, gentlemen, start your engine */
7080 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7083 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7084 * Resets should be performed. The RISC has to be running
7085 * to issue a SCSI Bus Reset.
7087 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7089 * If the BIOS Signature is present in memory, restore the
7090 * BIOS Handshake Configuration Table and do not perform
7091 * a SCSI Bus Reset.
7093 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7094 0x55AA) {
7096 * Restore per TID negotiated values.
7098 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7099 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7100 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7101 tagqng_able);
7102 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7103 AdvWriteByteLram(iop_base,
7104 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7105 max_cmd[tid]);
7107 } else {
7108 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7109 warn_code = ASC_WARN_BUSRESET_ERROR;
7114 return warn_code;
7118 * Initialize the ASC-38C0800.
7120 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7122 * For a non-fatal error return a warning code. If there are no warnings
7123 * then 0 is returned.
7125 * Needed after initialization for error recovery.
7127 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7129 AdvPortAddr iop_base;
7130 ushort warn_code;
7131 int begin_addr;
7132 int end_addr;
7133 ushort code_sum;
7134 int word;
7135 int i;
7136 ushort scsi_cfg1;
7137 uchar byte;
7138 uchar tid;
7139 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7140 ushort wdtr_able, sdtr_able, tagqng_able;
7141 uchar max_cmd[ADV_MAX_TID + 1];
7143 /* If there is already an error, don't continue. */
7144 if (asc_dvc->err_code != 0)
7145 return ADV_ERROR;
7148 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7150 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7151 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7152 return ADV_ERROR;
7155 warn_code = 0;
7156 iop_base = asc_dvc->iop_base;
7159 * Save the RISC memory BIOS region before writing the microcode.
7160 * The BIOS may already be loaded and using its RISC LRAM region
7161 * so its region must be saved and restored.
7163 * Note: This code makes the assumption, which is currently true,
7164 * that a chip reset does not clear RISC LRAM.
7166 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7167 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7168 bios_mem[i]);
7172 * Save current per TID negotiated values.
7174 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7175 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7176 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7177 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7178 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7179 max_cmd[tid]);
7183 * RAM BIST (RAM Built-In Self Test)
7185 * Address : I/O base + offset 0x38h register (byte).
7186 * Function: Bit 7-6(RW) : RAM mode
7187 * Normal Mode : 0x00
7188 * Pre-test Mode : 0x40
7189 * RAM Test Mode : 0x80
7190 * Bit 5 : unused
7191 * Bit 4(RO) : Done bit
7192 * Bit 3-0(RO) : Status
7193 * Host Error : 0x08
7194 * Int_RAM Error : 0x04
7195 * RISC Error : 0x02
7196 * SCSI Error : 0x01
7197 * No Error : 0x00
7199 * Note: RAM BIST code should be put right here, before loading the
7200 * microcode and after saving the RISC memory BIOS region.
7204 * LRAM Pre-test
7206 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7207 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7208 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7209 * to NORMAL_MODE, return an error too.
7211 for (i = 0; i < 2; i++) {
7212 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7213 mdelay(10); /* Wait for 10ms before reading back. */
7214 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7215 if ((byte & RAM_TEST_DONE) == 0
7216 || (byte & 0x0F) != PRE_TEST_VALUE) {
7217 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7218 return ADV_ERROR;
7221 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7222 mdelay(10); /* Wait for 10ms before reading back. */
7223 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7224 != NORMAL_VALUE) {
7225 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7226 return ADV_ERROR;
7231 * LRAM Test - It takes about 1.5 ms to run through the test.
7233 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7234 * If Done bit not set or Status not 0, save register byte, set the
7235 * err_code, and return an error.
7237 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7238 mdelay(10); /* Wait for 10ms before checking status. */
7240 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7241 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7242 /* Get here if Done bit not set or Status not 0. */
7243 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7244 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7245 return ADV_ERROR;
7248 /* We need to reset back to normal mode after LRAM test passes. */
7249 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7251 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
7252 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
7253 _adv_asc38C0800_chksum);
7254 if (asc_dvc->err_code)
7255 return ADV_ERROR;
7258 * Restore the RISC memory BIOS region.
7260 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7261 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7262 bios_mem[i]);
7266 * Calculate and write the microcode code checksum to the microcode
7267 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7269 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7270 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7271 code_sum = 0;
7272 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7273 for (word = begin_addr; word < end_addr; word += 2) {
7274 code_sum += AdvReadWordAutoIncLram(iop_base);
7276 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7279 * Read microcode version and date.
7281 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7282 asc_dvc->cfg->mcode_date);
7283 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7284 asc_dvc->cfg->mcode_version);
7287 * Set the chip type to indicate the ASC38C0800.
7289 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7292 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7293 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7294 * cable detection and then we are able to read C_DET[3:0].
7296 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7297 * Microcode Default Value' section below.
7299 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7300 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7301 scsi_cfg1 | DIS_TERM_DRV);
7304 * If the PCI Configuration Command Register "Parity Error Response
7305 * Control" Bit was clear (0), then set the microcode variable
7306 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7307 * to ignore DMA parity errors.
7309 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7310 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7311 word |= CONTROL_FLAG_IGNORE_PERR;
7312 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7316 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7317 * bits for the default FIFO threshold.
7319 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7321 * For DMA Errata #4 set the BC_THRESH_ENB bit.
7323 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7324 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7325 READ_CMD_MRM);
7328 * Microcode operating variables for WDTR, SDTR, and command tag
7329 * queuing will be set in slave_configure() based on what a
7330 * device reports it is capable of in Inquiry byte 7.
7332 * If SCSI Bus Resets have been disabled, then directly set
7333 * SDTR and WDTR from the EEPROM configuration. This will allow
7334 * the BIOS and warm boot to work without a SCSI bus hang on
7335 * the Inquiry caused by host and target mismatched DTR values.
7336 * Without the SCSI Bus Reset, before an Inquiry a device can't
7337 * be assumed to be in Asynchronous, Narrow mode.
7339 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7340 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7341 asc_dvc->wdtr_able);
7342 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7343 asc_dvc->sdtr_able);
7347 * Set microcode operating variables for DISC and SDTR_SPEED1,
7348 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7349 * configuration values.
7351 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7352 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7353 * without determining here whether the device supports SDTR.
7355 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7356 asc_dvc->cfg->disc_enable);
7357 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7358 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7359 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7360 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7363 * Set SCSI_CFG0 Microcode Default Value.
7365 * The microcode will set the SCSI_CFG0 register using this value
7366 * after it is started below.
7368 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7369 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7370 asc_dvc->chip_scsi_id);
7373 * Determine SCSI_CFG1 Microcode Default Value.
7375 * The microcode will set the SCSI_CFG1 register using this value
7376 * after it is started below.
7379 /* Read current SCSI_CFG1 Register value. */
7380 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7383 * If the internal narrow cable is reversed all of the SCSI_CTRL
7384 * register signals will be set. Check for and return an error if
7385 * this condition is found.
7387 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7388 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7389 return ADV_ERROR;
7393 * All kind of combinations of devices attached to one of four
7394 * connectors are acceptable except HVD device attached. For example,
7395 * LVD device can be attached to SE connector while SE device attached
7396 * to LVD connector. If LVD device attached to SE connector, it only
7397 * runs up to Ultra speed.
7399 * If an HVD device is attached to one of LVD connectors, return an
7400 * error. However, there is no way to detect HVD device attached to
7401 * SE connectors.
7403 if (scsi_cfg1 & HVD) {
7404 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7405 return ADV_ERROR;
7409 * If either SE or LVD automatic termination control is enabled, then
7410 * set the termination value based on a table listed in a_condor.h.
7412 * If manual termination was specified with an EEPROM setting then
7413 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
7414 * to be 'ored' into SCSI_CFG1.
7416 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7417 /* SE automatic termination control is enabled. */
7418 switch (scsi_cfg1 & C_DET_SE) {
7419 /* TERM_SE_HI: on, TERM_SE_LO: on */
7420 case 0x1:
7421 case 0x2:
7422 case 0x3:
7423 asc_dvc->cfg->termination |= TERM_SE;
7424 break;
7426 /* TERM_SE_HI: on, TERM_SE_LO: off */
7427 case 0x0:
7428 asc_dvc->cfg->termination |= TERM_SE_HI;
7429 break;
7433 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
7434 /* LVD automatic termination control is enabled. */
7435 switch (scsi_cfg1 & C_DET_LVD) {
7436 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
7437 case 0x4:
7438 case 0x8:
7439 case 0xC:
7440 asc_dvc->cfg->termination |= TERM_LVD;
7441 break;
7443 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7444 case 0x0:
7445 break;
7450 * Clear any set TERM_SE and TERM_LVD bits.
7452 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7455 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7457 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7460 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
7461 * bits and set possibly modified termination control bits in the
7462 * Microcode SCSI_CFG1 Register Value.
7464 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7467 * Set SCSI_CFG1 Microcode Default Value
7469 * Set possibly modified termination control and reset DIS_TERM_DRV
7470 * bits in the Microcode SCSI_CFG1 Register Value.
7472 * The microcode will set the SCSI_CFG1 register using this value
7473 * after it is started below.
7475 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7478 * Set MEM_CFG Microcode Default Value
7480 * The microcode will set the MEM_CFG register using this value
7481 * after it is started below.
7483 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7484 * are defined.
7486 * ASC-38C0800 has 16KB internal memory.
7488 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7489 BIOS_EN | RAM_SZ_16KB);
7492 * Set SEL_MASK Microcode Default Value
7494 * The microcode will set the SEL_MASK register using this value
7495 * after it is started below.
7497 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7498 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7500 AdvBuildCarrierFreelist(asc_dvc);
7503 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7506 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7507 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7508 return ADV_ERROR;
7510 asc_dvc->carr_freelist = (ADV_CARR_T *)
7511 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7514 * The first command issued will be placed in the stopper carrier.
7516 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7519 * Set RISC ICQ physical address start value.
7520 * carr_pa is LE, must be native before write
7522 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7525 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7527 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7528 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7529 return ADV_ERROR;
7531 asc_dvc->carr_freelist = (ADV_CARR_T *)
7532 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7535 * The first command completed by the RISC will be placed in
7536 * the stopper.
7538 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7539 * completed the RISC will set the ASC_RQ_STOPPER bit.
7541 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7544 * Set RISC IRQ physical address start value.
7546 * carr_pa is LE, must be native before write *
7548 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7549 asc_dvc->carr_pending_cnt = 0;
7551 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7552 (ADV_INTR_ENABLE_HOST_INTR |
7553 ADV_INTR_ENABLE_GLOBAL_INTR));
7555 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7556 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7558 /* finally, finally, gentlemen, start your engine */
7559 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7562 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7563 * Resets should be performed. The RISC has to be running
7564 * to issue a SCSI Bus Reset.
7566 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7568 * If the BIOS Signature is present in memory, restore the
7569 * BIOS Handshake Configuration Table and do not perform
7570 * a SCSI Bus Reset.
7572 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7573 0x55AA) {
7575 * Restore per TID negotiated values.
7577 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7578 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7579 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7580 tagqng_able);
7581 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7582 AdvWriteByteLram(iop_base,
7583 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7584 max_cmd[tid]);
7586 } else {
7587 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7588 warn_code = ASC_WARN_BUSRESET_ERROR;
7593 return warn_code;
7597 * Initialize the ASC-38C1600.
7599 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7601 * For a non-fatal error return a warning code. If there are no warnings
7602 * then 0 is returned.
7604 * Needed after initialization for error recovery.
7606 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7608 AdvPortAddr iop_base;
7609 ushort warn_code;
7610 int begin_addr;
7611 int end_addr;
7612 ushort code_sum;
7613 long word;
7614 int i;
7615 ushort scsi_cfg1;
7616 uchar byte;
7617 uchar tid;
7618 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7619 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
7620 uchar max_cmd[ASC_MAX_TID + 1];
7622 /* If there is already an error, don't continue. */
7623 if (asc_dvc->err_code != 0) {
7624 return ADV_ERROR;
7628 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7630 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7631 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7632 return ADV_ERROR;
7635 warn_code = 0;
7636 iop_base = asc_dvc->iop_base;
7639 * Save the RISC memory BIOS region before writing the microcode.
7640 * The BIOS may already be loaded and using its RISC LRAM region
7641 * so its region must be saved and restored.
7643 * Note: This code makes the assumption, which is currently true,
7644 * that a chip reset does not clear RISC LRAM.
7646 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7647 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7648 bios_mem[i]);
7652 * Save current per TID negotiated values.
7654 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7655 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7656 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
7657 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7658 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7659 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7660 max_cmd[tid]);
7664 * RAM BIST (Built-In Self Test)
7666 * Address : I/O base + offset 0x38h register (byte).
7667 * Function: Bit 7-6(RW) : RAM mode
7668 * Normal Mode : 0x00
7669 * Pre-test Mode : 0x40
7670 * RAM Test Mode : 0x80
7671 * Bit 5 : unused
7672 * Bit 4(RO) : Done bit
7673 * Bit 3-0(RO) : Status
7674 * Host Error : 0x08
7675 * Int_RAM Error : 0x04
7676 * RISC Error : 0x02
7677 * SCSI Error : 0x01
7678 * No Error : 0x00
7680 * Note: RAM BIST code should be put right here, before loading the
7681 * microcode and after saving the RISC memory BIOS region.
7685 * LRAM Pre-test
7687 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7688 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7689 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7690 * to NORMAL_MODE, return an error too.
7692 for (i = 0; i < 2; i++) {
7693 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7694 mdelay(10); /* Wait for 10ms before reading back. */
7695 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7696 if ((byte & RAM_TEST_DONE) == 0
7697 || (byte & 0x0F) != PRE_TEST_VALUE) {
7698 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7699 return ADV_ERROR;
7702 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7703 mdelay(10); /* Wait for 10ms before reading back. */
7704 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7705 != NORMAL_VALUE) {
7706 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7707 return ADV_ERROR;
7712 * LRAM Test - It takes about 1.5 ms to run through the test.
7714 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7715 * If Done bit not set or Status not 0, save register byte, set the
7716 * err_code, and return an error.
7718 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7719 mdelay(10); /* Wait for 10ms before checking status. */
7721 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7722 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7723 /* Get here if Done bit not set or Status not 0. */
7724 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7725 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7726 return ADV_ERROR;
7729 /* We need to reset back to normal mode after LRAM test passes. */
7730 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7732 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
7733 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
7734 _adv_asc38C1600_chksum);
7735 if (asc_dvc->err_code)
7736 return ADV_ERROR;
7739 * Restore the RISC memory BIOS region.
7741 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7742 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7743 bios_mem[i]);
7747 * Calculate and write the microcode code checksum to the microcode
7748 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7750 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7751 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7752 code_sum = 0;
7753 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7754 for (word = begin_addr; word < end_addr; word += 2) {
7755 code_sum += AdvReadWordAutoIncLram(iop_base);
7757 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7760 * Read microcode version and date.
7762 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7763 asc_dvc->cfg->mcode_date);
7764 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7765 asc_dvc->cfg->mcode_version);
7768 * Set the chip type to indicate the ASC38C1600.
7770 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7773 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7774 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7775 * cable detection and then we are able to read C_DET[3:0].
7777 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7778 * Microcode Default Value' section below.
7780 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7781 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7782 scsi_cfg1 | DIS_TERM_DRV);
7785 * If the PCI Configuration Command Register "Parity Error Response
7786 * Control" Bit was clear (0), then set the microcode variable
7787 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7788 * to ignore DMA parity errors.
7790 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7791 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7792 word |= CONTROL_FLAG_IGNORE_PERR;
7793 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7797 * If the BIOS control flag AIPP (Asynchronous Information
7798 * Phase Protection) disable bit is not set, then set the firmware
7799 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
7800 * AIPP checking and encoding.
7802 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
7803 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7804 word |= CONTROL_FLAG_ENABLE_AIPP;
7805 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7809 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7810 * and START_CTL_TH [3:2].
7812 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7813 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7816 * Microcode operating variables for WDTR, SDTR, and command tag
7817 * queuing will be set in slave_configure() based on what a
7818 * device reports it is capable of in Inquiry byte 7.
7820 * If SCSI Bus Resets have been disabled, then directly set
7821 * SDTR and WDTR from the EEPROM configuration. This will allow
7822 * the BIOS and warm boot to work without a SCSI bus hang on
7823 * the Inquiry caused by host and target mismatched DTR values.
7824 * Without the SCSI Bus Reset, before an Inquiry a device can't
7825 * be assumed to be in Asynchronous, Narrow mode.
7827 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7828 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7829 asc_dvc->wdtr_able);
7830 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7831 asc_dvc->sdtr_able);
7835 * Set microcode operating variables for DISC and SDTR_SPEED1,
7836 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7837 * configuration values.
7839 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7840 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7841 * without determining here whether the device supports SDTR.
7843 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7844 asc_dvc->cfg->disc_enable);
7845 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7846 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7847 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7848 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7851 * Set SCSI_CFG0 Microcode Default Value.
7853 * The microcode will set the SCSI_CFG0 register using this value
7854 * after it is started below.
7856 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7857 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7858 asc_dvc->chip_scsi_id);
7861 * Calculate SCSI_CFG1 Microcode Default Value.
7863 * The microcode will set the SCSI_CFG1 register using this value
7864 * after it is started below.
7866 * Each ASC-38C1600 function has only two cable detect bits.
7867 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
7869 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7872 * If the cable is reversed all of the SCSI_CTRL register signals
7873 * will be set. Check for and return an error if this condition is
7874 * found.
7876 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7877 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7878 return ADV_ERROR;
7882 * Each ASC-38C1600 function has two connectors. Only an HVD device
7883 * can not be connected to either connector. An LVD device or SE device
7884 * may be connected to either connecor. If an SE device is connected,
7885 * then at most Ultra speed (20 Mhz) can be used on both connectors.
7887 * If an HVD device is attached, return an error.
7889 if (scsi_cfg1 & HVD) {
7890 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
7891 return ADV_ERROR;
7895 * Each function in the ASC-38C1600 uses only the SE cable detect and
7896 * termination because there are two connectors for each function. Each
7897 * function may use either LVD or SE mode. Corresponding the SE automatic
7898 * termination control EEPROM bits are used for each function. Each
7899 * function has its own EEPROM. If SE automatic control is enabled for
7900 * the function, then set the termination value based on a table listed
7901 * in a_condor.h.
7903 * If manual termination is specified in the EEPROM for the function,
7904 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
7905 * ready to be 'ored' into SCSI_CFG1.
7907 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7908 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
7909 /* SE automatic termination control is enabled. */
7910 switch (scsi_cfg1 & C_DET_SE) {
7911 /* TERM_SE_HI: on, TERM_SE_LO: on */
7912 case 0x1:
7913 case 0x2:
7914 case 0x3:
7915 asc_dvc->cfg->termination |= TERM_SE;
7916 break;
7918 case 0x0:
7919 if (PCI_FUNC(pdev->devfn) == 0) {
7920 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
7921 } else {
7922 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
7923 asc_dvc->cfg->termination |= TERM_SE_HI;
7925 break;
7930 * Clear any set TERM_SE bits.
7932 scsi_cfg1 &= ~TERM_SE;
7935 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
7937 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
7940 * Clear Big Endian and Terminator Polarity bits and set possibly
7941 * modified termination control bits in the Microcode SCSI_CFG1
7942 * Register Value.
7944 * Big Endian bit is not used even on big endian machines.
7946 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
7949 * Set SCSI_CFG1 Microcode Default Value
7951 * Set possibly modified termination control bits in the Microcode
7952 * SCSI_CFG1 Register Value.
7954 * The microcode will set the SCSI_CFG1 register using this value
7955 * after it is started below.
7957 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7960 * Set MEM_CFG Microcode Default Value
7962 * The microcode will set the MEM_CFG register using this value
7963 * after it is started below.
7965 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7966 * are defined.
7968 * ASC-38C1600 has 32KB internal memory.
7970 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
7971 * out a special 16K Adv Library and Microcode version. After the issue
7972 * resolved, we should turn back to the 32K support. Both a_condor.h and
7973 * mcode.sas files also need to be updated.
7975 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7976 * BIOS_EN | RAM_SZ_32KB);
7978 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7979 BIOS_EN | RAM_SZ_16KB);
7982 * Set SEL_MASK Microcode Default Value
7984 * The microcode will set the SEL_MASK register using this value
7985 * after it is started below.
7987 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7988 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7990 AdvBuildCarrierFreelist(asc_dvc);
7993 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7995 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7996 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7997 return ADV_ERROR;
7999 asc_dvc->carr_freelist = (ADV_CARR_T *)
8000 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
8003 * The first command issued will be placed in the stopper carrier.
8005 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8008 * Set RISC ICQ physical address start value. Initialize the
8009 * COMMA register to the same value otherwise the RISC will
8010 * prematurely detect a command is available.
8012 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
8013 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8014 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
8017 * Set-up the RISC->Host Initiator Response Queue (IRQ).
8019 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
8020 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8021 return ADV_ERROR;
8023 asc_dvc->carr_freelist = (ADV_CARR_T *)
8024 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
8027 * The first command completed by the RISC will be placed in
8028 * the stopper.
8030 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
8031 * completed the RISC will set the ASC_RQ_STOPPER bit.
8033 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8036 * Set RISC IRQ physical address start value.
8038 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
8039 asc_dvc->carr_pending_cnt = 0;
8041 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
8042 (ADV_INTR_ENABLE_HOST_INTR |
8043 ADV_INTR_ENABLE_GLOBAL_INTR));
8044 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
8045 AdvWriteWordRegister(iop_base, IOPW_PC, word);
8047 /* finally, finally, gentlemen, start your engine */
8048 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
8051 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
8052 * Resets should be performed. The RISC has to be running
8053 * to issue a SCSI Bus Reset.
8055 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
8057 * If the BIOS Signature is present in memory, restore the
8058 * per TID microcode operating variables.
8060 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8061 0x55AA) {
8063 * Restore per TID negotiated values.
8065 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8066 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8067 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8068 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
8069 tagqng_able);
8070 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
8071 AdvWriteByteLram(iop_base,
8072 ASC_MC_NUMBER_OF_MAX_CMD + tid,
8073 max_cmd[tid]);
8075 } else {
8076 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8077 warn_code = ASC_WARN_BUSRESET_ERROR;
8082 return warn_code;
8086 * Reset chip and SCSI Bus.
8088 * Return Value:
8089 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
8090 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
8092 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8094 int status;
8095 ushort wdtr_able, sdtr_able, tagqng_able;
8096 ushort ppr_able = 0;
8097 uchar tid, max_cmd[ADV_MAX_TID + 1];
8098 AdvPortAddr iop_base;
8099 ushort bios_sig;
8101 iop_base = asc_dvc->iop_base;
8104 * Save current per TID negotiated values.
8106 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8107 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8108 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8109 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8111 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8112 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8113 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8114 max_cmd[tid]);
8118 * Force the AdvInitAsc3550/38C0800Driver() function to
8119 * perform a SCSI Bus Reset by clearing the BIOS signature word.
8120 * The initialization functions assumes a SCSI Bus Reset is not
8121 * needed if the BIOS signature word is present.
8123 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8124 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8127 * Stop chip and reset it.
8129 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
8130 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
8131 mdelay(100);
8132 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
8133 ADV_CTRL_REG_CMD_WR_IO_REG);
8136 * Reset Adv Library error code, if any, and try
8137 * re-initializing the chip.
8139 asc_dvc->err_code = 0;
8140 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8141 status = AdvInitAsc38C1600Driver(asc_dvc);
8142 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8143 status = AdvInitAsc38C0800Driver(asc_dvc);
8144 } else {
8145 status = AdvInitAsc3550Driver(asc_dvc);
8148 /* Translate initialization return value to status value. */
8149 if (status == 0) {
8150 status = ADV_TRUE;
8151 } else {
8152 status = ADV_FALSE;
8156 * Restore the BIOS signature word.
8158 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8161 * Restore per TID negotiated values.
8163 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8164 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8165 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8166 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8168 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8169 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8170 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8171 max_cmd[tid]);
8174 return status;
8178 * adv_async_callback() - Adv Library asynchronous event callback function.
8180 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8182 switch (code) {
8183 case ADV_ASYNC_SCSI_BUS_RESET_DET:
8185 * The firmware detected a SCSI Bus reset.
8187 ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n");
8188 break;
8190 case ADV_ASYNC_RDMA_FAILURE:
8192 * Handle RDMA failure by resetting the SCSI Bus and
8193 * possibly the chip if it is unresponsive. Log the error
8194 * with a unique code.
8196 ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n");
8197 AdvResetChipAndSB(adv_dvc_varp);
8198 break;
8200 case ADV_HOST_SCSI_BUS_RESET:
8202 * Host generated SCSI bus reset occurred.
8204 ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n");
8205 break;
8207 default:
8208 ASC_DBG(0, "unknown code 0x%x\n", code);
8209 break;
8214 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8216 * Callback function for the Wide SCSI Adv Library.
8218 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8220 struct asc_board *boardp;
8221 adv_req_t *reqp;
8222 adv_sgblk_t *sgblkp;
8223 struct scsi_cmnd *scp;
8224 struct Scsi_Host *shost;
8225 ADV_DCNT resid_cnt;
8227 ASC_DBG(1, "adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
8228 (ulong)adv_dvc_varp, (ulong)scsiqp);
8229 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8232 * Get the adv_req_t structure for the command that has been
8233 * completed. The adv_req_t structure actually contains the
8234 * completed ADV_SCSI_REQ_Q structure.
8236 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
8237 ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
8238 if (reqp == NULL) {
8239 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8240 return;
8244 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8245 * command that has been completed.
8247 * Note: The adv_req_t request structure and adv_sgblk_t structure,
8248 * if any, are dropped, because a board structure pointer can not be
8249 * determined.
8251 scp = reqp->cmndp;
8252 ASC_DBG(1, "scp 0x%p\n", scp);
8253 if (scp == NULL) {
8254 ASC_PRINT
8255 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8256 return;
8258 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8260 shost = scp->device->host;
8261 ASC_STATS(shost, callback);
8262 ASC_DBG(1, "shost 0x%p\n", shost);
8264 boardp = shost_priv(shost);
8265 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8268 * 'done_status' contains the command's ending status.
8270 switch (scsiqp->done_status) {
8271 case QD_NO_ERROR:
8272 ASC_DBG(2, "QD_NO_ERROR\n");
8273 scp->result = 0;
8276 * Check for an underrun condition.
8278 * If there was no error and an underrun condition, then
8279 * then return the number of underrun bytes.
8281 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8282 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
8283 resid_cnt <= scp->request_bufflen) {
8284 ASC_DBG(1, "underrun condition %lu bytes\n",
8285 (ulong)resid_cnt);
8286 scp->resid = resid_cnt;
8288 break;
8290 case QD_WITH_ERROR:
8291 ASC_DBG(2, "QD_WITH_ERROR\n");
8292 switch (scsiqp->host_status) {
8293 case QHSTA_NO_ERROR:
8294 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
8295 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
8296 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8297 sizeof(scp->sense_buffer));
8299 * Note: The 'status_byte()' macro used by
8300 * target drivers defined in scsi.h shifts the
8301 * status byte returned by host drivers right
8302 * by 1 bit. This is why target drivers also
8303 * use right shifted status byte definitions.
8304 * For instance target drivers use
8305 * CHECK_CONDITION, defined to 0x1, instead of
8306 * the SCSI defined check condition value of
8307 * 0x2. Host drivers are supposed to return
8308 * the status byte as it is defined by SCSI.
8310 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8311 STATUS_BYTE(scsiqp->scsi_status);
8312 } else {
8313 scp->result = STATUS_BYTE(scsiqp->scsi_status);
8315 break;
8317 default:
8318 /* Some other QHSTA error occurred. */
8319 ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
8320 scp->result = HOST_BYTE(DID_BAD_TARGET);
8321 break;
8323 break;
8325 case QD_ABORTED_BY_HOST:
8326 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
8327 scp->result =
8328 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8329 break;
8331 default:
8332 ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
8333 scp->result =
8334 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8335 break;
8339 * If the 'init_tidmask' bit isn't already set for the target and the
8340 * current request finished normally, then set the bit for the target
8341 * to indicate that a device is present.
8343 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
8344 scsiqp->done_status == QD_NO_ERROR &&
8345 scsiqp->host_status == QHSTA_NO_ERROR) {
8346 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
8349 asc_scsi_done(scp);
8352 * Free all 'adv_sgblk_t' structures allocated for the request.
8354 while ((sgblkp = reqp->sgblkp) != NULL) {
8355 /* Remove 'sgblkp' from the request list. */
8356 reqp->sgblkp = sgblkp->next_sgblkp;
8358 /* Add 'sgblkp' to the board free list. */
8359 sgblkp->next_sgblkp = boardp->adv_sgblkp;
8360 boardp->adv_sgblkp = sgblkp;
8364 * Free the adv_req_t structure used with the command by adding
8365 * it back to the board free list.
8367 reqp->next_reqp = boardp->adv_reqp;
8368 boardp->adv_reqp = reqp;
8370 ASC_DBG(1, "done\n");
8374 * Adv Library Interrupt Service Routine
8376 * This function is called by a driver's interrupt service routine.
8377 * The function disables and re-enables interrupts.
8379 * When a microcode idle command is completed, the ADV_DVC_VAR
8380 * 'idle_cmd_done' field is set to ADV_TRUE.
8382 * Note: AdvISR() can be called when interrupts are disabled or even
8383 * when there is no hardware interrupt condition present. It will
8384 * always check for completed idle commands and microcode requests.
8385 * This is an important feature that shouldn't be changed because it
8386 * allows commands to be completed from polling mode loops.
8388 * Return:
8389 * ADV_TRUE(1) - interrupt was pending
8390 * ADV_FALSE(0) - no interrupt was pending
8392 static int AdvISR(ADV_DVC_VAR *asc_dvc)
8394 AdvPortAddr iop_base;
8395 uchar int_stat;
8396 ushort target_bit;
8397 ADV_CARR_T *free_carrp;
8398 ADV_VADDR irq_next_vpa;
8399 ADV_SCSI_REQ_Q *scsiq;
8401 iop_base = asc_dvc->iop_base;
8403 /* Reading the register clears the interrupt. */
8404 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8406 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8407 ADV_INTR_STATUS_INTRC)) == 0) {
8408 return ADV_FALSE;
8412 * Notify the driver of an asynchronous microcode condition by
8413 * calling the adv_async_callback function. The function
8414 * is passed the microcode ASC_MC_INTRB_CODE byte value.
8416 if (int_stat & ADV_INTR_STATUS_INTRB) {
8417 uchar intrb_code;
8419 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8421 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8422 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8423 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
8424 asc_dvc->carr_pending_cnt != 0) {
8425 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8426 ADV_TICKLE_A);
8427 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8428 AdvWriteByteRegister(iop_base,
8429 IOPB_TICKLE,
8430 ADV_TICKLE_NOP);
8435 adv_async_callback(asc_dvc, intrb_code);
8439 * Check if the IRQ stopper carrier contains a completed request.
8441 while (((irq_next_vpa =
8442 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8444 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
8445 * The RISC will have set 'areq_vpa' to a virtual address.
8447 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
8448 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
8449 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
8450 * in AdvExeScsiQueue().
8452 scsiq = (ADV_SCSI_REQ_Q *)
8453 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8456 * Request finished with good status and the queue was not
8457 * DMAed to host memory by the firmware. Set all status fields
8458 * to indicate good status.
8460 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
8461 scsiq->done_status = QD_NO_ERROR;
8462 scsiq->host_status = scsiq->scsi_status = 0;
8463 scsiq->data_cnt = 0L;
8467 * Advance the stopper pointer to the next carrier
8468 * ignoring the lower four bits. Free the previous
8469 * stopper carrier.
8471 free_carrp = asc_dvc->irq_sp;
8472 asc_dvc->irq_sp = (ADV_CARR_T *)
8473 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
8475 free_carrp->next_vpa =
8476 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
8477 asc_dvc->carr_freelist = free_carrp;
8478 asc_dvc->carr_pending_cnt--;
8480 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8483 * Clear request microcode control flag.
8485 scsiq->cntl = 0;
8488 * Notify the driver of the completed request by passing
8489 * the ADV_SCSI_REQ_Q pointer to its callback function.
8491 scsiq->a_flag |= ADV_SCSIQ_DONE;
8492 adv_isr_callback(asc_dvc, scsiq);
8494 * Note: After the driver callback function is called, 'scsiq'
8495 * can no longer be referenced.
8497 * Fall through and continue processing other completed
8498 * requests...
8501 return ADV_TRUE;
8504 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8506 if (asc_dvc->err_code == 0) {
8507 asc_dvc->err_code = err_code;
8508 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8509 err_code);
8511 return err_code;
8514 static void AscAckInterrupt(PortAddr iop_base)
8516 uchar host_flag;
8517 uchar risc_flag;
8518 ushort loop;
8520 loop = 0;
8521 do {
8522 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8523 if (loop++ > 0x7FFF) {
8524 break;
8526 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8527 host_flag =
8528 AscReadLramByte(iop_base,
8529 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8530 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8531 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8532 AscSetChipStatus(iop_base, CIW_INT_ACK);
8533 loop = 0;
8534 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8535 AscSetChipStatus(iop_base, CIW_INT_ACK);
8536 if (loop++ > 3) {
8537 break;
8540 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8543 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8545 const uchar *period_table;
8546 int max_index;
8547 int min_index;
8548 int i;
8550 period_table = asc_dvc->sdtr_period_tbl;
8551 max_index = (int)asc_dvc->max_sdtr_index;
8552 min_index = (int)asc_dvc->min_sdtr_index;
8553 if ((syn_time <= period_table[max_index])) {
8554 for (i = min_index; i < (max_index - 1); i++) {
8555 if (syn_time <= period_table[i]) {
8556 return (uchar)i;
8559 return (uchar)max_index;
8560 } else {
8561 return (uchar)(max_index + 1);
8565 static uchar
8566 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8568 EXT_MSG sdtr_buf;
8569 uchar sdtr_period_index;
8570 PortAddr iop_base;
8572 iop_base = asc_dvc->iop_base;
8573 sdtr_buf.msg_type = EXTENDED_MESSAGE;
8574 sdtr_buf.msg_len = MS_SDTR_LEN;
8575 sdtr_buf.msg_req = EXTENDED_SDTR;
8576 sdtr_buf.xfer_period = sdtr_period;
8577 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8578 sdtr_buf.req_ack_offset = sdtr_offset;
8579 sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8580 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
8581 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8582 (uchar *)&sdtr_buf,
8583 sizeof(EXT_MSG) >> 1);
8584 return ((sdtr_period_index << 4) | sdtr_offset);
8585 } else {
8586 sdtr_buf.req_ack_offset = 0;
8587 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8588 (uchar *)&sdtr_buf,
8589 sizeof(EXT_MSG) >> 1);
8590 return 0;
8594 static uchar
8595 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8597 uchar byte;
8598 uchar sdtr_period_ix;
8600 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8601 if (sdtr_period_ix > asc_dvc->max_sdtr_index)
8602 return 0xFF;
8603 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8604 return byte;
8607 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8609 ASC_SCSI_BIT_ID_TYPE org_id;
8610 int i;
8611 int sta = TRUE;
8613 AscSetBank(iop_base, 1);
8614 org_id = AscReadChipDvcID(iop_base);
8615 for (i = 0; i <= ASC_MAX_TID; i++) {
8616 if (org_id == (0x01 << i))
8617 break;
8619 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8620 AscWriteChipDvcID(iop_base, id);
8621 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8622 AscSetBank(iop_base, 0);
8623 AscSetChipSyn(iop_base, sdtr_data);
8624 if (AscGetChipSyn(iop_base) != sdtr_data) {
8625 sta = FALSE;
8627 } else {
8628 sta = FALSE;
8630 AscSetBank(iop_base, 1);
8631 AscWriteChipDvcID(iop_base, org_id);
8632 AscSetBank(iop_base, 0);
8633 return (sta);
8636 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8638 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8639 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8642 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8644 EXT_MSG ext_msg;
8645 EXT_MSG out_msg;
8646 ushort halt_q_addr;
8647 int sdtr_accept;
8648 ushort int_halt_code;
8649 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8650 ASC_SCSI_BIT_ID_TYPE target_id;
8651 PortAddr iop_base;
8652 uchar tag_code;
8653 uchar q_status;
8654 uchar halt_qp;
8655 uchar sdtr_data;
8656 uchar target_ix;
8657 uchar q_cntl, tid_no;
8658 uchar cur_dvc_qng;
8659 uchar asyn_sdtr;
8660 uchar scsi_status;
8661 struct asc_board *boardp;
8663 BUG_ON(!asc_dvc->drv_ptr);
8664 boardp = asc_dvc->drv_ptr;
8666 iop_base = asc_dvc->iop_base;
8667 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8669 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8670 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8671 target_ix = AscReadLramByte(iop_base,
8672 (ushort)(halt_q_addr +
8673 (ushort)ASC_SCSIQ_B_TARGET_IX));
8674 q_cntl = AscReadLramByte(iop_base,
8675 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8676 tid_no = ASC_TIX_TO_TID(target_ix);
8677 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8678 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8679 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8680 } else {
8681 asyn_sdtr = 0;
8683 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8684 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8685 AscSetChipSDTR(iop_base, 0, tid_no);
8686 boardp->sdtr_data[tid_no] = 0;
8688 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8689 return (0);
8690 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8691 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8692 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8693 boardp->sdtr_data[tid_no] = asyn_sdtr;
8695 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8696 return (0);
8697 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8698 AscMemWordCopyPtrFromLram(iop_base,
8699 ASCV_MSGIN_BEG,
8700 (uchar *)&ext_msg,
8701 sizeof(EXT_MSG) >> 1);
8703 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8704 ext_msg.msg_req == EXTENDED_SDTR &&
8705 ext_msg.msg_len == MS_SDTR_LEN) {
8706 sdtr_accept = TRUE;
8707 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8709 sdtr_accept = FALSE;
8710 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8712 if ((ext_msg.xfer_period <
8713 asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index])
8714 || (ext_msg.xfer_period >
8715 asc_dvc->sdtr_period_tbl[asc_dvc->
8716 max_sdtr_index])) {
8717 sdtr_accept = FALSE;
8718 ext_msg.xfer_period =
8719 asc_dvc->sdtr_period_tbl[asc_dvc->
8720 min_sdtr_index];
8722 if (sdtr_accept) {
8723 sdtr_data =
8724 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8725 ext_msg.req_ack_offset);
8726 if ((sdtr_data == 0xFF)) {
8728 q_cntl |= QC_MSG_OUT;
8729 asc_dvc->init_sdtr &= ~target_id;
8730 asc_dvc->sdtr_done &= ~target_id;
8731 AscSetChipSDTR(iop_base, asyn_sdtr,
8732 tid_no);
8733 boardp->sdtr_data[tid_no] = asyn_sdtr;
8736 if (ext_msg.req_ack_offset == 0) {
8738 q_cntl &= ~QC_MSG_OUT;
8739 asc_dvc->init_sdtr &= ~target_id;
8740 asc_dvc->sdtr_done &= ~target_id;
8741 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8742 } else {
8743 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8744 q_cntl &= ~QC_MSG_OUT;
8745 asc_dvc->sdtr_done |= target_id;
8746 asc_dvc->init_sdtr |= target_id;
8747 asc_dvc->pci_fix_asyn_xfer &=
8748 ~target_id;
8749 sdtr_data =
8750 AscCalSDTRData(asc_dvc,
8751 ext_msg.xfer_period,
8752 ext_msg.
8753 req_ack_offset);
8754 AscSetChipSDTR(iop_base, sdtr_data,
8755 tid_no);
8756 boardp->sdtr_data[tid_no] = sdtr_data;
8757 } else {
8758 q_cntl |= QC_MSG_OUT;
8759 AscMsgOutSDTR(asc_dvc,
8760 ext_msg.xfer_period,
8761 ext_msg.req_ack_offset);
8762 asc_dvc->pci_fix_asyn_xfer &=
8763 ~target_id;
8764 sdtr_data =
8765 AscCalSDTRData(asc_dvc,
8766 ext_msg.xfer_period,
8767 ext_msg.
8768 req_ack_offset);
8769 AscSetChipSDTR(iop_base, sdtr_data,
8770 tid_no);
8771 boardp->sdtr_data[tid_no] = sdtr_data;
8772 asc_dvc->sdtr_done |= target_id;
8773 asc_dvc->init_sdtr |= target_id;
8777 AscWriteLramByte(iop_base,
8778 (ushort)(halt_q_addr +
8779 (ushort)ASC_SCSIQ_B_CNTL),
8780 q_cntl);
8781 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8782 return (0);
8783 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8784 ext_msg.msg_req == EXTENDED_WDTR &&
8785 ext_msg.msg_len == MS_WDTR_LEN) {
8787 ext_msg.wdtr_width = 0;
8788 AscMemWordCopyPtrToLram(iop_base,
8789 ASCV_MSGOUT_BEG,
8790 (uchar *)&ext_msg,
8791 sizeof(EXT_MSG) >> 1);
8792 q_cntl |= QC_MSG_OUT;
8793 AscWriteLramByte(iop_base,
8794 (ushort)(halt_q_addr +
8795 (ushort)ASC_SCSIQ_B_CNTL),
8796 q_cntl);
8797 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8798 return (0);
8799 } else {
8801 ext_msg.msg_type = MESSAGE_REJECT;
8802 AscMemWordCopyPtrToLram(iop_base,
8803 ASCV_MSGOUT_BEG,
8804 (uchar *)&ext_msg,
8805 sizeof(EXT_MSG) >> 1);
8806 q_cntl |= QC_MSG_OUT;
8807 AscWriteLramByte(iop_base,
8808 (ushort)(halt_q_addr +
8809 (ushort)ASC_SCSIQ_B_CNTL),
8810 q_cntl);
8811 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8812 return (0);
8814 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8816 q_cntl |= QC_REQ_SENSE;
8818 if ((asc_dvc->init_sdtr & target_id) != 0) {
8820 asc_dvc->sdtr_done &= ~target_id;
8822 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8823 q_cntl |= QC_MSG_OUT;
8824 AscMsgOutSDTR(asc_dvc,
8825 asc_dvc->
8826 sdtr_period_tbl[(sdtr_data >> 4) &
8827 (uchar)(asc_dvc->
8828 max_sdtr_index -
8829 1)],
8830 (uchar)(sdtr_data & (uchar)
8831 ASC_SYN_MAX_OFFSET));
8834 AscWriteLramByte(iop_base,
8835 (ushort)(halt_q_addr +
8836 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8838 tag_code = AscReadLramByte(iop_base,
8839 (ushort)(halt_q_addr + (ushort)
8840 ASC_SCSIQ_B_TAG_CODE));
8841 tag_code &= 0xDC;
8842 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8843 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8846 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8847 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8850 AscWriteLramByte(iop_base,
8851 (ushort)(halt_q_addr +
8852 (ushort)ASC_SCSIQ_B_TAG_CODE),
8853 tag_code);
8855 q_status = AscReadLramByte(iop_base,
8856 (ushort)(halt_q_addr + (ushort)
8857 ASC_SCSIQ_B_STATUS));
8858 q_status |= (QS_READY | QS_BUSY);
8859 AscWriteLramByte(iop_base,
8860 (ushort)(halt_q_addr +
8861 (ushort)ASC_SCSIQ_B_STATUS),
8862 q_status);
8864 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8865 scsi_busy &= ~target_id;
8866 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8868 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8869 return (0);
8870 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8872 AscMemWordCopyPtrFromLram(iop_base,
8873 ASCV_MSGOUT_BEG,
8874 (uchar *)&out_msg,
8875 sizeof(EXT_MSG) >> 1);
8877 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8878 (out_msg.msg_len == MS_SDTR_LEN) &&
8879 (out_msg.msg_req == EXTENDED_SDTR)) {
8881 asc_dvc->init_sdtr &= ~target_id;
8882 asc_dvc->sdtr_done &= ~target_id;
8883 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8884 boardp->sdtr_data[tid_no] = asyn_sdtr;
8886 q_cntl &= ~QC_MSG_OUT;
8887 AscWriteLramByte(iop_base,
8888 (ushort)(halt_q_addr +
8889 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8890 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8891 return (0);
8892 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8894 scsi_status = AscReadLramByte(iop_base,
8895 (ushort)((ushort)halt_q_addr +
8896 (ushort)
8897 ASC_SCSIQ_SCSI_STATUS));
8898 cur_dvc_qng =
8899 AscReadLramByte(iop_base,
8900 (ushort)((ushort)ASC_QADR_BEG +
8901 (ushort)target_ix));
8902 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8904 scsi_busy = AscReadLramByte(iop_base,
8905 (ushort)ASCV_SCSIBUSY_B);
8906 scsi_busy |= target_id;
8907 AscWriteLramByte(iop_base,
8908 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8909 asc_dvc->queue_full_or_busy |= target_id;
8911 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8912 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8913 cur_dvc_qng -= 1;
8914 asc_dvc->max_dvc_qng[tid_no] =
8915 cur_dvc_qng;
8917 AscWriteLramByte(iop_base,
8918 (ushort)((ushort)
8919 ASCV_MAX_DVC_QNG_BEG
8920 + (ushort)
8921 tid_no),
8922 cur_dvc_qng);
8925 * Set the device queue depth to the
8926 * number of active requests when the
8927 * QUEUE FULL condition was encountered.
8929 boardp->queue_full |= target_id;
8930 boardp->queue_full_cnt[tid_no] =
8931 cur_dvc_qng;
8935 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8936 return (0);
8938 #if CC_VERY_LONG_SG_LIST
8939 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8940 uchar q_no;
8941 ushort q_addr;
8942 uchar sg_wk_q_no;
8943 uchar first_sg_wk_q_no;
8944 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8945 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8946 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8947 ushort sg_list_dwords;
8948 ushort sg_entry_cnt;
8949 uchar next_qp;
8950 int i;
8952 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8953 if (q_no == ASC_QLINK_END)
8954 return 0;
8956 q_addr = ASC_QNO_TO_QADDR(q_no);
8959 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8960 * structure pointer using a macro provided by the driver.
8961 * The ASC_SCSI_REQ pointer provides a pointer to the
8962 * host ASC_SG_HEAD structure.
8964 /* Read request's SRB pointer. */
8965 scsiq = (ASC_SCSI_Q *)
8966 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8967 (ushort)
8968 (q_addr +
8969 ASC_SCSIQ_D_SRBPTR))));
8972 * Get request's first and working SG queue.
8974 sg_wk_q_no = AscReadLramByte(iop_base,
8975 (ushort)(q_addr +
8976 ASC_SCSIQ_B_SG_WK_QP));
8978 first_sg_wk_q_no = AscReadLramByte(iop_base,
8979 (ushort)(q_addr +
8980 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8983 * Reset request's working SG queue back to the
8984 * first SG queue.
8986 AscWriteLramByte(iop_base,
8987 (ushort)(q_addr +
8988 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8989 first_sg_wk_q_no);
8991 sg_head = scsiq->sg_head;
8994 * Set sg_entry_cnt to the number of SG elements
8995 * that will be completed on this interrupt.
8997 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8998 * SG elements. The data_cnt and data_addr fields which
8999 * add 1 to the SG element capacity are not used when
9000 * restarting SG handling after a halt.
9002 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
9003 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9006 * Keep track of remaining number of SG elements that
9007 * will need to be handled on the next interrupt.
9009 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
9010 } else {
9011 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
9012 scsiq->remain_sg_entry_cnt = 0;
9016 * Copy SG elements into the list of allocated SG queues.
9018 * Last index completed is saved in scsiq->next_sg_index.
9020 next_qp = first_sg_wk_q_no;
9021 q_addr = ASC_QNO_TO_QADDR(next_qp);
9022 scsi_sg_q.sg_head_qp = q_no;
9023 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9024 for (i = 0; i < sg_head->queue_cnt; i++) {
9025 scsi_sg_q.seq_no = i + 1;
9026 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9027 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9028 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9030 * After very first SG queue RISC FW uses next
9031 * SG queue first element then checks sg_list_cnt
9032 * against zero and then decrements, so set
9033 * sg_list_cnt 1 less than number of SG elements
9034 * in each SG queue.
9036 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
9037 scsi_sg_q.sg_cur_list_cnt =
9038 ASC_SG_LIST_PER_Q - 1;
9039 } else {
9041 * This is the last SG queue in the list of
9042 * allocated SG queues. If there are more
9043 * SG elements than will fit in the allocated
9044 * queues, then set the QCSG_SG_XFER_MORE flag.
9046 if (scsiq->remain_sg_entry_cnt != 0) {
9047 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9048 } else {
9049 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9051 /* equals sg_entry_cnt * 2 */
9052 sg_list_dwords = sg_entry_cnt << 1;
9053 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
9054 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
9055 sg_entry_cnt = 0;
9058 scsi_sg_q.q_no = next_qp;
9059 AscMemWordCopyPtrToLram(iop_base,
9060 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9061 (uchar *)&scsi_sg_q,
9062 sizeof(ASC_SG_LIST_Q) >> 1);
9064 AscMemDWordCopyPtrToLram(iop_base,
9065 q_addr + ASC_SGQ_LIST_BEG,
9066 (uchar *)&sg_head->
9067 sg_list[scsiq->next_sg_index],
9068 sg_list_dwords);
9070 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9073 * If the just completed SG queue contained the
9074 * last SG element, then no more SG queues need
9075 * to be written.
9077 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9078 break;
9081 next_qp = AscReadLramByte(iop_base,
9082 (ushort)(q_addr +
9083 ASC_SCSIQ_B_FWD));
9084 q_addr = ASC_QNO_TO_QADDR(next_qp);
9088 * Clear the halt condition so the RISC will be restarted
9089 * after the return.
9091 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9092 return (0);
9094 #endif /* CC_VERY_LONG_SG_LIST */
9095 return (0);
9099 * void
9100 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9102 * Calling/Exit State:
9103 * none
9105 * Description:
9106 * Input an ASC_QDONE_INFO structure from the chip
9108 static void
9109 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9111 int i;
9112 ushort word;
9114 AscSetChipLramAddr(iop_base, s_addr);
9115 for (i = 0; i < 2 * words; i += 2) {
9116 if (i == 10) {
9117 continue;
9119 word = inpw(iop_base + IOP_RAM_DATA);
9120 inbuf[i] = word & 0xff;
9121 inbuf[i + 1] = (word >> 8) & 0xff;
9123 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9126 static uchar
9127 _AscCopyLramScsiDoneQ(PortAddr iop_base,
9128 ushort q_addr,
9129 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9131 ushort _val;
9132 uchar sg_queue_cnt;
9134 DvcGetQinfo(iop_base,
9135 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
9136 (uchar *)scsiq,
9137 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
9139 _val = AscReadLramWord(iop_base,
9140 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
9141 scsiq->q_status = (uchar)_val;
9142 scsiq->q_no = (uchar)(_val >> 8);
9143 _val = AscReadLramWord(iop_base,
9144 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
9145 scsiq->cntl = (uchar)_val;
9146 sg_queue_cnt = (uchar)(_val >> 8);
9147 _val = AscReadLramWord(iop_base,
9148 (ushort)(q_addr +
9149 (ushort)ASC_SCSIQ_B_SENSE_LEN));
9150 scsiq->sense_len = (uchar)_val;
9151 scsiq->extra_bytes = (uchar)(_val >> 8);
9154 * Read high word of remain bytes from alternate location.
9156 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9157 (ushort)(q_addr +
9158 (ushort)
9159 ASC_SCSIQ_W_ALT_DC1)))
9160 << 16);
9162 * Read low word of remain bytes from original location.
9164 scsiq->remain_bytes += AscReadLramWord(iop_base,
9165 (ushort)(q_addr + (ushort)
9166 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9168 scsiq->remain_bytes &= max_dma_count;
9169 return sg_queue_cnt;
9173 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9175 * Interrupt callback function for the Narrow SCSI Asc Library.
9177 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9179 struct asc_board *boardp;
9180 struct scsi_cmnd *scp;
9181 struct Scsi_Host *shost;
9183 ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
9184 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9187 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
9188 * command that has been completed.
9190 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
9191 ASC_DBG(1, "scp 0x%p\n", scp);
9193 if (scp == NULL) {
9194 ASC_PRINT("asc_isr_callback: scp is NULL\n");
9195 return;
9197 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9199 shost = scp->device->host;
9200 ASC_STATS(shost, callback);
9201 ASC_DBG(1, "shost 0x%p\n", shost);
9203 boardp = shost_priv(shost);
9204 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9207 * 'qdonep' contains the command's ending status.
9209 switch (qdonep->d3.done_stat) {
9210 case QD_NO_ERROR:
9211 ASC_DBG(2, "QD_NO_ERROR\n");
9212 scp->result = 0;
9215 * Check for an underrun condition.
9217 * If there was no error and an underrun condition, then
9218 * return the number of underrun bytes.
9220 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
9221 qdonep->remain_bytes <= scp->request_bufflen) {
9222 ASC_DBG(1, "underrun condition %u bytes\n",
9223 (unsigned)qdonep->remain_bytes);
9224 scp->resid = qdonep->remain_bytes;
9226 break;
9228 case QD_WITH_ERROR:
9229 ASC_DBG(2, "QD_WITH_ERROR\n");
9230 switch (qdonep->d3.host_stat) {
9231 case QHSTA_NO_ERROR:
9232 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
9233 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
9234 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9235 sizeof(scp->sense_buffer));
9237 * Note: The 'status_byte()' macro used by
9238 * target drivers defined in scsi.h shifts the
9239 * status byte returned by host drivers right
9240 * by 1 bit. This is why target drivers also
9241 * use right shifted status byte definitions.
9242 * For instance target drivers use
9243 * CHECK_CONDITION, defined to 0x1, instead of
9244 * the SCSI defined check condition value of
9245 * 0x2. Host drivers are supposed to return
9246 * the status byte as it is defined by SCSI.
9248 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
9249 STATUS_BYTE(qdonep->d3.scsi_stat);
9250 } else {
9251 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
9253 break;
9255 default:
9256 /* QHSTA error occurred */
9257 ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
9258 scp->result = HOST_BYTE(DID_BAD_TARGET);
9259 break;
9261 break;
9263 case QD_ABORTED_BY_HOST:
9264 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
9265 scp->result =
9266 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9267 scsi_msg) |
9268 STATUS_BYTE(qdonep->d3.scsi_stat);
9269 break;
9271 default:
9272 ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
9273 scp->result =
9274 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9275 scsi_msg) |
9276 STATUS_BYTE(qdonep->d3.scsi_stat);
9277 break;
9281 * If the 'init_tidmask' bit isn't already set for the target and the
9282 * current request finished normally, then set the bit for the target
9283 * to indicate that a device is present.
9285 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
9286 qdonep->d3.done_stat == QD_NO_ERROR &&
9287 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
9288 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
9291 asc_scsi_done(scp);
9294 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9296 uchar next_qp;
9297 uchar n_q_used;
9298 uchar sg_list_qp;
9299 uchar sg_queue_cnt;
9300 uchar q_cnt;
9301 uchar done_q_tail;
9302 uchar tid_no;
9303 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9304 ASC_SCSI_BIT_ID_TYPE target_id;
9305 PortAddr iop_base;
9306 ushort q_addr;
9307 ushort sg_q_addr;
9308 uchar cur_target_qng;
9309 ASC_QDONE_INFO scsiq_buf;
9310 ASC_QDONE_INFO *scsiq;
9311 int false_overrun;
9313 iop_base = asc_dvc->iop_base;
9314 n_q_used = 1;
9315 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9316 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9317 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9318 next_qp = AscReadLramByte(iop_base,
9319 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9320 if (next_qp != ASC_QLINK_END) {
9321 AscPutVarDoneQTail(iop_base, next_qp);
9322 q_addr = ASC_QNO_TO_QADDR(next_qp);
9323 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9324 asc_dvc->max_dma_count);
9325 AscWriteLramByte(iop_base,
9326 (ushort)(q_addr +
9327 (ushort)ASC_SCSIQ_B_STATUS),
9328 (uchar)(scsiq->
9329 q_status & (uchar)~(QS_READY |
9330 QS_ABORTED)));
9331 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9332 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9333 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9334 sg_q_addr = q_addr;
9335 sg_list_qp = next_qp;
9336 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9337 sg_list_qp = AscReadLramByte(iop_base,
9338 (ushort)(sg_q_addr
9339 + (ushort)
9340 ASC_SCSIQ_B_FWD));
9341 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9342 if (sg_list_qp == ASC_QLINK_END) {
9343 AscSetLibErrorCode(asc_dvc,
9344 ASCQ_ERR_SG_Q_LINKS);
9345 scsiq->d3.done_stat = QD_WITH_ERROR;
9346 scsiq->d3.host_stat =
9347 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9348 goto FATAL_ERR_QDONE;
9350 AscWriteLramByte(iop_base,
9351 (ushort)(sg_q_addr + (ushort)
9352 ASC_SCSIQ_B_STATUS),
9353 QS_FREE);
9355 n_q_used = sg_queue_cnt + 1;
9356 AscPutVarDoneQTail(iop_base, sg_list_qp);
9358 if (asc_dvc->queue_full_or_busy & target_id) {
9359 cur_target_qng = AscReadLramByte(iop_base,
9360 (ushort)((ushort)
9361 ASC_QADR_BEG
9362 + (ushort)
9363 scsiq->d2.
9364 target_ix));
9365 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9366 scsi_busy = AscReadLramByte(iop_base, (ushort)
9367 ASCV_SCSIBUSY_B);
9368 scsi_busy &= ~target_id;
9369 AscWriteLramByte(iop_base,
9370 (ushort)ASCV_SCSIBUSY_B,
9371 scsi_busy);
9372 asc_dvc->queue_full_or_busy &= ~target_id;
9375 if (asc_dvc->cur_total_qng >= n_q_used) {
9376 asc_dvc->cur_total_qng -= n_q_used;
9377 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9378 asc_dvc->cur_dvc_qng[tid_no]--;
9380 } else {
9381 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9382 scsiq->d3.done_stat = QD_WITH_ERROR;
9383 goto FATAL_ERR_QDONE;
9385 if ((scsiq->d2.srb_ptr == 0UL) ||
9386 ((scsiq->q_status & QS_ABORTED) != 0)) {
9387 return (0x11);
9388 } else if (scsiq->q_status == QS_DONE) {
9389 false_overrun = FALSE;
9390 if (scsiq->extra_bytes != 0) {
9391 scsiq->remain_bytes +=
9392 (ADV_DCNT)scsiq->extra_bytes;
9394 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9395 if (scsiq->d3.host_stat ==
9396 QHSTA_M_DATA_OVER_RUN) {
9397 if ((scsiq->
9398 cntl & (QC_DATA_IN | QC_DATA_OUT))
9399 == 0) {
9400 scsiq->d3.done_stat =
9401 QD_NO_ERROR;
9402 scsiq->d3.host_stat =
9403 QHSTA_NO_ERROR;
9404 } else if (false_overrun) {
9405 scsiq->d3.done_stat =
9406 QD_NO_ERROR;
9407 scsiq->d3.host_stat =
9408 QHSTA_NO_ERROR;
9410 } else if (scsiq->d3.host_stat ==
9411 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9412 AscStopChip(iop_base);
9413 AscSetChipControl(iop_base,
9414 (uchar)(CC_SCSI_RESET
9415 | CC_HALT));
9416 udelay(60);
9417 AscSetChipControl(iop_base, CC_HALT);
9418 AscSetChipStatus(iop_base,
9419 CIW_CLR_SCSI_RESET_INT);
9420 AscSetChipStatus(iop_base, 0);
9421 AscSetChipControl(iop_base, 0);
9424 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9425 asc_isr_callback(asc_dvc, scsiq);
9426 } else {
9427 if ((AscReadLramByte(iop_base,
9428 (ushort)(q_addr + (ushort)
9429 ASC_SCSIQ_CDB_BEG))
9430 == START_STOP)) {
9431 asc_dvc->unit_not_ready &= ~target_id;
9432 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9433 asc_dvc->start_motor &=
9434 ~target_id;
9438 return (1);
9439 } else {
9440 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9441 FATAL_ERR_QDONE:
9442 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9443 asc_isr_callback(asc_dvc, scsiq);
9445 return (0x80);
9448 return (0);
9451 static int AscISR(ASC_DVC_VAR *asc_dvc)
9453 ASC_CS_TYPE chipstat;
9454 PortAddr iop_base;
9455 ushort saved_ram_addr;
9456 uchar ctrl_reg;
9457 uchar saved_ctrl_reg;
9458 int int_pending;
9459 int status;
9460 uchar host_flag;
9462 iop_base = asc_dvc->iop_base;
9463 int_pending = FALSE;
9465 if (AscIsIntPending(iop_base) == 0)
9466 return int_pending;
9468 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9469 return ERR;
9471 if (asc_dvc->in_critical_cnt != 0) {
9472 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9473 return ERR;
9475 if (asc_dvc->is_in_int) {
9476 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9477 return ERR;
9479 asc_dvc->is_in_int = TRUE;
9480 ctrl_reg = AscGetChipControl(iop_base);
9481 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9482 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9483 chipstat = AscGetChipStatus(iop_base);
9484 if (chipstat & CSW_SCSI_RESET_LATCH) {
9485 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9486 int i = 10;
9487 int_pending = TRUE;
9488 asc_dvc->sdtr_done = 0;
9489 saved_ctrl_reg &= (uchar)(~CC_HALT);
9490 while ((AscGetChipStatus(iop_base) &
9491 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9492 mdelay(100);
9494 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9495 AscSetChipControl(iop_base, CC_HALT);
9496 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9497 AscSetChipStatus(iop_base, 0);
9498 chipstat = AscGetChipStatus(iop_base);
9501 saved_ram_addr = AscGetChipLramAddr(iop_base);
9502 host_flag = AscReadLramByte(iop_base,
9503 ASCV_HOST_FLAG_B) &
9504 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9505 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9506 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9507 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
9508 AscAckInterrupt(iop_base);
9509 int_pending = TRUE;
9510 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9511 if (AscIsrChipHalted(asc_dvc) == ERR) {
9512 goto ISR_REPORT_QDONE_FATAL_ERROR;
9513 } else {
9514 saved_ctrl_reg &= (uchar)(~CC_HALT);
9516 } else {
9517 ISR_REPORT_QDONE_FATAL_ERROR:
9518 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9519 while (((status =
9520 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9522 } else {
9523 do {
9524 if ((status =
9525 AscIsrQDone(asc_dvc)) == 1) {
9526 break;
9528 } while (status == 0x11);
9530 if ((status & 0x80) != 0)
9531 int_pending = ERR;
9534 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9535 AscSetChipLramAddr(iop_base, saved_ram_addr);
9536 AscSetChipControl(iop_base, saved_ctrl_reg);
9537 asc_dvc->is_in_int = FALSE;
9538 return int_pending;
9542 * advansys_reset()
9544 * Reset the bus associated with the command 'scp'.
9546 * This function runs its own thread. Interrupts must be blocked but
9547 * sleeping is allowed and no locking other than for host structures is
9548 * required. Returns SUCCESS or FAILED.
9550 static int advansys_reset(struct scsi_cmnd *scp)
9552 struct Scsi_Host *shost = scp->device->host;
9553 struct asc_board *boardp = shost_priv(shost);
9554 unsigned long flags;
9555 int status;
9556 int ret = SUCCESS;
9558 ASC_DBG(1, "0x%p\n", scp);
9560 ASC_STATS(shost, reset);
9562 scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
9564 if (ASC_NARROW_BOARD(boardp)) {
9565 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9567 /* Reset the chip and SCSI bus. */
9568 ASC_DBG(1, "before AscInitAsc1000Driver()\n");
9569 status = AscInitAsc1000Driver(asc_dvc);
9571 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
9572 if (asc_dvc->err_code) {
9573 scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9574 "0x%x\n", asc_dvc->err_code);
9575 ret = FAILED;
9576 } else if (status) {
9577 scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9578 "0x%x\n", status);
9579 } else {
9580 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9581 "successful\n");
9584 ASC_DBG(1, "after AscInitAsc1000Driver()\n");
9585 spin_lock_irqsave(shost->host_lock, flags);
9586 } else {
9588 * If the suggest reset bus flags are set, then reset the bus.
9589 * Otherwise only reset the device.
9591 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
9594 * Reset the target's SCSI bus.
9596 ASC_DBG(1, "before AdvResetChipAndSB()\n");
9597 switch (AdvResetChipAndSB(adv_dvc)) {
9598 case ASC_TRUE:
9599 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9600 "successful\n");
9601 break;
9602 case ASC_FALSE:
9603 default:
9604 scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
9605 ret = FAILED;
9606 break;
9608 spin_lock_irqsave(shost->host_lock, flags);
9609 AdvISR(adv_dvc);
9612 /* Save the time of the most recently completed reset. */
9613 boardp->last_reset = jiffies;
9614 spin_unlock_irqrestore(shost->host_lock, flags);
9616 ASC_DBG(1, "ret %d\n", ret);
9618 return ret;
9622 * advansys_biosparam()
9624 * Translate disk drive geometry if the "BIOS greater than 1 GB"
9625 * support is enabled for a drive.
9627 * ip (information pointer) is an int array with the following definition:
9628 * ip[0]: heads
9629 * ip[1]: sectors
9630 * ip[2]: cylinders
9632 static int
9633 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9634 sector_t capacity, int ip[])
9636 struct asc_board *boardp = shost_priv(sdev->host);
9638 ASC_DBG(1, "begin\n");
9639 ASC_STATS(sdev->host, biosparam);
9640 if (ASC_NARROW_BOARD(boardp)) {
9641 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
9642 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
9643 ip[0] = 255;
9644 ip[1] = 63;
9645 } else {
9646 ip[0] = 64;
9647 ip[1] = 32;
9649 } else {
9650 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
9651 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
9652 ip[0] = 255;
9653 ip[1] = 63;
9654 } else {
9655 ip[0] = 64;
9656 ip[1] = 32;
9659 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
9660 ASC_DBG(1, "end\n");
9661 return 0;
9665 * First-level interrupt handler.
9667 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9669 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9671 struct Scsi_Host *shost = dev_id;
9672 struct asc_board *boardp = shost_priv(shost);
9673 irqreturn_t result = IRQ_NONE;
9675 ASC_DBG(2, "boardp 0x%p\n", boardp);
9676 spin_lock(shost->host_lock);
9677 if (ASC_NARROW_BOARD(boardp)) {
9678 if (AscIsIntPending(shost->io_port)) {
9679 result = IRQ_HANDLED;
9680 ASC_STATS(shost, interrupt);
9681 ASC_DBG(1, "before AscISR()\n");
9682 AscISR(&boardp->dvc_var.asc_dvc_var);
9684 } else {
9685 ASC_DBG(1, "before AdvISR()\n");
9686 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9687 result = IRQ_HANDLED;
9688 ASC_STATS(shost, interrupt);
9691 spin_unlock(shost->host_lock);
9693 ASC_DBG(1, "end\n");
9694 return result;
9697 static int AscHostReqRiscHalt(PortAddr iop_base)
9699 int count = 0;
9700 int sta = 0;
9701 uchar saved_stop_code;
9703 if (AscIsChipHalted(iop_base))
9704 return (1);
9705 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9706 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9707 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9708 do {
9709 if (AscIsChipHalted(iop_base)) {
9710 sta = 1;
9711 break;
9713 mdelay(100);
9714 } while (count++ < 20);
9715 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9716 return (sta);
9719 static int
9720 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9722 int sta = FALSE;
9724 if (AscHostReqRiscHalt(iop_base)) {
9725 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9726 AscStartChip(iop_base);
9728 return sta;
9731 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9733 char type = sdev->type;
9734 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
9736 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9737 return;
9738 if (asc_dvc->init_sdtr & tid_bits)
9739 return;
9741 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9742 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9744 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9745 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9746 (type == TYPE_ROM) || (type == TYPE_TAPE))
9747 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9749 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9750 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
9751 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
9754 static void
9755 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9757 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
9758 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
9760 if (sdev->lun == 0) {
9761 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
9762 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
9763 asc_dvc->init_sdtr |= tid_bit;
9764 } else {
9765 asc_dvc->init_sdtr &= ~tid_bit;
9768 if (orig_init_sdtr != asc_dvc->init_sdtr)
9769 AscAsyncFix(asc_dvc, sdev);
9772 if (sdev->tagged_supported) {
9773 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
9774 if (sdev->lun == 0) {
9775 asc_dvc->cfg->can_tagged_qng |= tid_bit;
9776 asc_dvc->use_tagged_qng |= tid_bit;
9778 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9779 asc_dvc->max_dvc_qng[sdev->id]);
9781 } else {
9782 if (sdev->lun == 0) {
9783 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9784 asc_dvc->use_tagged_qng &= ~tid_bit;
9786 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9789 if ((sdev->lun == 0) &&
9790 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
9791 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
9792 asc_dvc->cfg->disc_enable);
9793 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
9794 asc_dvc->use_tagged_qng);
9795 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
9796 asc_dvc->cfg->can_tagged_qng);
9798 asc_dvc->max_dvc_qng[sdev->id] =
9799 asc_dvc->cfg->max_tag_qng[sdev->id];
9800 AscWriteLramByte(asc_dvc->iop_base,
9801 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
9802 asc_dvc->max_dvc_qng[sdev->id]);
9807 * Wide Transfers
9809 * If the EEPROM enabled WDTR for the device and the device supports wide
9810 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
9811 * write the new value to the microcode.
9813 static void
9814 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
9816 unsigned short cfg_word;
9817 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9818 if ((cfg_word & tidmask) != 0)
9819 return;
9821 cfg_word |= tidmask;
9822 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9825 * Clear the microcode SDTR and WDTR negotiation done indicators for
9826 * the target to cause it to negotiate with the new setting set above.
9827 * WDTR when accepted causes the target to enter asynchronous mode, so
9828 * SDTR must be negotiated.
9830 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9831 cfg_word &= ~tidmask;
9832 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9833 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9834 cfg_word &= ~tidmask;
9835 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9839 * Synchronous Transfers
9841 * If the EEPROM enabled SDTR for the device and the device
9842 * supports synchronous transfers, then turn on the device's
9843 * 'sdtr_able' bit. Write the new value to the microcode.
9845 static void
9846 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
9848 unsigned short cfg_word;
9849 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9850 if ((cfg_word & tidmask) != 0)
9851 return;
9853 cfg_word |= tidmask;
9854 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9857 * Clear the microcode "SDTR negotiation" done indicator for the
9858 * target to cause it to negotiate with the new setting set above.
9860 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9861 cfg_word &= ~tidmask;
9862 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9866 * PPR (Parallel Protocol Request) Capable
9868 * If the device supports DT mode, then it must be PPR capable.
9869 * The PPR message will be used in place of the SDTR and WDTR
9870 * messages to negotiate synchronous speed and offset, transfer
9871 * width, and protocol options.
9873 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
9874 AdvPortAddr iop_base, unsigned short tidmask)
9876 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9877 adv_dvc->ppr_able |= tidmask;
9878 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9881 static void
9882 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
9884 AdvPortAddr iop_base = adv_dvc->iop_base;
9885 unsigned short tidmask = 1 << sdev->id;
9887 if (sdev->lun == 0) {
9889 * Handle WDTR, SDTR, and Tag Queuing. If the feature
9890 * is enabled in the EEPROM and the device supports the
9891 * feature, then enable it in the microcode.
9894 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
9895 advansys_wide_enable_wdtr(iop_base, tidmask);
9896 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
9897 advansys_wide_enable_sdtr(iop_base, tidmask);
9898 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
9899 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
9902 * Tag Queuing is disabled for the BIOS which runs in polled
9903 * mode and would see no benefit from Tag Queuing. Also by
9904 * disabling Tag Queuing in the BIOS devices with Tag Queuing
9905 * bugs will at least work with the BIOS.
9907 if ((adv_dvc->tagqng_able & tidmask) &&
9908 sdev->tagged_supported) {
9909 unsigned short cfg_word;
9910 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
9911 cfg_word |= tidmask;
9912 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
9913 cfg_word);
9914 AdvWriteByteLram(iop_base,
9915 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
9916 adv_dvc->max_dvc_qng);
9920 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
9921 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9922 adv_dvc->max_dvc_qng);
9923 } else {
9924 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9929 * Set the number of commands to queue per device for the
9930 * specified host adapter.
9932 static int advansys_slave_configure(struct scsi_device *sdev)
9934 struct asc_board *boardp = shost_priv(sdev->host);
9936 if (ASC_NARROW_BOARD(boardp))
9937 advansys_narrow_slave_configure(sdev,
9938 &boardp->dvc_var.asc_dvc_var);
9939 else
9940 advansys_wide_slave_configure(sdev,
9941 &boardp->dvc_var.adv_dvc_var);
9943 return 0;
9946 static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
9947 struct asc_scsi_q *asc_scsi_q)
9949 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
9952 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
9954 asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
9957 * Build the ASC_SCSI_Q request.
9959 asc_scsi_q->cdbptr = &scp->cmnd[0];
9960 asc_scsi_q->q2.cdb_len = scp->cmd_len;
9961 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
9962 asc_scsi_q->q1.target_lun = scp->device->lun;
9963 asc_scsi_q->q2.target_ix =
9964 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
9965 asc_scsi_q->q1.sense_addr =
9966 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
9967 asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
9970 * If there are any outstanding requests for the current target,
9971 * then every 255th request send an ORDERED request. This heuristic
9972 * tries to retain the benefit of request sorting while preventing
9973 * request starvation. 255 is the max number of tags or pending commands
9974 * a device may have outstanding.
9976 * The request count is incremented below for every successfully
9977 * started request.
9980 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
9981 (boardp->reqcnt[scp->device->id] % 255) == 0) {
9982 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
9983 } else {
9984 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
9988 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
9989 * buffer command.
9991 if (scp->use_sg == 0) {
9993 * CDB request of single contiguous buffer.
9995 ASC_STATS(scp->device->host, cont_cnt);
9996 scp->SCp.dma_handle = scp->request_bufflen ?
9997 dma_map_single(boardp->dev, scp->request_buffer,
9998 scp->request_bufflen,
9999 scp->sc_data_direction) : 0;
10000 asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
10001 asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen);
10002 ASC_STATS_ADD(scp->device->host, cont_xfer,
10003 ASC_CEILING(scp->request_bufflen, 512));
10004 asc_scsi_q->q1.sg_queue_cnt = 0;
10005 asc_scsi_q->sg_head = NULL;
10006 } else {
10008 * CDB scatter-gather request list.
10010 int sgcnt;
10011 int use_sg;
10012 struct scatterlist *slp;
10013 struct asc_sg_head *asc_sg_head;
10015 slp = (struct scatterlist *)scp->request_buffer;
10016 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10017 scp->sc_data_direction);
10019 if (use_sg > scp->device->host->sg_tablesize) {
10020 scmd_printk(KERN_ERR, scp, "use_sg %d > "
10021 "sg_tablesize %d\n", use_sg,
10022 scp->device->host->sg_tablesize);
10023 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10024 scp->sc_data_direction);
10025 scp->result = HOST_BYTE(DID_ERROR);
10026 return ASC_ERROR;
10029 ASC_STATS(scp->device->host, sg_cnt);
10031 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
10032 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
10033 if (!asc_sg_head) {
10034 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10035 scp->sc_data_direction);
10036 scp->result = HOST_BYTE(DID_SOFT_ERROR);
10037 return ASC_ERROR;
10040 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
10041 asc_scsi_q->sg_head = asc_sg_head;
10042 asc_scsi_q->q1.data_cnt = 0;
10043 asc_scsi_q->q1.data_addr = 0;
10044 /* This is a byte value, otherwise it would need to be swapped. */
10045 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
10046 ASC_STATS_ADD(scp->device->host, sg_elem,
10047 asc_sg_head->entry_cnt);
10050 * Convert scatter-gather list into ASC_SG_HEAD list.
10052 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
10053 asc_sg_head->sg_list[sgcnt].addr =
10054 cpu_to_le32(sg_dma_address(slp));
10055 asc_sg_head->sg_list[sgcnt].bytes =
10056 cpu_to_le32(sg_dma_len(slp));
10057 ASC_STATS_ADD(scp->device->host, sg_xfer,
10058 ASC_CEILING(sg_dma_len(slp), 512));
10062 ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
10063 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10065 return ASC_NOERROR;
10069 * Build scatter-gather list for Adv Library (Wide Board).
10071 * Additional ADV_SG_BLOCK structures will need to be allocated
10072 * if the total number of scatter-gather elements exceeds
10073 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
10074 * assumed to be physically contiguous.
10076 * Return:
10077 * ADV_SUCCESS(1) - SG List successfully created
10078 * ADV_ERROR(-1) - SG List creation failed
10080 static int
10081 adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
10082 int use_sg)
10084 adv_sgblk_t *sgblkp;
10085 ADV_SCSI_REQ_Q *scsiqp;
10086 struct scatterlist *slp;
10087 int sg_elem_cnt;
10088 ADV_SG_BLOCK *sg_block, *prev_sg_block;
10089 ADV_PADDR sg_block_paddr;
10090 int i;
10092 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10093 slp = (struct scatterlist *)scp->request_buffer;
10094 sg_elem_cnt = use_sg;
10095 prev_sg_block = NULL;
10096 reqp->sgblkp = NULL;
10098 for (;;) {
10100 * Allocate a 'adv_sgblk_t' structure from the board free
10101 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
10102 * (15) scatter-gather elements.
10104 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
10105 ASC_DBG(1, "no free adv_sgblk_t\n");
10106 ASC_STATS(scp->device->host, adv_build_nosg);
10109 * Allocation failed. Free 'adv_sgblk_t' structures
10110 * already allocated for the request.
10112 while ((sgblkp = reqp->sgblkp) != NULL) {
10113 /* Remove 'sgblkp' from the request list. */
10114 reqp->sgblkp = sgblkp->next_sgblkp;
10116 /* Add 'sgblkp' to the board free list. */
10117 sgblkp->next_sgblkp = boardp->adv_sgblkp;
10118 boardp->adv_sgblkp = sgblkp;
10120 return ASC_BUSY;
10123 /* Complete 'adv_sgblk_t' board allocation. */
10124 boardp->adv_sgblkp = sgblkp->next_sgblkp;
10125 sgblkp->next_sgblkp = NULL;
10128 * Get 8 byte aligned virtual and physical addresses
10129 * for the allocated ADV_SG_BLOCK structure.
10131 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10132 sg_block_paddr = virt_to_bus(sg_block);
10135 * Check if this is the first 'adv_sgblk_t' for the
10136 * request.
10138 if (reqp->sgblkp == NULL) {
10139 /* Request's first scatter-gather block. */
10140 reqp->sgblkp = sgblkp;
10143 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10144 * address pointers.
10146 scsiqp->sg_list_ptr = sg_block;
10147 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
10148 } else {
10149 /* Request's second or later scatter-gather block. */
10150 sgblkp->next_sgblkp = reqp->sgblkp;
10151 reqp->sgblkp = sgblkp;
10154 * Point the previous ADV_SG_BLOCK structure to
10155 * the newly allocated ADV_SG_BLOCK structure.
10157 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
10160 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
10161 sg_block->sg_list[i].sg_addr =
10162 cpu_to_le32(sg_dma_address(slp));
10163 sg_block->sg_list[i].sg_count =
10164 cpu_to_le32(sg_dma_len(slp));
10165 ASC_STATS_ADD(scp->device->host, sg_xfer,
10166 ASC_CEILING(sg_dma_len(slp), 512));
10168 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
10169 sg_block->sg_cnt = i + 1;
10170 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
10171 return ADV_SUCCESS;
10173 slp++;
10175 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10176 prev_sg_block = sg_block;
10181 * Build a request structure for the Adv Library (Wide Board).
10183 * If an adv_req_t can not be allocated to issue the request,
10184 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
10186 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
10187 * microcode for DMA addresses or math operations are byte swapped
10188 * to little-endian order.
10190 static int
10191 adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
10192 ADV_SCSI_REQ_Q **adv_scsiqpp)
10194 adv_req_t *reqp;
10195 ADV_SCSI_REQ_Q *scsiqp;
10196 int i;
10197 int ret;
10200 * Allocate an adv_req_t structure from the board to execute
10201 * the command.
10203 if (boardp->adv_reqp == NULL) {
10204 ASC_DBG(1, "no free adv_req_t\n");
10205 ASC_STATS(scp->device->host, adv_build_noreq);
10206 return ASC_BUSY;
10207 } else {
10208 reqp = boardp->adv_reqp;
10209 boardp->adv_reqp = reqp->next_reqp;
10210 reqp->next_reqp = NULL;
10214 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
10216 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10219 * Initialize the structure.
10221 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
10224 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
10226 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
10229 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
10231 reqp->cmndp = scp;
10234 * Build the ADV_SCSI_REQ_Q request.
10237 /* Set CDB length and copy it to the request structure. */
10238 scsiqp->cdb_len = scp->cmd_len;
10239 /* Copy first 12 CDB bytes to cdb[]. */
10240 for (i = 0; i < scp->cmd_len && i < 12; i++) {
10241 scsiqp->cdb[i] = scp->cmnd[i];
10243 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
10244 for (; i < scp->cmd_len; i++) {
10245 scsiqp->cdb16[i - 12] = scp->cmnd[i];
10248 scsiqp->target_id = scp->device->id;
10249 scsiqp->target_lun = scp->device->lun;
10251 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10252 scsiqp->sense_len = sizeof(scp->sense_buffer);
10255 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
10256 * buffer command.
10259 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10260 scsiqp->vdata_addr = scp->request_buffer;
10261 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
10263 if (scp->use_sg == 0) {
10265 * CDB request of single contiguous buffer.
10267 reqp->sgblkp = NULL;
10268 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10269 if (scp->request_bufflen) {
10270 scsiqp->vdata_addr = scp->request_buffer;
10271 scp->SCp.dma_handle =
10272 dma_map_single(boardp->dev, scp->request_buffer,
10273 scp->request_bufflen,
10274 scp->sc_data_direction);
10275 } else {
10276 scsiqp->vdata_addr = NULL;
10277 scp->SCp.dma_handle = 0;
10279 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
10280 scsiqp->sg_list_ptr = NULL;
10281 scsiqp->sg_real_addr = 0;
10282 ASC_STATS(scp->device->host, cont_cnt);
10283 ASC_STATS_ADD(scp->device->host, cont_xfer,
10284 ASC_CEILING(scp->request_bufflen, 512));
10285 } else {
10287 * CDB scatter-gather request list.
10289 struct scatterlist *slp;
10290 int use_sg;
10292 slp = (struct scatterlist *)scp->request_buffer;
10293 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10294 scp->sc_data_direction);
10296 if (use_sg > ADV_MAX_SG_LIST) {
10297 scmd_printk(KERN_ERR, scp, "use_sg %d > "
10298 "ADV_MAX_SG_LIST %d\n", use_sg,
10299 scp->device->host->sg_tablesize);
10300 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10301 scp->sc_data_direction);
10302 scp->result = HOST_BYTE(DID_ERROR);
10305 * Free the 'adv_req_t' structure by adding it back
10306 * to the board free list.
10308 reqp->next_reqp = boardp->adv_reqp;
10309 boardp->adv_reqp = reqp;
10311 return ASC_ERROR;
10314 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10315 if (ret != ADV_SUCCESS) {
10317 * Free the adv_req_t structure by adding it back to
10318 * the board free list.
10320 reqp->next_reqp = boardp->adv_reqp;
10321 boardp->adv_reqp = reqp;
10323 return ret;
10326 ASC_STATS(scp->device->host, sg_cnt);
10327 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
10330 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10331 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10333 *adv_scsiqpp = scsiqp;
10335 return ASC_NOERROR;
10338 static int AscSgListToQueue(int sg_list)
10340 int n_sg_list_qs;
10342 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10343 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10344 n_sg_list_qs++;
10345 return n_sg_list_qs + 1;
10348 static uint
10349 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10351 uint cur_used_qs;
10352 uint cur_free_qs;
10353 ASC_SCSI_BIT_ID_TYPE target_id;
10354 uchar tid_no;
10356 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10357 tid_no = ASC_TIX_TO_TID(target_ix);
10358 if ((asc_dvc->unit_not_ready & target_id) ||
10359 (asc_dvc->queue_full_or_busy & target_id)) {
10360 return 0;
10362 if (n_qs == 1) {
10363 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10364 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
10365 } else {
10366 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10367 (uint) ASC_MIN_FREE_Q;
10369 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10370 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10371 if (asc_dvc->cur_dvc_qng[tid_no] >=
10372 asc_dvc->max_dvc_qng[tid_no]) {
10373 return 0;
10375 return cur_free_qs;
10377 if (n_qs > 1) {
10378 if ((n_qs > asc_dvc->last_q_shortage)
10379 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10380 asc_dvc->last_q_shortage = n_qs;
10383 return 0;
10386 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10388 ushort q_addr;
10389 uchar next_qp;
10390 uchar q_status;
10392 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10393 q_status = (uchar)AscReadLramByte(iop_base,
10394 (ushort)(q_addr +
10395 ASC_SCSIQ_B_STATUS));
10396 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10397 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
10398 return next_qp;
10399 return ASC_QLINK_END;
10402 static uchar
10403 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10405 uchar i;
10407 for (i = 0; i < n_free_q; i++) {
10408 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
10409 if (free_q_head == ASC_QLINK_END)
10410 break;
10412 return free_q_head;
10416 * void
10417 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10419 * Calling/Exit State:
10420 * none
10422 * Description:
10423 * Output an ASC_SCSI_Q structure to the chip
10425 static void
10426 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10428 int i;
10430 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
10431 AscSetChipLramAddr(iop_base, s_addr);
10432 for (i = 0; i < 2 * words; i += 2) {
10433 if (i == 4 || i == 20) {
10434 continue;
10436 outpw(iop_base + IOP_RAM_DATA,
10437 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
10441 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10443 ushort q_addr;
10444 uchar tid_no;
10445 uchar sdtr_data;
10446 uchar syn_period_ix;
10447 uchar syn_offset;
10448 PortAddr iop_base;
10450 iop_base = asc_dvc->iop_base;
10451 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10452 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10453 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10454 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10455 syn_period_ix =
10456 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
10457 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
10458 AscMsgOutSDTR(asc_dvc,
10459 asc_dvc->sdtr_period_tbl[syn_period_ix],
10460 syn_offset);
10461 scsiq->q1.cntl |= QC_MSG_OUT;
10463 q_addr = ASC_QNO_TO_QADDR(q_no);
10464 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
10465 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10467 scsiq->q1.status = QS_FREE;
10468 AscMemWordCopyPtrToLram(iop_base,
10469 q_addr + ASC_SCSIQ_CDB_BEG,
10470 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
10472 DvcPutScsiQ(iop_base,
10473 q_addr + ASC_SCSIQ_CPY_BEG,
10474 (uchar *)&scsiq->q1.cntl,
10475 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
10476 AscWriteLramWord(iop_base,
10477 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
10478 (ushort)(((ushort)scsiq->q1.
10479 q_no << 8) | (ushort)QS_READY));
10480 return 1;
10483 static int
10484 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10486 int sta;
10487 int i;
10488 ASC_SG_HEAD *sg_head;
10489 ASC_SG_LIST_Q scsi_sg_q;
10490 ASC_DCNT saved_data_addr;
10491 ASC_DCNT saved_data_cnt;
10492 PortAddr iop_base;
10493 ushort sg_list_dwords;
10494 ushort sg_index;
10495 ushort sg_entry_cnt;
10496 ushort q_addr;
10497 uchar next_qp;
10499 iop_base = asc_dvc->iop_base;
10500 sg_head = scsiq->sg_head;
10501 saved_data_addr = scsiq->q1.data_addr;
10502 saved_data_cnt = scsiq->q1.data_cnt;
10503 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
10504 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
10505 #if CC_VERY_LONG_SG_LIST
10507 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
10508 * then not all SG elements will fit in the allocated queues.
10509 * The rest of the SG elements will be copied when the RISC
10510 * completes the SG elements that fit and halts.
10512 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10514 * Set sg_entry_cnt to be the number of SG elements that
10515 * will fit in the allocated SG queues. It is minus 1, because
10516 * the first SG element is handled above. ASC_MAX_SG_LIST is
10517 * already inflated by 1 to account for this. For example it
10518 * may be 50 which is 1 + 7 queues * 7 SG elements.
10520 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10523 * Keep track of remaining number of SG elements that will
10524 * need to be handled from a_isr.c.
10526 scsiq->remain_sg_entry_cnt =
10527 sg_head->entry_cnt - ASC_MAX_SG_LIST;
10528 } else {
10529 #endif /* CC_VERY_LONG_SG_LIST */
10531 * Set sg_entry_cnt to be the number of SG elements that
10532 * will fit in the allocated SG queues. It is minus 1, because
10533 * the first SG element is handled above.
10535 sg_entry_cnt = sg_head->entry_cnt - 1;
10536 #if CC_VERY_LONG_SG_LIST
10538 #endif /* CC_VERY_LONG_SG_LIST */
10539 if (sg_entry_cnt != 0) {
10540 scsiq->q1.cntl |= QC_SG_HEAD;
10541 q_addr = ASC_QNO_TO_QADDR(q_no);
10542 sg_index = 1;
10543 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10544 scsi_sg_q.sg_head_qp = q_no;
10545 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10546 for (i = 0; i < sg_head->queue_cnt; i++) {
10547 scsi_sg_q.seq_no = i + 1;
10548 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10549 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10550 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10551 if (i == 0) {
10552 scsi_sg_q.sg_list_cnt =
10553 ASC_SG_LIST_PER_Q;
10554 scsi_sg_q.sg_cur_list_cnt =
10555 ASC_SG_LIST_PER_Q;
10556 } else {
10557 scsi_sg_q.sg_list_cnt =
10558 ASC_SG_LIST_PER_Q - 1;
10559 scsi_sg_q.sg_cur_list_cnt =
10560 ASC_SG_LIST_PER_Q - 1;
10562 } else {
10563 #if CC_VERY_LONG_SG_LIST
10565 * This is the last SG queue in the list of
10566 * allocated SG queues. If there are more
10567 * SG elements than will fit in the allocated
10568 * queues, then set the QCSG_SG_XFER_MORE flag.
10570 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10571 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10572 } else {
10573 #endif /* CC_VERY_LONG_SG_LIST */
10574 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10575 #if CC_VERY_LONG_SG_LIST
10577 #endif /* CC_VERY_LONG_SG_LIST */
10578 sg_list_dwords = sg_entry_cnt << 1;
10579 if (i == 0) {
10580 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10581 scsi_sg_q.sg_cur_list_cnt =
10582 sg_entry_cnt;
10583 } else {
10584 scsi_sg_q.sg_list_cnt =
10585 sg_entry_cnt - 1;
10586 scsi_sg_q.sg_cur_list_cnt =
10587 sg_entry_cnt - 1;
10589 sg_entry_cnt = 0;
10591 next_qp = AscReadLramByte(iop_base,
10592 (ushort)(q_addr +
10593 ASC_SCSIQ_B_FWD));
10594 scsi_sg_q.q_no = next_qp;
10595 q_addr = ASC_QNO_TO_QADDR(next_qp);
10596 AscMemWordCopyPtrToLram(iop_base,
10597 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10598 (uchar *)&scsi_sg_q,
10599 sizeof(ASC_SG_LIST_Q) >> 1);
10600 AscMemDWordCopyPtrToLram(iop_base,
10601 q_addr + ASC_SGQ_LIST_BEG,
10602 (uchar *)&sg_head->
10603 sg_list[sg_index],
10604 sg_list_dwords);
10605 sg_index += ASC_SG_LIST_PER_Q;
10606 scsiq->next_sg_index = sg_index;
10608 } else {
10609 scsiq->q1.cntl &= ~QC_SG_HEAD;
10611 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10612 scsiq->q1.data_addr = saved_data_addr;
10613 scsiq->q1.data_cnt = saved_data_cnt;
10614 return (sta);
10617 static int
10618 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10620 PortAddr iop_base;
10621 uchar free_q_head;
10622 uchar next_qp;
10623 uchar tid_no;
10624 uchar target_ix;
10625 int sta;
10627 iop_base = asc_dvc->iop_base;
10628 target_ix = scsiq->q2.target_ix;
10629 tid_no = ASC_TIX_TO_TID(target_ix);
10630 sta = 0;
10631 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
10632 if (n_q_required > 1) {
10633 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
10634 (uchar)n_q_required);
10635 if (next_qp != ASC_QLINK_END) {
10636 asc_dvc->last_q_shortage = 0;
10637 scsiq->sg_head->queue_cnt = n_q_required - 1;
10638 scsiq->q1.q_no = free_q_head;
10639 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10640 free_q_head);
10642 } else if (n_q_required == 1) {
10643 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
10644 if (next_qp != ASC_QLINK_END) {
10645 scsiq->q1.q_no = free_q_head;
10646 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
10649 if (sta == 1) {
10650 AscPutVarFreeQHead(iop_base, next_qp);
10651 asc_dvc->cur_total_qng += n_q_required;
10652 asc_dvc->cur_dvc_qng[tid_no]++;
10654 return sta;
10657 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10658 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
10659 INQUIRY,
10660 REQUEST_SENSE,
10661 READ_CAPACITY,
10662 READ_TOC,
10663 MODE_SELECT,
10664 MODE_SENSE,
10665 MODE_SELECT_10,
10666 MODE_SENSE_10,
10667 0xFF,
10668 0xFF,
10669 0xFF,
10670 0xFF,
10671 0xFF,
10672 0xFF,
10673 0xFF,
10674 0xFF
10677 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10679 PortAddr iop_base;
10680 int sta;
10681 int n_q_required;
10682 int disable_syn_offset_one_fix;
10683 int i;
10684 ASC_PADDR addr;
10685 ushort sg_entry_cnt = 0;
10686 ushort sg_entry_cnt_minus_one = 0;
10687 uchar target_ix;
10688 uchar tid_no;
10689 uchar sdtr_data;
10690 uchar extra_bytes;
10691 uchar scsi_cmd;
10692 uchar disable_cmd;
10693 ASC_SG_HEAD *sg_head;
10694 ASC_DCNT data_cnt;
10696 iop_base = asc_dvc->iop_base;
10697 sg_head = scsiq->sg_head;
10698 if (asc_dvc->err_code != 0)
10699 return (ERR);
10700 scsiq->q1.q_no = 0;
10701 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10702 scsiq->q1.extra_bytes = 0;
10704 sta = 0;
10705 target_ix = scsiq->q2.target_ix;
10706 tid_no = ASC_TIX_TO_TID(target_ix);
10707 n_q_required = 1;
10708 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10709 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10710 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10711 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10712 AscMsgOutSDTR(asc_dvc,
10713 asc_dvc->
10714 sdtr_period_tbl[(sdtr_data >> 4) &
10715 (uchar)(asc_dvc->
10716 max_sdtr_index -
10717 1)],
10718 (uchar)(sdtr_data & (uchar)
10719 ASC_SYN_MAX_OFFSET));
10720 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10723 if (asc_dvc->in_critical_cnt != 0) {
10724 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10725 return (ERR);
10727 asc_dvc->in_critical_cnt++;
10728 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10729 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10730 asc_dvc->in_critical_cnt--;
10731 return (ERR);
10733 #if !CC_VERY_LONG_SG_LIST
10734 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10735 asc_dvc->in_critical_cnt--;
10736 return (ERR);
10738 #endif /* !CC_VERY_LONG_SG_LIST */
10739 if (sg_entry_cnt == 1) {
10740 scsiq->q1.data_addr =
10741 (ADV_PADDR)sg_head->sg_list[0].addr;
10742 scsiq->q1.data_cnt =
10743 (ADV_DCNT)sg_head->sg_list[0].bytes;
10744 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10746 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10748 scsi_cmd = scsiq->cdbptr[0];
10749 disable_syn_offset_one_fix = FALSE;
10750 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10751 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10752 if (scsiq->q1.cntl & QC_SG_HEAD) {
10753 data_cnt = 0;
10754 for (i = 0; i < sg_entry_cnt; i++) {
10755 data_cnt +=
10756 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
10757 bytes);
10759 } else {
10760 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10762 if (data_cnt != 0UL) {
10763 if (data_cnt < 512UL) {
10764 disable_syn_offset_one_fix = TRUE;
10765 } else {
10766 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
10767 i++) {
10768 disable_cmd =
10769 _syn_offset_one_disable_cmd[i];
10770 if (disable_cmd == 0xFF) {
10771 break;
10773 if (scsi_cmd == disable_cmd) {
10774 disable_syn_offset_one_fix =
10775 TRUE;
10776 break;
10782 if (disable_syn_offset_one_fix) {
10783 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10784 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10785 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10786 } else {
10787 scsiq->q2.tag_code &= 0x27;
10789 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10790 if (asc_dvc->bug_fix_cntl) {
10791 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10792 if ((scsi_cmd == READ_6) ||
10793 (scsi_cmd == READ_10)) {
10794 addr =
10795 (ADV_PADDR)le32_to_cpu(sg_head->
10796 sg_list
10797 [sg_entry_cnt_minus_one].
10798 addr) +
10799 (ADV_DCNT)le32_to_cpu(sg_head->
10800 sg_list
10801 [sg_entry_cnt_minus_one].
10802 bytes);
10803 extra_bytes =
10804 (uchar)((ushort)addr & 0x0003);
10805 if ((extra_bytes != 0)
10807 ((scsiq->q2.
10808 tag_code &
10809 ASC_TAG_FLAG_EXTRA_BYTES)
10810 == 0)) {
10811 scsiq->q2.tag_code |=
10812 ASC_TAG_FLAG_EXTRA_BYTES;
10813 scsiq->q1.extra_bytes =
10814 extra_bytes;
10815 data_cnt =
10816 le32_to_cpu(sg_head->
10817 sg_list
10818 [sg_entry_cnt_minus_one].
10819 bytes);
10820 data_cnt -=
10821 (ASC_DCNT) extra_bytes;
10822 sg_head->
10823 sg_list
10824 [sg_entry_cnt_minus_one].
10825 bytes =
10826 cpu_to_le32(data_cnt);
10831 sg_head->entry_to_copy = sg_head->entry_cnt;
10832 #if CC_VERY_LONG_SG_LIST
10834 * Set the sg_entry_cnt to the maximum possible. The rest of
10835 * the SG elements will be copied when the RISC completes the
10836 * SG elements that fit and halts.
10838 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10839 sg_entry_cnt = ASC_MAX_SG_LIST;
10841 #endif /* CC_VERY_LONG_SG_LIST */
10842 n_q_required = AscSgListToQueue(sg_entry_cnt);
10843 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10844 (uint) n_q_required)
10845 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10846 if ((sta =
10847 AscSendScsiQueue(asc_dvc, scsiq,
10848 n_q_required)) == 1) {
10849 asc_dvc->in_critical_cnt--;
10850 return (sta);
10853 } else {
10854 if (asc_dvc->bug_fix_cntl) {
10855 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10856 if ((scsi_cmd == READ_6) ||
10857 (scsi_cmd == READ_10)) {
10858 addr =
10859 le32_to_cpu(scsiq->q1.data_addr) +
10860 le32_to_cpu(scsiq->q1.data_cnt);
10861 extra_bytes =
10862 (uchar)((ushort)addr & 0x0003);
10863 if ((extra_bytes != 0)
10865 ((scsiq->q2.
10866 tag_code &
10867 ASC_TAG_FLAG_EXTRA_BYTES)
10868 == 0)) {
10869 data_cnt =
10870 le32_to_cpu(scsiq->q1.
10871 data_cnt);
10872 if (((ushort)data_cnt & 0x01FF)
10873 == 0) {
10874 scsiq->q2.tag_code |=
10875 ASC_TAG_FLAG_EXTRA_BYTES;
10876 data_cnt -= (ASC_DCNT)
10877 extra_bytes;
10878 scsiq->q1.data_cnt =
10879 cpu_to_le32
10880 (data_cnt);
10881 scsiq->q1.extra_bytes =
10882 extra_bytes;
10888 n_q_required = 1;
10889 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10890 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10891 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10892 n_q_required)) == 1) {
10893 asc_dvc->in_critical_cnt--;
10894 return (sta);
10898 asc_dvc->in_critical_cnt--;
10899 return (sta);
10903 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
10905 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
10906 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
10907 * RISC to notify it a new command is ready to be executed.
10909 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
10910 * set to SCSI_MAX_RETRY.
10912 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
10913 * for DMA addresses or math operations are byte swapped to little-endian
10914 * order.
10916 * Return:
10917 * ADV_SUCCESS(1) - The request was successfully queued.
10918 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
10919 * request completes.
10920 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
10921 * host IC error.
10923 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
10925 AdvPortAddr iop_base;
10926 ADV_DCNT req_size;
10927 ADV_PADDR req_paddr;
10928 ADV_CARR_T *new_carrp;
10931 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
10933 if (scsiq->target_id > ADV_MAX_TID) {
10934 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
10935 scsiq->done_status = QD_WITH_ERROR;
10936 return ADV_ERROR;
10939 iop_base = asc_dvc->iop_base;
10942 * Allocate a carrier ensuring at least one carrier always
10943 * remains on the freelist and initialize fields.
10945 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
10946 return ADV_BUSY;
10948 asc_dvc->carr_freelist = (ADV_CARR_T *)
10949 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
10950 asc_dvc->carr_pending_cnt++;
10953 * Set the carrier to be a stopper by setting 'next_vpa'
10954 * to the stopper value. The current stopper will be changed
10955 * below to point to the new stopper.
10957 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
10960 * Clear the ADV_SCSI_REQ_Q done flag.
10962 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
10964 req_size = sizeof(ADV_SCSI_REQ_Q);
10965 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
10966 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
10968 BUG_ON(req_paddr & 31);
10969 BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
10971 /* Wait for assertion before making little-endian */
10972 req_paddr = cpu_to_le32(req_paddr);
10974 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
10975 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
10976 scsiq->scsiq_rptr = req_paddr;
10978 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
10980 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
10981 * order during initialization.
10983 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
10986 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
10987 * the microcode. The newly allocated stopper will become the new
10988 * stopper.
10990 asc_dvc->icq_sp->areq_vpa = req_paddr;
10993 * Set the 'next_vpa' pointer for the old stopper to be the
10994 * physical address of the new stopper. The RISC can only
10995 * follow physical addresses.
10997 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
11000 * Set the host adapter stopper pointer to point to the new carrier.
11002 asc_dvc->icq_sp = new_carrp;
11004 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
11005 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
11007 * Tickle the RISC to tell it to read its Command Queue Head pointer.
11009 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
11010 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
11012 * Clear the tickle value. In the ASC-3550 the RISC flag
11013 * command 'clr_tickle_a' does not work unless the host
11014 * value is cleared.
11016 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
11017 ADV_TICKLE_NOP);
11019 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
11021 * Notify the RISC a carrier is ready by writing the physical
11022 * address of the new carrier stopper to the COMMA register.
11024 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
11025 le32_to_cpu(new_carrp->carr_pa));
11028 return ADV_SUCCESS;
11032 * Execute a single 'Scsi_Cmnd'.
11034 * The function 'done' is called when the request has been completed.
11036 * Scsi_Cmnd:
11038 * host - board controlling device
11039 * device - device to send command
11040 * target - target of device
11041 * lun - lun of device
11042 * cmd_len - length of SCSI CDB
11043 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
11044 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
11046 * if (use_sg == 0) {
11047 * request_buffer - buffer address for request
11048 * request_bufflen - length of request buffer
11049 * } else {
11050 * request_buffer - pointer to scatterlist structure
11053 * sense_buffer - sense command buffer
11055 * result (4 bytes of an int):
11056 * Byte Meaning
11057 * 0 SCSI Status Byte Code
11058 * 1 SCSI One Byte Message Code
11059 * 2 Host Error Code
11060 * 3 Mid-Level Error Code
11062 * host driver fields:
11063 * SCp - Scsi_Pointer used for command processing status
11064 * scsi_done - used to save caller's done function
11065 * host_scribble - used for pointer to another struct scsi_cmnd
11067 * If this function returns ASC_NOERROR the request will be completed
11068 * from the interrupt handler.
11070 * If this function returns ASC_ERROR the host error code has been set,
11071 * and the called must call asc_scsi_done.
11073 * If ASC_BUSY is returned the request will be returned to the midlayer
11074 * and re-tried later.
11076 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
11078 int ret, err_code;
11079 struct asc_board *boardp = shost_priv(scp->device->host);
11081 ASC_DBG(1, "scp 0x%p\n", scp);
11083 if (ASC_NARROW_BOARD(boardp)) {
11084 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
11085 struct asc_scsi_q asc_scsi_q;
11087 /* asc_build_req() can not return ASC_BUSY. */
11088 ret = asc_build_req(boardp, scp, &asc_scsi_q);
11089 if (ret == ASC_ERROR) {
11090 ASC_STATS(scp->device->host, build_error);
11091 return ASC_ERROR;
11094 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
11095 kfree(asc_scsi_q.sg_head);
11096 err_code = asc_dvc->err_code;
11097 } else {
11098 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
11099 ADV_SCSI_REQ_Q *adv_scsiqp;
11101 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
11102 case ASC_NOERROR:
11103 ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
11104 break;
11105 case ASC_BUSY:
11106 ASC_DBG(1, "adv_build_req ASC_BUSY\n");
11108 * The asc_stats fields 'adv_build_noreq' and
11109 * 'adv_build_nosg' count wide board busy conditions.
11110 * They are updated in adv_build_req and
11111 * adv_get_sglist, respectively.
11113 return ASC_BUSY;
11114 case ASC_ERROR:
11115 default:
11116 ASC_DBG(1, "adv_build_req ASC_ERROR\n");
11117 ASC_STATS(scp->device->host, build_error);
11118 return ASC_ERROR;
11121 ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
11122 err_code = adv_dvc->err_code;
11125 switch (ret) {
11126 case ASC_NOERROR:
11127 ASC_STATS(scp->device->host, exe_noerror);
11129 * Increment monotonically increasing per device
11130 * successful request counter. Wrapping doesn't matter.
11132 boardp->reqcnt[scp->device->id]++;
11133 ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
11134 break;
11135 case ASC_BUSY:
11136 ASC_STATS(scp->device->host, exe_busy);
11137 break;
11138 case ASC_ERROR:
11139 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
11140 "err_code 0x%x\n", err_code);
11141 ASC_STATS(scp->device->host, exe_error);
11142 scp->result = HOST_BYTE(DID_ERROR);
11143 break;
11144 default:
11145 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
11146 "err_code 0x%x\n", err_code);
11147 ASC_STATS(scp->device->host, exe_unknown);
11148 scp->result = HOST_BYTE(DID_ERROR);
11149 break;
11152 ASC_DBG(1, "end\n");
11153 return ret;
11157 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11159 * This function always returns 0. Command return status is saved
11160 * in the 'scp' result field.
11162 static int
11163 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11165 struct Scsi_Host *shost = scp->device->host;
11166 int asc_res, result = 0;
11168 ASC_STATS(shost, queuecommand);
11169 scp->scsi_done = done;
11171 asc_res = asc_execute_scsi_cmnd(scp);
11173 switch (asc_res) {
11174 case ASC_NOERROR:
11175 break;
11176 case ASC_BUSY:
11177 result = SCSI_MLQUEUE_HOST_BUSY;
11178 break;
11179 case ASC_ERROR:
11180 default:
11181 asc_scsi_done(scp);
11182 break;
11185 return result;
11188 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11190 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11191 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
11192 return inpw(eisa_cfg_iop);
11196 * Return the BIOS address of the adapter at the specified
11197 * I/O port and with the specified bus type.
11199 static unsigned short __devinit
11200 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11202 unsigned short cfg_lsw;
11203 unsigned short bios_addr;
11206 * The PCI BIOS is re-located by the motherboard BIOS. Because
11207 * of this the driver can not determine where a PCI BIOS is
11208 * loaded and executes.
11210 if (bus_type & ASC_IS_PCI)
11211 return 0;
11213 if ((bus_type & ASC_IS_EISA) != 0) {
11214 cfg_lsw = AscGetEisaChipCfg(iop_base);
11215 cfg_lsw &= 0x000F;
11216 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
11217 return bios_addr;
11220 cfg_lsw = AscGetChipCfgLsw(iop_base);
11223 * ISA PnP uses the top bit as the 32K BIOS flag
11225 if (bus_type == ASC_IS_ISAPNP)
11226 cfg_lsw &= 0x7FFF;
11227 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
11228 return bios_addr;
11231 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11233 ushort cfg_lsw;
11235 if (AscGetChipScsiID(iop_base) == new_host_id) {
11236 return (new_host_id);
11238 cfg_lsw = AscGetChipCfgLsw(iop_base);
11239 cfg_lsw &= 0xF8FF;
11240 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
11241 AscSetChipCfgLsw(iop_base, cfg_lsw);
11242 return (AscGetChipScsiID(iop_base));
11245 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11247 unsigned char sc;
11249 AscSetBank(iop_base, 1);
11250 sc = inp(iop_base + IOP_REG_SC);
11251 AscSetBank(iop_base, 0);
11252 return sc;
11255 static unsigned char __devinit
11256 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11258 if (bus_type & ASC_IS_EISA) {
11259 PortAddr eisa_iop;
11260 unsigned char revision;
11261 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11262 (PortAddr) ASC_EISA_REV_IOP_MASK;
11263 revision = inp(eisa_iop);
11264 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
11266 return AscGetChipVerNo(iop_base);
11269 #ifdef CONFIG_ISA
11270 static void __devinit AscEnableIsaDma(uchar dma_channel)
11272 if (dma_channel < 4) {
11273 outp(0x000B, (ushort)(0xC0 | dma_channel));
11274 outp(0x000A, dma_channel);
11275 } else if (dma_channel < 8) {
11276 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
11277 outp(0x00D4, (ushort)(dma_channel - 4));
11280 #endif /* CONFIG_ISA */
11282 static int AscStopQueueExe(PortAddr iop_base)
11284 int count = 0;
11286 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11287 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11288 ASC_STOP_REQ_RISC_STOP);
11289 do {
11290 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11291 ASC_STOP_ACK_RISC_STOP) {
11292 return (1);
11294 mdelay(100);
11295 } while (count++ < 20);
11297 return (0);
11300 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11302 if (bus_type & ASC_IS_ISA)
11303 return ASC_MAX_ISA_DMA_COUNT;
11304 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11305 return ASC_MAX_VL_DMA_COUNT;
11306 return ASC_MAX_PCI_DMA_COUNT;
11309 #ifdef CONFIG_ISA
11310 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
11312 ushort channel;
11314 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11315 if (channel == 0x03)
11316 return (0);
11317 else if (channel == 0x00)
11318 return (7);
11319 return (channel + 4);
11322 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11324 ushort cfg_lsw;
11325 uchar value;
11327 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11328 if (dma_channel == 7)
11329 value = 0x00;
11330 else
11331 value = dma_channel - 4;
11332 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11333 cfg_lsw |= value;
11334 AscSetChipCfgLsw(iop_base, cfg_lsw);
11335 return (AscGetIsaDmaChannel(iop_base));
11337 return 0;
11340 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11342 uchar speed_value;
11344 AscSetBank(iop_base, 1);
11345 speed_value = AscReadChipDmaSpeed(iop_base);
11346 speed_value &= 0x07;
11347 AscSetBank(iop_base, 0);
11348 return speed_value;
11351 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11353 speed_value &= 0x07;
11354 AscSetBank(iop_base, 1);
11355 AscWriteChipDmaSpeed(iop_base, speed_value);
11356 AscSetBank(iop_base, 0);
11357 return AscGetIsaDmaSpeed(iop_base);
11359 #endif /* CONFIG_ISA */
11361 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11363 int i;
11364 PortAddr iop_base;
11365 ushort warn_code;
11366 uchar chip_version;
11368 iop_base = asc_dvc->iop_base;
11369 warn_code = 0;
11370 asc_dvc->err_code = 0;
11371 if ((asc_dvc->bus_type &
11372 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
11373 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
11375 AscSetChipControl(iop_base, CC_HALT);
11376 AscSetChipStatus(iop_base, 0);
11377 asc_dvc->bug_fix_cntl = 0;
11378 asc_dvc->pci_fix_asyn_xfer = 0;
11379 asc_dvc->pci_fix_asyn_xfer_always = 0;
11380 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
11381 asc_dvc->sdtr_done = 0;
11382 asc_dvc->cur_total_qng = 0;
11383 asc_dvc->is_in_int = 0;
11384 asc_dvc->in_critical_cnt = 0;
11385 asc_dvc->last_q_shortage = 0;
11386 asc_dvc->use_tagged_qng = 0;
11387 asc_dvc->no_scam = 0;
11388 asc_dvc->unit_not_ready = 0;
11389 asc_dvc->queue_full_or_busy = 0;
11390 asc_dvc->redo_scam = 0;
11391 asc_dvc->res2 = 0;
11392 asc_dvc->min_sdtr_index = 0;
11393 asc_dvc->cfg->can_tagged_qng = 0;
11394 asc_dvc->cfg->cmd_qng_enabled = 0;
11395 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
11396 asc_dvc->init_sdtr = 0;
11397 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
11398 asc_dvc->scsi_reset_wait = 3;
11399 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
11400 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
11401 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
11402 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
11403 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
11404 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11405 asc_dvc->cfg->chip_version = chip_version;
11406 asc_dvc->sdtr_period_tbl = asc_syn_xfer_period;
11407 asc_dvc->max_sdtr_index = 7;
11408 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
11409 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
11410 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
11411 asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period;
11412 asc_dvc->max_sdtr_index = 15;
11413 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
11414 AscSetExtraControl(iop_base,
11415 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11416 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
11417 AscSetExtraControl(iop_base,
11418 (SEC_ACTIVE_NEGATE |
11419 SEC_ENABLE_FILTER));
11422 if (asc_dvc->bus_type == ASC_IS_PCI) {
11423 AscSetExtraControl(iop_base,
11424 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11427 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
11428 #ifdef CONFIG_ISA
11429 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
11430 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
11431 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
11432 asc_dvc->bus_type = ASC_IS_ISAPNP;
11434 asc_dvc->cfg->isa_dma_channel =
11435 (uchar)AscGetIsaDmaChannel(iop_base);
11437 #endif /* CONFIG_ISA */
11438 for (i = 0; i <= ASC_MAX_TID; i++) {
11439 asc_dvc->cur_dvc_qng[i] = 0;
11440 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
11441 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
11442 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
11443 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
11445 return warn_code;
11448 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11450 int retry;
11452 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
11453 unsigned char read_back;
11454 AscSetChipEEPCmd(iop_base, cmd_reg);
11455 mdelay(1);
11456 read_back = AscGetChipEEPCmd(iop_base);
11457 if (read_back == cmd_reg)
11458 return 1;
11460 return 0;
11463 static void __devinit AscWaitEEPRead(void)
11465 mdelay(1);
11468 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
11470 ushort read_wval;
11471 uchar cmd_reg;
11473 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11474 AscWaitEEPRead();
11475 cmd_reg = addr | ASC_EEP_CMD_READ;
11476 AscWriteEEPCmdReg(iop_base, cmd_reg);
11477 AscWaitEEPRead();
11478 read_wval = AscGetChipEEPData(iop_base);
11479 AscWaitEEPRead();
11480 return read_wval;
11483 static ushort __devinit
11484 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11486 ushort wval;
11487 ushort sum;
11488 ushort *wbuf;
11489 int cfg_beg;
11490 int cfg_end;
11491 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11492 int s_addr;
11494 wbuf = (ushort *)cfg_buf;
11495 sum = 0;
11496 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11497 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11498 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11499 sum += *wbuf;
11501 if (bus_type & ASC_IS_VL) {
11502 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11503 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11504 } else {
11505 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11506 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11508 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11509 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11510 if (s_addr <= uchar_end_in_config) {
11512 * Swap all char fields - must unswap bytes already swapped
11513 * by AscReadEEPWord().
11515 *wbuf = le16_to_cpu(wval);
11516 } else {
11517 /* Don't swap word field at the end - cntl field. */
11518 *wbuf = wval;
11520 sum += wval; /* Checksum treats all EEPROM data as words. */
11523 * Read the checksum word which will be compared against 'sum'
11524 * by the caller. Word field already swapped.
11526 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11527 return sum;
11530 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11532 PortAddr iop_base;
11533 ushort q_addr;
11534 ushort saved_word;
11535 int sta;
11537 iop_base = asc_dvc->iop_base;
11538 sta = 0;
11539 q_addr = ASC_QNO_TO_QADDR(241);
11540 saved_word = AscReadLramWord(iop_base, q_addr);
11541 AscSetChipLramAddr(iop_base, q_addr);
11542 AscSetChipLramData(iop_base, 0x55AA);
11543 mdelay(10);
11544 AscSetChipLramAddr(iop_base, q_addr);
11545 if (AscGetChipLramData(iop_base) == 0x55AA) {
11546 sta = 1;
11547 AscWriteLramWord(iop_base, q_addr, saved_word);
11549 return (sta);
11552 static void __devinit AscWaitEEPWrite(void)
11554 mdelay(20);
11557 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11559 ushort read_back;
11560 int retry;
11562 retry = 0;
11563 while (TRUE) {
11564 AscSetChipEEPData(iop_base, data_reg);
11565 mdelay(1);
11566 read_back = AscGetChipEEPData(iop_base);
11567 if (read_back == data_reg) {
11568 return (1);
11570 if (retry++ > ASC_EEP_MAX_RETRY) {
11571 return (0);
11576 static ushort __devinit
11577 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11579 ushort read_wval;
11581 read_wval = AscReadEEPWord(iop_base, addr);
11582 if (read_wval != word_val) {
11583 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11584 AscWaitEEPRead();
11585 AscWriteEEPDataReg(iop_base, word_val);
11586 AscWaitEEPRead();
11587 AscWriteEEPCmdReg(iop_base,
11588 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11589 AscWaitEEPWrite();
11590 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11591 AscWaitEEPRead();
11592 return (AscReadEEPWord(iop_base, addr));
11594 return (read_wval);
11597 static int __devinit
11598 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11600 int n_error;
11601 ushort *wbuf;
11602 ushort word;
11603 ushort sum;
11604 int s_addr;
11605 int cfg_beg;
11606 int cfg_end;
11607 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11609 wbuf = (ushort *)cfg_buf;
11610 n_error = 0;
11611 sum = 0;
11612 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11613 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11614 sum += *wbuf;
11615 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11616 n_error++;
11619 if (bus_type & ASC_IS_VL) {
11620 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11621 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11622 } else {
11623 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11624 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11626 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11627 if (s_addr <= uchar_end_in_config) {
11629 * This is a char field. Swap char fields before they are
11630 * swapped again by AscWriteEEPWord().
11632 word = cpu_to_le16(*wbuf);
11633 if (word !=
11634 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11635 n_error++;
11637 } else {
11638 /* Don't swap word field at the end - cntl field. */
11639 if (*wbuf !=
11640 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11641 n_error++;
11644 sum += *wbuf; /* Checksum calculated from word values. */
11646 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11647 *wbuf = sum;
11648 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11649 n_error++;
11652 /* Read EEPROM back again. */
11653 wbuf = (ushort *)cfg_buf;
11655 * Read two config words; Byte-swapping done by AscReadEEPWord().
11657 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11658 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11659 n_error++;
11662 if (bus_type & ASC_IS_VL) {
11663 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11664 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11665 } else {
11666 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11667 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11669 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11670 if (s_addr <= uchar_end_in_config) {
11672 * Swap all char fields. Must unswap bytes already swapped
11673 * by AscReadEEPWord().
11675 word =
11676 le16_to_cpu(AscReadEEPWord
11677 (iop_base, (uchar)s_addr));
11678 } else {
11679 /* Don't swap word field at the end - cntl field. */
11680 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11682 if (*wbuf != word) {
11683 n_error++;
11686 /* Read checksum; Byte swapping not needed. */
11687 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11688 n_error++;
11690 return n_error;
11693 static int __devinit
11694 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11696 int retry;
11697 int n_error;
11699 retry = 0;
11700 while (TRUE) {
11701 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11702 bus_type)) == 0) {
11703 break;
11705 if (++retry > ASC_EEP_MAX_RETRY) {
11706 break;
11709 return n_error;
11712 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
11714 ASCEEP_CONFIG eep_config_buf;
11715 ASCEEP_CONFIG *eep_config;
11716 PortAddr iop_base;
11717 ushort chksum;
11718 ushort warn_code;
11719 ushort cfg_msw, cfg_lsw;
11720 int i;
11721 int write_eep = 0;
11723 iop_base = asc_dvc->iop_base;
11724 warn_code = 0;
11725 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
11726 AscStopQueueExe(iop_base);
11727 if ((AscStopChip(iop_base) == FALSE) ||
11728 (AscGetChipScsiCtrl(iop_base) != 0)) {
11729 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
11730 AscResetChipAndScsiBus(asc_dvc);
11731 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
11733 if (AscIsChipHalted(iop_base) == FALSE) {
11734 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11735 return (warn_code);
11737 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11738 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11739 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11740 return (warn_code);
11742 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
11743 cfg_msw = AscGetChipCfgMsw(iop_base);
11744 cfg_lsw = AscGetChipCfgLsw(iop_base);
11745 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11746 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11747 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11748 AscSetChipCfgMsw(iop_base, cfg_msw);
11750 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
11751 ASC_DBG(1, "chksum 0x%x\n", chksum);
11752 if (chksum == 0) {
11753 chksum = 0xaa55;
11755 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11756 warn_code |= ASC_WARN_AUTO_CONFIG;
11757 if (asc_dvc->cfg->chip_version == 3) {
11758 if (eep_config->cfg_lsw != cfg_lsw) {
11759 warn_code |= ASC_WARN_EEPROM_RECOVER;
11760 eep_config->cfg_lsw =
11761 AscGetChipCfgLsw(iop_base);
11763 if (eep_config->cfg_msw != cfg_msw) {
11764 warn_code |= ASC_WARN_EEPROM_RECOVER;
11765 eep_config->cfg_msw =
11766 AscGetChipCfgMsw(iop_base);
11770 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11771 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
11772 ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
11773 if (chksum != eep_config->chksum) {
11774 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
11775 ASC_CHIP_VER_PCI_ULTRA_3050) {
11776 ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
11777 eep_config->init_sdtr = 0xFF;
11778 eep_config->disc_enable = 0xFF;
11779 eep_config->start_motor = 0xFF;
11780 eep_config->use_cmd_qng = 0;
11781 eep_config->max_total_qng = 0xF0;
11782 eep_config->max_tag_qng = 0x20;
11783 eep_config->cntl = 0xBFFF;
11784 ASC_EEP_SET_CHIP_ID(eep_config, 7);
11785 eep_config->no_scam = 0;
11786 eep_config->adapter_info[0] = 0;
11787 eep_config->adapter_info[1] = 0;
11788 eep_config->adapter_info[2] = 0;
11789 eep_config->adapter_info[3] = 0;
11790 eep_config->adapter_info[4] = 0;
11791 /* Indicate EEPROM-less board. */
11792 eep_config->adapter_info[5] = 0xBB;
11793 } else {
11794 ASC_PRINT
11795 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
11796 write_eep = 1;
11797 warn_code |= ASC_WARN_EEPROM_CHKSUM;
11800 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
11801 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
11802 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
11803 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
11804 asc_dvc->start_motor = eep_config->start_motor;
11805 asc_dvc->dvc_cntl = eep_config->cntl;
11806 asc_dvc->no_scam = eep_config->no_scam;
11807 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
11808 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
11809 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
11810 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
11811 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
11812 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
11813 if (!AscTestExternalLram(asc_dvc)) {
11814 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
11815 ASC_IS_PCI_ULTRA)) {
11816 eep_config->max_total_qng =
11817 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
11818 eep_config->max_tag_qng =
11819 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
11820 } else {
11821 eep_config->cfg_msw |= 0x0800;
11822 cfg_msw |= 0x0800;
11823 AscSetChipCfgMsw(iop_base, cfg_msw);
11824 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
11825 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
11827 } else {
11829 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11830 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11832 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11833 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11835 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11836 eep_config->max_tag_qng = eep_config->max_total_qng;
11838 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
11839 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
11841 asc_dvc->max_total_qng = eep_config->max_total_qng;
11842 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
11843 eep_config->use_cmd_qng) {
11844 eep_config->disc_enable = eep_config->use_cmd_qng;
11845 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11847 ASC_EEP_SET_CHIP_ID(eep_config,
11848 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
11849 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
11850 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
11851 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
11852 asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
11855 for (i = 0; i <= ASC_MAX_TID; i++) {
11856 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
11857 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
11858 asc_dvc->cfg->sdtr_period_offset[i] =
11859 (uchar)(ASC_DEF_SDTR_OFFSET |
11860 (asc_dvc->min_sdtr_index << 4));
11862 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
11863 if (write_eep) {
11864 if ((i = AscSetEEPConfig(iop_base, eep_config,
11865 asc_dvc->bus_type)) != 0) {
11866 ASC_PRINT1
11867 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
11869 } else {
11870 ASC_PRINT
11871 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
11874 return (warn_code);
11877 static int __devinit AscInitGetConfig(struct Scsi_Host *shost)
11879 struct asc_board *board = shost_priv(shost);
11880 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
11881 unsigned short warn_code = 0;
11883 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11884 if (asc_dvc->err_code != 0)
11885 return asc_dvc->err_code;
11887 if (AscFindSignature(asc_dvc->iop_base)) {
11888 warn_code |= AscInitAscDvcVar(asc_dvc);
11889 warn_code |= AscInitFromEEP(asc_dvc);
11890 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11891 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
11892 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11893 } else {
11894 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11897 switch (warn_code) {
11898 case 0: /* No error */
11899 break;
11900 case ASC_WARN_IO_PORT_ROTATE:
11901 shost_printk(KERN_WARNING, shost, "I/O port address "
11902 "modified\n");
11903 break;
11904 case ASC_WARN_AUTO_CONFIG:
11905 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
11906 "enabled\n");
11907 break;
11908 case ASC_WARN_EEPROM_CHKSUM:
11909 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
11910 break;
11911 case ASC_WARN_IRQ_MODIFIED:
11912 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
11913 break;
11914 case ASC_WARN_CMD_QNG_CONFLICT:
11915 shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o "
11916 "disconnects\n");
11917 break;
11918 default:
11919 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
11920 warn_code);
11921 break;
11924 if (asc_dvc->err_code != 0)
11925 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
11926 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
11928 return asc_dvc->err_code;
11931 static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
11933 struct asc_board *board = shost_priv(shost);
11934 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
11935 PortAddr iop_base = asc_dvc->iop_base;
11936 unsigned short cfg_msw;
11937 unsigned short warn_code = 0;
11939 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11940 if (asc_dvc->err_code != 0)
11941 return asc_dvc->err_code;
11942 if (!AscFindSignature(asc_dvc->iop_base)) {
11943 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11944 return asc_dvc->err_code;
11947 cfg_msw = AscGetChipCfgMsw(iop_base);
11948 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11949 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11950 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11951 AscSetChipCfgMsw(iop_base, cfg_msw);
11953 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
11954 asc_dvc->cfg->cmd_qng_enabled) {
11955 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
11956 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11958 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11959 warn_code |= ASC_WARN_AUTO_CONFIG;
11961 #ifdef CONFIG_PCI
11962 if (asc_dvc->bus_type & ASC_IS_PCI) {
11963 cfg_msw &= 0xFFC0;
11964 AscSetChipCfgMsw(iop_base, cfg_msw);
11965 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
11966 } else {
11967 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
11968 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
11969 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
11970 asc_dvc->bug_fix_cntl |=
11971 ASC_BUG_FIX_ASYN_USE_SYN;
11974 } else
11975 #endif /* CONFIG_PCI */
11976 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
11977 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
11978 == ASC_CHIP_VER_ASYN_BUG) {
11979 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
11982 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
11983 asc_dvc->cfg->chip_scsi_id) {
11984 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
11986 #ifdef CONFIG_ISA
11987 if (asc_dvc->bus_type & ASC_IS_ISA) {
11988 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
11989 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
11991 #endif /* CONFIG_ISA */
11993 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11995 switch (warn_code) {
11996 case 0: /* No error. */
11997 break;
11998 case ASC_WARN_IO_PORT_ROTATE:
11999 shost_printk(KERN_WARNING, shost, "I/O port address "
12000 "modified\n");
12001 break;
12002 case ASC_WARN_AUTO_CONFIG:
12003 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
12004 "enabled\n");
12005 break;
12006 case ASC_WARN_EEPROM_CHKSUM:
12007 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
12008 break;
12009 case ASC_WARN_IRQ_MODIFIED:
12010 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
12011 break;
12012 case ASC_WARN_CMD_QNG_CONFLICT:
12013 shost_printk(KERN_WARNING, shost, "tag queuing w/o "
12014 "disconnects\n");
12015 break;
12016 default:
12017 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
12018 warn_code);
12019 break;
12022 if (asc_dvc->err_code != 0)
12023 shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
12024 "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
12026 return asc_dvc->err_code;
12030 * EEPROM Configuration.
12032 * All drivers should use this structure to set the default EEPROM
12033 * configuration. The BIOS now uses this structure when it is built.
12034 * Additional structure information can be found in a_condor.h where
12035 * the structure is defined.
12037 * The *_Field_IsChar structs are needed to correct for endianness.
12038 * These values are read from the board 16 bits at a time directly
12039 * into the structs. Because some fields are char, the values will be
12040 * in the wrong order. The *_Field_IsChar tells when to flip the
12041 * bytes. Data read and written to PCI memory is automatically swapped
12042 * on big-endian platforms so char fields read as words are actually being
12043 * unswapped on big-endian platforms.
12045 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
12046 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
12047 0x0000, /* cfg_msw */
12048 0xFFFF, /* disc_enable */
12049 0xFFFF, /* wdtr_able */
12050 0xFFFF, /* sdtr_able */
12051 0xFFFF, /* start_motor */
12052 0xFFFF, /* tagqng_able */
12053 0xFFFF, /* bios_scan */
12054 0, /* scam_tolerant */
12055 7, /* adapter_scsi_id */
12056 0, /* bios_boot_delay */
12057 3, /* scsi_reset_delay */
12058 0, /* bios_id_lun */
12059 0, /* termination */
12060 0, /* reserved1 */
12061 0xFFE7, /* bios_ctrl */
12062 0xFFFF, /* ultra_able */
12063 0, /* reserved2 */
12064 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
12065 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12066 0, /* dvc_cntl */
12067 0, /* bug_fix */
12068 0, /* serial_number_word1 */
12069 0, /* serial_number_word2 */
12070 0, /* serial_number_word3 */
12071 0, /* check_sum */
12072 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12073 , /* oem_name[16] */
12074 0, /* dvc_err_code */
12075 0, /* adv_err_code */
12076 0, /* adv_err_addr */
12077 0, /* saved_dvc_err_code */
12078 0, /* saved_adv_err_code */
12079 0, /* saved_adv_err_addr */
12080 0 /* num_of_err */
12083 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
12084 0, /* cfg_lsw */
12085 0, /* cfg_msw */
12086 0, /* -disc_enable */
12087 0, /* wdtr_able */
12088 0, /* sdtr_able */
12089 0, /* start_motor */
12090 0, /* tagqng_able */
12091 0, /* bios_scan */
12092 0, /* scam_tolerant */
12093 1, /* adapter_scsi_id */
12094 1, /* bios_boot_delay */
12095 1, /* scsi_reset_delay */
12096 1, /* bios_id_lun */
12097 1, /* termination */
12098 1, /* reserved1 */
12099 0, /* bios_ctrl */
12100 0, /* ultra_able */
12101 0, /* reserved2 */
12102 1, /* max_host_qng */
12103 1, /* max_dvc_qng */
12104 0, /* dvc_cntl */
12105 0, /* bug_fix */
12106 0, /* serial_number_word1 */
12107 0, /* serial_number_word2 */
12108 0, /* serial_number_word3 */
12109 0, /* check_sum */
12110 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12111 , /* oem_name[16] */
12112 0, /* dvc_err_code */
12113 0, /* adv_err_code */
12114 0, /* adv_err_addr */
12115 0, /* saved_dvc_err_code */
12116 0, /* saved_adv_err_code */
12117 0, /* saved_adv_err_addr */
12118 0 /* num_of_err */
12121 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
12122 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12123 0x0000, /* 01 cfg_msw */
12124 0xFFFF, /* 02 disc_enable */
12125 0xFFFF, /* 03 wdtr_able */
12126 0x4444, /* 04 sdtr_speed1 */
12127 0xFFFF, /* 05 start_motor */
12128 0xFFFF, /* 06 tagqng_able */
12129 0xFFFF, /* 07 bios_scan */
12130 0, /* 08 scam_tolerant */
12131 7, /* 09 adapter_scsi_id */
12132 0, /* bios_boot_delay */
12133 3, /* 10 scsi_reset_delay */
12134 0, /* bios_id_lun */
12135 0, /* 11 termination_se */
12136 0, /* termination_lvd */
12137 0xFFE7, /* 12 bios_ctrl */
12138 0x4444, /* 13 sdtr_speed2 */
12139 0x4444, /* 14 sdtr_speed3 */
12140 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12141 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12142 0, /* 16 dvc_cntl */
12143 0x4444, /* 17 sdtr_speed4 */
12144 0, /* 18 serial_number_word1 */
12145 0, /* 19 serial_number_word2 */
12146 0, /* 20 serial_number_word3 */
12147 0, /* 21 check_sum */
12148 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12149 , /* 22-29 oem_name[16] */
12150 0, /* 30 dvc_err_code */
12151 0, /* 31 adv_err_code */
12152 0, /* 32 adv_err_addr */
12153 0, /* 33 saved_dvc_err_code */
12154 0, /* 34 saved_adv_err_code */
12155 0, /* 35 saved_adv_err_addr */
12156 0, /* 36 reserved */
12157 0, /* 37 reserved */
12158 0, /* 38 reserved */
12159 0, /* 39 reserved */
12160 0, /* 40 reserved */
12161 0, /* 41 reserved */
12162 0, /* 42 reserved */
12163 0, /* 43 reserved */
12164 0, /* 44 reserved */
12165 0, /* 45 reserved */
12166 0, /* 46 reserved */
12167 0, /* 47 reserved */
12168 0, /* 48 reserved */
12169 0, /* 49 reserved */
12170 0, /* 50 reserved */
12171 0, /* 51 reserved */
12172 0, /* 52 reserved */
12173 0, /* 53 reserved */
12174 0, /* 54 reserved */
12175 0, /* 55 reserved */
12176 0, /* 56 cisptr_lsw */
12177 0, /* 57 cisprt_msw */
12178 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12179 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
12180 0, /* 60 reserved */
12181 0, /* 61 reserved */
12182 0, /* 62 reserved */
12183 0 /* 63 reserved */
12186 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12187 0, /* 00 cfg_lsw */
12188 0, /* 01 cfg_msw */
12189 0, /* 02 disc_enable */
12190 0, /* 03 wdtr_able */
12191 0, /* 04 sdtr_speed1 */
12192 0, /* 05 start_motor */
12193 0, /* 06 tagqng_able */
12194 0, /* 07 bios_scan */
12195 0, /* 08 scam_tolerant */
12196 1, /* 09 adapter_scsi_id */
12197 1, /* bios_boot_delay */
12198 1, /* 10 scsi_reset_delay */
12199 1, /* bios_id_lun */
12200 1, /* 11 termination_se */
12201 1, /* termination_lvd */
12202 0, /* 12 bios_ctrl */
12203 0, /* 13 sdtr_speed2 */
12204 0, /* 14 sdtr_speed3 */
12205 1, /* 15 max_host_qng */
12206 1, /* max_dvc_qng */
12207 0, /* 16 dvc_cntl */
12208 0, /* 17 sdtr_speed4 */
12209 0, /* 18 serial_number_word1 */
12210 0, /* 19 serial_number_word2 */
12211 0, /* 20 serial_number_word3 */
12212 0, /* 21 check_sum */
12213 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12214 , /* 22-29 oem_name[16] */
12215 0, /* 30 dvc_err_code */
12216 0, /* 31 adv_err_code */
12217 0, /* 32 adv_err_addr */
12218 0, /* 33 saved_dvc_err_code */
12219 0, /* 34 saved_adv_err_code */
12220 0, /* 35 saved_adv_err_addr */
12221 0, /* 36 reserved */
12222 0, /* 37 reserved */
12223 0, /* 38 reserved */
12224 0, /* 39 reserved */
12225 0, /* 40 reserved */
12226 0, /* 41 reserved */
12227 0, /* 42 reserved */
12228 0, /* 43 reserved */
12229 0, /* 44 reserved */
12230 0, /* 45 reserved */
12231 0, /* 46 reserved */
12232 0, /* 47 reserved */
12233 0, /* 48 reserved */
12234 0, /* 49 reserved */
12235 0, /* 50 reserved */
12236 0, /* 51 reserved */
12237 0, /* 52 reserved */
12238 0, /* 53 reserved */
12239 0, /* 54 reserved */
12240 0, /* 55 reserved */
12241 0, /* 56 cisptr_lsw */
12242 0, /* 57 cisprt_msw */
12243 0, /* 58 subsysvid */
12244 0, /* 59 subsysid */
12245 0, /* 60 reserved */
12246 0, /* 61 reserved */
12247 0, /* 62 reserved */
12248 0 /* 63 reserved */
12251 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12252 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12253 0x0000, /* 01 cfg_msw */
12254 0xFFFF, /* 02 disc_enable */
12255 0xFFFF, /* 03 wdtr_able */
12256 0x5555, /* 04 sdtr_speed1 */
12257 0xFFFF, /* 05 start_motor */
12258 0xFFFF, /* 06 tagqng_able */
12259 0xFFFF, /* 07 bios_scan */
12260 0, /* 08 scam_tolerant */
12261 7, /* 09 adapter_scsi_id */
12262 0, /* bios_boot_delay */
12263 3, /* 10 scsi_reset_delay */
12264 0, /* bios_id_lun */
12265 0, /* 11 termination_se */
12266 0, /* termination_lvd */
12267 0xFFE7, /* 12 bios_ctrl */
12268 0x5555, /* 13 sdtr_speed2 */
12269 0x5555, /* 14 sdtr_speed3 */
12270 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12271 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12272 0, /* 16 dvc_cntl */
12273 0x5555, /* 17 sdtr_speed4 */
12274 0, /* 18 serial_number_word1 */
12275 0, /* 19 serial_number_word2 */
12276 0, /* 20 serial_number_word3 */
12277 0, /* 21 check_sum */
12278 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12279 , /* 22-29 oem_name[16] */
12280 0, /* 30 dvc_err_code */
12281 0, /* 31 adv_err_code */
12282 0, /* 32 adv_err_addr */
12283 0, /* 33 saved_dvc_err_code */
12284 0, /* 34 saved_adv_err_code */
12285 0, /* 35 saved_adv_err_addr */
12286 0, /* 36 reserved */
12287 0, /* 37 reserved */
12288 0, /* 38 reserved */
12289 0, /* 39 reserved */
12290 0, /* 40 reserved */
12291 0, /* 41 reserved */
12292 0, /* 42 reserved */
12293 0, /* 43 reserved */
12294 0, /* 44 reserved */
12295 0, /* 45 reserved */
12296 0, /* 46 reserved */
12297 0, /* 47 reserved */
12298 0, /* 48 reserved */
12299 0, /* 49 reserved */
12300 0, /* 50 reserved */
12301 0, /* 51 reserved */
12302 0, /* 52 reserved */
12303 0, /* 53 reserved */
12304 0, /* 54 reserved */
12305 0, /* 55 reserved */
12306 0, /* 56 cisptr_lsw */
12307 0, /* 57 cisprt_msw */
12308 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12309 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
12310 0, /* 60 reserved */
12311 0, /* 61 reserved */
12312 0, /* 62 reserved */
12313 0 /* 63 reserved */
12316 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12317 0, /* 00 cfg_lsw */
12318 0, /* 01 cfg_msw */
12319 0, /* 02 disc_enable */
12320 0, /* 03 wdtr_able */
12321 0, /* 04 sdtr_speed1 */
12322 0, /* 05 start_motor */
12323 0, /* 06 tagqng_able */
12324 0, /* 07 bios_scan */
12325 0, /* 08 scam_tolerant */
12326 1, /* 09 adapter_scsi_id */
12327 1, /* bios_boot_delay */
12328 1, /* 10 scsi_reset_delay */
12329 1, /* bios_id_lun */
12330 1, /* 11 termination_se */
12331 1, /* termination_lvd */
12332 0, /* 12 bios_ctrl */
12333 0, /* 13 sdtr_speed2 */
12334 0, /* 14 sdtr_speed3 */
12335 1, /* 15 max_host_qng */
12336 1, /* max_dvc_qng */
12337 0, /* 16 dvc_cntl */
12338 0, /* 17 sdtr_speed4 */
12339 0, /* 18 serial_number_word1 */
12340 0, /* 19 serial_number_word2 */
12341 0, /* 20 serial_number_word3 */
12342 0, /* 21 check_sum */
12343 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12344 , /* 22-29 oem_name[16] */
12345 0, /* 30 dvc_err_code */
12346 0, /* 31 adv_err_code */
12347 0, /* 32 adv_err_addr */
12348 0, /* 33 saved_dvc_err_code */
12349 0, /* 34 saved_adv_err_code */
12350 0, /* 35 saved_adv_err_addr */
12351 0, /* 36 reserved */
12352 0, /* 37 reserved */
12353 0, /* 38 reserved */
12354 0, /* 39 reserved */
12355 0, /* 40 reserved */
12356 0, /* 41 reserved */
12357 0, /* 42 reserved */
12358 0, /* 43 reserved */
12359 0, /* 44 reserved */
12360 0, /* 45 reserved */
12361 0, /* 46 reserved */
12362 0, /* 47 reserved */
12363 0, /* 48 reserved */
12364 0, /* 49 reserved */
12365 0, /* 50 reserved */
12366 0, /* 51 reserved */
12367 0, /* 52 reserved */
12368 0, /* 53 reserved */
12369 0, /* 54 reserved */
12370 0, /* 55 reserved */
12371 0, /* 56 cisptr_lsw */
12372 0, /* 57 cisprt_msw */
12373 0, /* 58 subsysvid */
12374 0, /* 59 subsysid */
12375 0, /* 60 reserved */
12376 0, /* 61 reserved */
12377 0, /* 62 reserved */
12378 0 /* 63 reserved */
12381 #ifdef CONFIG_PCI
12383 * Wait for EEPROM command to complete
12385 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
12387 int eep_delay_ms;
12389 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
12390 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
12391 ASC_EEP_CMD_DONE) {
12392 break;
12394 mdelay(1);
12396 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12398 BUG();
12402 * Read the EEPROM from specified location
12404 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12406 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12407 ASC_EEP_CMD_READ | eep_word_addr);
12408 AdvWaitEEPCmd(iop_base);
12409 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
12413 * Write the EEPROM from 'cfg_buf'.
12415 void __devinit
12416 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12418 ushort *wbuf;
12419 ushort addr, chksum;
12420 ushort *charfields;
12422 wbuf = (ushort *)cfg_buf;
12423 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12424 chksum = 0;
12426 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12427 AdvWaitEEPCmd(iop_base);
12430 * Write EEPROM from word 0 to word 20.
12432 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12433 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12434 ushort word;
12436 if (*charfields++) {
12437 word = cpu_to_le16(*wbuf);
12438 } else {
12439 word = *wbuf;
12441 chksum += *wbuf; /* Checksum is calculated from word values. */
12442 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12443 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12444 ASC_EEP_CMD_WRITE | addr);
12445 AdvWaitEEPCmd(iop_base);
12446 mdelay(ADV_EEP_DELAY_MS);
12450 * Write EEPROM checksum at word 21.
12452 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12453 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12454 AdvWaitEEPCmd(iop_base);
12455 wbuf++;
12456 charfields++;
12459 * Write EEPROM OEM name at words 22 to 29.
12461 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12462 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12463 ushort word;
12465 if (*charfields++) {
12466 word = cpu_to_le16(*wbuf);
12467 } else {
12468 word = *wbuf;
12470 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12471 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12472 ASC_EEP_CMD_WRITE | addr);
12473 AdvWaitEEPCmd(iop_base);
12475 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12476 AdvWaitEEPCmd(iop_base);
12480 * Write the EEPROM from 'cfg_buf'.
12482 void __devinit
12483 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12485 ushort *wbuf;
12486 ushort *charfields;
12487 ushort addr, chksum;
12489 wbuf = (ushort *)cfg_buf;
12490 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12491 chksum = 0;
12493 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12494 AdvWaitEEPCmd(iop_base);
12497 * Write EEPROM from word 0 to word 20.
12499 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12500 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12501 ushort word;
12503 if (*charfields++) {
12504 word = cpu_to_le16(*wbuf);
12505 } else {
12506 word = *wbuf;
12508 chksum += *wbuf; /* Checksum is calculated from word values. */
12509 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12510 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12511 ASC_EEP_CMD_WRITE | addr);
12512 AdvWaitEEPCmd(iop_base);
12513 mdelay(ADV_EEP_DELAY_MS);
12517 * Write EEPROM checksum at word 21.
12519 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12520 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12521 AdvWaitEEPCmd(iop_base);
12522 wbuf++;
12523 charfields++;
12526 * Write EEPROM OEM name at words 22 to 29.
12528 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12529 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12530 ushort word;
12532 if (*charfields++) {
12533 word = cpu_to_le16(*wbuf);
12534 } else {
12535 word = *wbuf;
12537 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12538 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12539 ASC_EEP_CMD_WRITE | addr);
12540 AdvWaitEEPCmd(iop_base);
12542 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12543 AdvWaitEEPCmd(iop_base);
12547 * Write the EEPROM from 'cfg_buf'.
12549 void __devinit
12550 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12552 ushort *wbuf;
12553 ushort *charfields;
12554 ushort addr, chksum;
12556 wbuf = (ushort *)cfg_buf;
12557 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12558 chksum = 0;
12560 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12561 AdvWaitEEPCmd(iop_base);
12564 * Write EEPROM from word 0 to word 20.
12566 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12567 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12568 ushort word;
12570 if (*charfields++) {
12571 word = cpu_to_le16(*wbuf);
12572 } else {
12573 word = *wbuf;
12575 chksum += *wbuf; /* Checksum is calculated from word values. */
12576 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12577 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12578 ASC_EEP_CMD_WRITE | addr);
12579 AdvWaitEEPCmd(iop_base);
12580 mdelay(ADV_EEP_DELAY_MS);
12584 * Write EEPROM checksum at word 21.
12586 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12587 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12588 AdvWaitEEPCmd(iop_base);
12589 wbuf++;
12590 charfields++;
12593 * Write EEPROM OEM name at words 22 to 29.
12595 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12596 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12597 ushort word;
12599 if (*charfields++) {
12600 word = cpu_to_le16(*wbuf);
12601 } else {
12602 word = *wbuf;
12604 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12605 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12606 ASC_EEP_CMD_WRITE | addr);
12607 AdvWaitEEPCmd(iop_base);
12609 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12610 AdvWaitEEPCmd(iop_base);
12614 * Read EEPROM configuration into the specified buffer.
12616 * Return a checksum based on the EEPROM configuration read.
12618 static ushort __devinit
12619 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12621 ushort wval, chksum;
12622 ushort *wbuf;
12623 int eep_addr;
12624 ushort *charfields;
12626 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12627 wbuf = (ushort *)cfg_buf;
12628 chksum = 0;
12630 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12631 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12632 wval = AdvReadEEPWord(iop_base, eep_addr);
12633 chksum += wval; /* Checksum is calculated from word values. */
12634 if (*charfields++) {
12635 *wbuf = le16_to_cpu(wval);
12636 } else {
12637 *wbuf = wval;
12640 /* Read checksum word. */
12641 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12642 wbuf++;
12643 charfields++;
12645 /* Read rest of EEPROM not covered by the checksum. */
12646 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12647 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12648 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12649 if (*charfields++) {
12650 *wbuf = le16_to_cpu(*wbuf);
12653 return chksum;
12657 * Read EEPROM configuration into the specified buffer.
12659 * Return a checksum based on the EEPROM configuration read.
12661 static ushort __devinit
12662 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12664 ushort wval, chksum;
12665 ushort *wbuf;
12666 int eep_addr;
12667 ushort *charfields;
12669 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12670 wbuf = (ushort *)cfg_buf;
12671 chksum = 0;
12673 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12674 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12675 wval = AdvReadEEPWord(iop_base, eep_addr);
12676 chksum += wval; /* Checksum is calculated from word values. */
12677 if (*charfields++) {
12678 *wbuf = le16_to_cpu(wval);
12679 } else {
12680 *wbuf = wval;
12683 /* Read checksum word. */
12684 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12685 wbuf++;
12686 charfields++;
12688 /* Read rest of EEPROM not covered by the checksum. */
12689 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12690 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12691 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12692 if (*charfields++) {
12693 *wbuf = le16_to_cpu(*wbuf);
12696 return chksum;
12700 * Read EEPROM configuration into the specified buffer.
12702 * Return a checksum based on the EEPROM configuration read.
12704 static ushort __devinit
12705 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12707 ushort wval, chksum;
12708 ushort *wbuf;
12709 int eep_addr;
12710 ushort *charfields;
12712 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12713 wbuf = (ushort *)cfg_buf;
12714 chksum = 0;
12716 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12717 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12718 wval = AdvReadEEPWord(iop_base, eep_addr);
12719 chksum += wval; /* Checksum is calculated from word values. */
12720 if (*charfields++) {
12721 *wbuf = le16_to_cpu(wval);
12722 } else {
12723 *wbuf = wval;
12726 /* Read checksum word. */
12727 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12728 wbuf++;
12729 charfields++;
12731 /* Read rest of EEPROM not covered by the checksum. */
12732 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12733 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12734 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12735 if (*charfields++) {
12736 *wbuf = le16_to_cpu(*wbuf);
12739 return chksum;
12743 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12744 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12745 * all of this is done.
12747 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12749 * For a non-fatal error return a warning code. If there are no warnings
12750 * then 0 is returned.
12752 * Note: Chip is stopped on entry.
12754 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
12756 AdvPortAddr iop_base;
12757 ushort warn_code;
12758 ADVEEP_3550_CONFIG eep_config;
12760 iop_base = asc_dvc->iop_base;
12762 warn_code = 0;
12765 * Read the board's EEPROM configuration.
12767 * Set default values if a bad checksum is found.
12769 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12770 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12773 * Set EEPROM default values.
12775 memcpy(&eep_config, &Default_3550_EEPROM_Config,
12776 sizeof(ADVEEP_3550_CONFIG));
12779 * Assume the 6 byte board serial number that was read from
12780 * EEPROM is correct even if the EEPROM checksum failed.
12782 eep_config.serial_number_word3 =
12783 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
12785 eep_config.serial_number_word2 =
12786 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
12788 eep_config.serial_number_word1 =
12789 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
12791 AdvSet3550EEPConfig(iop_base, &eep_config);
12794 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12795 * EEPROM configuration that was read.
12797 * This is the mapping of EEPROM fields to Adv Library fields.
12799 asc_dvc->wdtr_able = eep_config.wdtr_able;
12800 asc_dvc->sdtr_able = eep_config.sdtr_able;
12801 asc_dvc->ultra_able = eep_config.ultra_able;
12802 asc_dvc->tagqng_able = eep_config.tagqng_able;
12803 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12804 asc_dvc->max_host_qng = eep_config.max_host_qng;
12805 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12806 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12807 asc_dvc->start_motor = eep_config.start_motor;
12808 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12809 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12810 asc_dvc->no_scam = eep_config.scam_tolerant;
12811 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12812 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12813 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12816 * Set the host maximum queuing (max. 253, min. 16) and the per device
12817 * maximum queuing (max. 63, min. 4).
12819 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12820 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12821 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12822 /* If the value is zero, assume it is uninitialized. */
12823 if (eep_config.max_host_qng == 0) {
12824 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12825 } else {
12826 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12830 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12831 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12832 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12833 /* If the value is zero, assume it is uninitialized. */
12834 if (eep_config.max_dvc_qng == 0) {
12835 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12836 } else {
12837 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12842 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12843 * set 'max_dvc_qng' to 'max_host_qng'.
12845 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12846 eep_config.max_dvc_qng = eep_config.max_host_qng;
12850 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12851 * values based on possibly adjusted EEPROM values.
12853 asc_dvc->max_host_qng = eep_config.max_host_qng;
12854 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12857 * If the EEPROM 'termination' field is set to automatic (0), then set
12858 * the ADV_DVC_CFG 'termination' field to automatic also.
12860 * If the termination is specified with a non-zero 'termination'
12861 * value check that a legal value is set and set the ADV_DVC_CFG
12862 * 'termination' field appropriately.
12864 if (eep_config.termination == 0) {
12865 asc_dvc->cfg->termination = 0; /* auto termination */
12866 } else {
12867 /* Enable manual control with low off / high off. */
12868 if (eep_config.termination == 1) {
12869 asc_dvc->cfg->termination = TERM_CTL_SEL;
12871 /* Enable manual control with low off / high on. */
12872 } else if (eep_config.termination == 2) {
12873 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
12875 /* Enable manual control with low on / high on. */
12876 } else if (eep_config.termination == 3) {
12877 asc_dvc->cfg->termination =
12878 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
12879 } else {
12881 * The EEPROM 'termination' field contains a bad value. Use
12882 * automatic termination instead.
12884 asc_dvc->cfg->termination = 0;
12885 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12889 return warn_code;
12893 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12894 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12895 * all of this is done.
12897 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12899 * For a non-fatal error return a warning code. If there are no warnings
12900 * then 0 is returned.
12902 * Note: Chip is stopped on entry.
12904 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
12906 AdvPortAddr iop_base;
12907 ushort warn_code;
12908 ADVEEP_38C0800_CONFIG eep_config;
12909 uchar tid, termination;
12910 ushort sdtr_speed = 0;
12912 iop_base = asc_dvc->iop_base;
12914 warn_code = 0;
12917 * Read the board's EEPROM configuration.
12919 * Set default values if a bad checksum is found.
12921 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
12922 eep_config.check_sum) {
12923 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12926 * Set EEPROM default values.
12928 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
12929 sizeof(ADVEEP_38C0800_CONFIG));
12932 * Assume the 6 byte board serial number that was read from
12933 * EEPROM is correct even if the EEPROM checksum failed.
12935 eep_config.serial_number_word3 =
12936 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
12938 eep_config.serial_number_word2 =
12939 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
12941 eep_config.serial_number_word1 =
12942 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
12944 AdvSet38C0800EEPConfig(iop_base, &eep_config);
12947 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
12948 * EEPROM configuration that was read.
12950 * This is the mapping of EEPROM fields to Adv Library fields.
12952 asc_dvc->wdtr_able = eep_config.wdtr_able;
12953 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
12954 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
12955 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
12956 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
12957 asc_dvc->tagqng_able = eep_config.tagqng_able;
12958 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12959 asc_dvc->max_host_qng = eep_config.max_host_qng;
12960 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12961 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12962 asc_dvc->start_motor = eep_config.start_motor;
12963 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12964 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12965 asc_dvc->no_scam = eep_config.scam_tolerant;
12966 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12967 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12968 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12971 * For every Target ID if any of its 'sdtr_speed[1234]' bits
12972 * are set, then set an 'sdtr_able' bit for it.
12974 asc_dvc->sdtr_able = 0;
12975 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12976 if (tid == 0) {
12977 sdtr_speed = asc_dvc->sdtr_speed1;
12978 } else if (tid == 4) {
12979 sdtr_speed = asc_dvc->sdtr_speed2;
12980 } else if (tid == 8) {
12981 sdtr_speed = asc_dvc->sdtr_speed3;
12982 } else if (tid == 12) {
12983 sdtr_speed = asc_dvc->sdtr_speed4;
12985 if (sdtr_speed & ADV_MAX_TID) {
12986 asc_dvc->sdtr_able |= (1 << tid);
12988 sdtr_speed >>= 4;
12992 * Set the host maximum queuing (max. 253, min. 16) and the per device
12993 * maximum queuing (max. 63, min. 4).
12995 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12996 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12997 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12998 /* If the value is zero, assume it is uninitialized. */
12999 if (eep_config.max_host_qng == 0) {
13000 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13001 } else {
13002 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13006 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13007 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13008 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13009 /* If the value is zero, assume it is uninitialized. */
13010 if (eep_config.max_dvc_qng == 0) {
13011 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13012 } else {
13013 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13018 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13019 * set 'max_dvc_qng' to 'max_host_qng'.
13021 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13022 eep_config.max_dvc_qng = eep_config.max_host_qng;
13026 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13027 * values based on possibly adjusted EEPROM values.
13029 asc_dvc->max_host_qng = eep_config.max_host_qng;
13030 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13033 * If the EEPROM 'termination' field is set to automatic (0), then set
13034 * the ADV_DVC_CFG 'termination' field to automatic also.
13036 * If the termination is specified with a non-zero 'termination'
13037 * value check that a legal value is set and set the ADV_DVC_CFG
13038 * 'termination' field appropriately.
13040 if (eep_config.termination_se == 0) {
13041 termination = 0; /* auto termination for SE */
13042 } else {
13043 /* Enable manual control with low off / high off. */
13044 if (eep_config.termination_se == 1) {
13045 termination = 0;
13047 /* Enable manual control with low off / high on. */
13048 } else if (eep_config.termination_se == 2) {
13049 termination = TERM_SE_HI;
13051 /* Enable manual control with low on / high on. */
13052 } else if (eep_config.termination_se == 3) {
13053 termination = TERM_SE;
13054 } else {
13056 * The EEPROM 'termination_se' field contains a bad value.
13057 * Use automatic termination instead.
13059 termination = 0;
13060 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13064 if (eep_config.termination_lvd == 0) {
13065 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13066 } else {
13067 /* Enable manual control with low off / high off. */
13068 if (eep_config.termination_lvd == 1) {
13069 asc_dvc->cfg->termination = termination;
13071 /* Enable manual control with low off / high on. */
13072 } else if (eep_config.termination_lvd == 2) {
13073 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13075 /* Enable manual control with low on / high on. */
13076 } else if (eep_config.termination_lvd == 3) {
13077 asc_dvc->cfg->termination = termination | TERM_LVD;
13078 } else {
13080 * The EEPROM 'termination_lvd' field contains a bad value.
13081 * Use automatic termination instead.
13083 asc_dvc->cfg->termination = termination;
13084 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13088 return warn_code;
13092 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13093 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13094 * all of this is done.
13096 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13098 * For a non-fatal error return a warning code. If there are no warnings
13099 * then 0 is returned.
13101 * Note: Chip is stopped on entry.
13103 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
13105 AdvPortAddr iop_base;
13106 ushort warn_code;
13107 ADVEEP_38C1600_CONFIG eep_config;
13108 uchar tid, termination;
13109 ushort sdtr_speed = 0;
13111 iop_base = asc_dvc->iop_base;
13113 warn_code = 0;
13116 * Read the board's EEPROM configuration.
13118 * Set default values if a bad checksum is found.
13120 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13121 eep_config.check_sum) {
13122 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
13123 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13126 * Set EEPROM default values.
13128 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13129 sizeof(ADVEEP_38C1600_CONFIG));
13131 if (PCI_FUNC(pdev->devfn) != 0) {
13132 u8 ints;
13134 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13135 * and old Mac system booting problem. The Expansion
13136 * ROM must be disabled in Function 1 for these systems
13138 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13140 * Clear the INTAB (bit 11) if the GPIO 0 input
13141 * indicates the Function 1 interrupt line is wired
13142 * to INTB.
13144 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13145 * 1 - Function 1 interrupt line wired to INT A.
13146 * 0 - Function 1 interrupt line wired to INT B.
13148 * Note: Function 0 is always wired to INTA.
13149 * Put all 5 GPIO bits in input mode and then read
13150 * their input values.
13152 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13153 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13154 if ((ints & 0x01) == 0)
13155 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
13159 * Assume the 6 byte board serial number that was read from
13160 * EEPROM is correct even if the EEPROM checksum failed.
13162 eep_config.serial_number_word3 =
13163 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13164 eep_config.serial_number_word2 =
13165 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13166 eep_config.serial_number_word1 =
13167 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13169 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13173 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13174 * EEPROM configuration that was read.
13176 * This is the mapping of EEPROM fields to Adv Library fields.
13178 asc_dvc->wdtr_able = eep_config.wdtr_able;
13179 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13180 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13181 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13182 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13183 asc_dvc->ppr_able = 0;
13184 asc_dvc->tagqng_able = eep_config.tagqng_able;
13185 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13186 asc_dvc->max_host_qng = eep_config.max_host_qng;
13187 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13188 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13189 asc_dvc->start_motor = eep_config.start_motor;
13190 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13191 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13192 asc_dvc->no_scam = eep_config.scam_tolerant;
13195 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13196 * are set, then set an 'sdtr_able' bit for it.
13198 asc_dvc->sdtr_able = 0;
13199 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13200 if (tid == 0) {
13201 sdtr_speed = asc_dvc->sdtr_speed1;
13202 } else if (tid == 4) {
13203 sdtr_speed = asc_dvc->sdtr_speed2;
13204 } else if (tid == 8) {
13205 sdtr_speed = asc_dvc->sdtr_speed3;
13206 } else if (tid == 12) {
13207 sdtr_speed = asc_dvc->sdtr_speed4;
13209 if (sdtr_speed & ASC_MAX_TID) {
13210 asc_dvc->sdtr_able |= (1 << tid);
13212 sdtr_speed >>= 4;
13216 * Set the host maximum queuing (max. 253, min. 16) and the per device
13217 * maximum queuing (max. 63, min. 4).
13219 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13220 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13221 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13222 /* If the value is zero, assume it is uninitialized. */
13223 if (eep_config.max_host_qng == 0) {
13224 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13225 } else {
13226 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13230 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13231 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13232 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13233 /* If the value is zero, assume it is uninitialized. */
13234 if (eep_config.max_dvc_qng == 0) {
13235 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13236 } else {
13237 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13242 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13243 * set 'max_dvc_qng' to 'max_host_qng'.
13245 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13246 eep_config.max_dvc_qng = eep_config.max_host_qng;
13250 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13251 * values based on possibly adjusted EEPROM values.
13253 asc_dvc->max_host_qng = eep_config.max_host_qng;
13254 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13257 * If the EEPROM 'termination' field is set to automatic (0), then set
13258 * the ASC_DVC_CFG 'termination' field to automatic also.
13260 * If the termination is specified with a non-zero 'termination'
13261 * value check that a legal value is set and set the ASC_DVC_CFG
13262 * 'termination' field appropriately.
13264 if (eep_config.termination_se == 0) {
13265 termination = 0; /* auto termination for SE */
13266 } else {
13267 /* Enable manual control with low off / high off. */
13268 if (eep_config.termination_se == 1) {
13269 termination = 0;
13271 /* Enable manual control with low off / high on. */
13272 } else if (eep_config.termination_se == 2) {
13273 termination = TERM_SE_HI;
13275 /* Enable manual control with low on / high on. */
13276 } else if (eep_config.termination_se == 3) {
13277 termination = TERM_SE;
13278 } else {
13280 * The EEPROM 'termination_se' field contains a bad value.
13281 * Use automatic termination instead.
13283 termination = 0;
13284 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13288 if (eep_config.termination_lvd == 0) {
13289 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13290 } else {
13291 /* Enable manual control with low off / high off. */
13292 if (eep_config.termination_lvd == 1) {
13293 asc_dvc->cfg->termination = termination;
13295 /* Enable manual control with low off / high on. */
13296 } else if (eep_config.termination_lvd == 2) {
13297 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13299 /* Enable manual control with low on / high on. */
13300 } else if (eep_config.termination_lvd == 3) {
13301 asc_dvc->cfg->termination = termination | TERM_LVD;
13302 } else {
13304 * The EEPROM 'termination_lvd' field contains a bad value.
13305 * Use automatic termination instead.
13307 asc_dvc->cfg->termination = termination;
13308 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13312 return warn_code;
13316 * Initialize the ADV_DVC_VAR structure.
13318 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13320 * For a non-fatal error return a warning code. If there are no warnings
13321 * then 0 is returned.
13323 static int __devinit
13324 AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
13326 struct asc_board *board = shost_priv(shost);
13327 ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
13328 unsigned short warn_code = 0;
13329 AdvPortAddr iop_base = asc_dvc->iop_base;
13330 u16 cmd;
13331 int status;
13333 asc_dvc->err_code = 0;
13336 * Save the state of the PCI Configuration Command Register
13337 * "Parity Error Response Control" Bit. If the bit is clear (0),
13338 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13339 * DMA parity errors.
13341 asc_dvc->cfg->control_flag = 0;
13342 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13343 if ((cmd & PCI_COMMAND_PARITY) == 0)
13344 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13346 asc_dvc->cfg->chip_version =
13347 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13349 ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
13350 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13351 (ushort)ADV_CHIP_ID_BYTE);
13353 ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
13354 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13355 (ushort)ADV_CHIP_ID_WORD);
13358 * Reset the chip to start and allow register writes.
13360 if (AdvFindSignature(iop_base) == 0) {
13361 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13362 return ADV_ERROR;
13363 } else {
13365 * The caller must set 'chip_type' to a valid setting.
13367 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13368 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13369 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13370 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13371 return ADV_ERROR;
13375 * Reset Chip.
13377 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13378 ADV_CTRL_REG_CMD_RESET);
13379 mdelay(100);
13380 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13381 ADV_CTRL_REG_CMD_WR_IO_REG);
13383 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13384 status = AdvInitFrom38C1600EEP(asc_dvc);
13385 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13386 status = AdvInitFrom38C0800EEP(asc_dvc);
13387 } else {
13388 status = AdvInitFrom3550EEP(asc_dvc);
13390 warn_code |= status;
13393 if (warn_code != 0)
13394 shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code);
13396 if (asc_dvc->err_code)
13397 shost_printk(KERN_ERR, shost, "error code 0x%x\n",
13398 asc_dvc->err_code);
13400 return asc_dvc->err_code;
13402 #endif
13404 static struct scsi_host_template advansys_template = {
13405 .proc_name = DRV_NAME,
13406 #ifdef CONFIG_PROC_FS
13407 .proc_info = advansys_proc_info,
13408 #endif
13409 .name = DRV_NAME,
13410 .info = advansys_info,
13411 .queuecommand = advansys_queuecommand,
13412 .eh_bus_reset_handler = advansys_reset,
13413 .bios_param = advansys_biosparam,
13414 .slave_configure = advansys_slave_configure,
13416 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
13417 * must be set. The flag will be cleared in advansys_board_found
13418 * for non-ISA adapters.
13420 .unchecked_isa_dma = 1,
13422 * All adapters controlled by this driver are capable of large
13423 * scatter-gather lists. According to the mid-level SCSI documentation
13424 * this obviates any performance gain provided by setting
13425 * 'use_clustering'. But empirically while CPU utilization is increased
13426 * by enabling clustering, I/O throughput increases as well.
13428 .use_clustering = ENABLE_CLUSTERING,
13431 static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
13433 struct asc_board *board = shost_priv(shost);
13434 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
13435 int req_cnt = 0;
13436 adv_req_t *reqp = NULL;
13437 int sg_cnt = 0;
13438 adv_sgblk_t *sgp;
13439 int warn_code, err_code;
13442 * Allocate buffer carrier structures. The total size
13443 * is about 4 KB, so allocate all at once.
13445 board->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13446 ASC_DBG(1, "carrp 0x%p\n", board->carrp);
13448 if (!board->carrp)
13449 goto kmalloc_failed;
13452 * Allocate up to 'max_host_qng' request structures for the Wide
13453 * board. The total size is about 16 KB, so allocate all at once.
13454 * If the allocation fails decrement and try again.
13456 for (req_cnt = adv_dvc->max_host_qng; req_cnt > 0; req_cnt--) {
13457 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13459 ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt,
13460 (ulong)sizeof(adv_req_t) * req_cnt);
13462 if (reqp)
13463 break;
13466 if (!reqp)
13467 goto kmalloc_failed;
13469 board->orig_reqp = reqp;
13472 * Allocate up to ADV_TOT_SG_BLOCK request structures for
13473 * the Wide board. Each structure is about 136 bytes.
13475 board->adv_sgblkp = NULL;
13476 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13477 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13479 if (!sgp)
13480 break;
13482 sgp->next_sgblkp = board->adv_sgblkp;
13483 board->adv_sgblkp = sgp;
13487 ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t),
13488 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
13490 if (!board->adv_sgblkp)
13491 goto kmalloc_failed;
13493 adv_dvc->carrier_buf = board->carrp;
13496 * Point 'adv_reqp' to the request structures and
13497 * link them together.
13499 req_cnt--;
13500 reqp[req_cnt].next_reqp = NULL;
13501 for (; req_cnt > 0; req_cnt--) {
13502 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
13504 board->adv_reqp = &reqp[0];
13506 if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
13507 ASC_DBG(2, "AdvInitAsc3550Driver()\n");
13508 warn_code = AdvInitAsc3550Driver(adv_dvc);
13509 } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13510 ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
13511 warn_code = AdvInitAsc38C0800Driver(adv_dvc);
13512 } else {
13513 ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
13514 warn_code = AdvInitAsc38C1600Driver(adv_dvc);
13516 err_code = adv_dvc->err_code;
13518 if (warn_code || err_code) {
13519 shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error "
13520 "0x%x\n", warn_code, err_code);
13523 goto exit;
13525 kmalloc_failed:
13526 shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n");
13527 err_code = ADV_ERROR;
13528 exit:
13529 return err_code;
13532 static void advansys_wide_free_mem(struct asc_board *boardp)
13534 kfree(boardp->carrp);
13535 boardp->carrp = NULL;
13536 kfree(boardp->orig_reqp);
13537 boardp->orig_reqp = boardp->adv_reqp = NULL;
13538 while (boardp->adv_sgblkp) {
13539 adv_sgblk_t *sgp = boardp->adv_sgblkp;
13540 boardp->adv_sgblkp = sgp->next_sgblkp;
13541 kfree(sgp);
13545 static int __devinit advansys_board_found(struct Scsi_Host *shost,
13546 unsigned int iop, int bus_type)
13548 struct pci_dev *pdev;
13549 struct asc_board *boardp = shost_priv(shost);
13550 ASC_DVC_VAR *asc_dvc_varp = NULL;
13551 ADV_DVC_VAR *adv_dvc_varp = NULL;
13552 int share_irq, warn_code, ret;
13554 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
13556 if (ASC_NARROW_BOARD(boardp)) {
13557 ASC_DBG(1, "narrow board\n");
13558 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
13559 asc_dvc_varp->bus_type = bus_type;
13560 asc_dvc_varp->drv_ptr = boardp;
13561 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
13562 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
13563 asc_dvc_varp->iop_base = iop;
13564 } else {
13565 #ifdef CONFIG_PCI
13566 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
13567 adv_dvc_varp->drv_ptr = boardp;
13568 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
13569 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
13570 ASC_DBG(1, "wide board ASC-3550\n");
13571 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13572 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
13573 ASC_DBG(1, "wide board ASC-38C0800\n");
13574 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13575 } else {
13576 ASC_DBG(1, "wide board ASC-38C1600\n");
13577 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13580 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
13581 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
13582 boardp->asc_n_io_port);
13583 if (!boardp->ioremap_addr) {
13584 shost_printk(KERN_ERR, shost, "ioremap(%x, %d) "
13585 "returned NULL\n",
13586 pci_resource_start(pdev, 1),
13587 boardp->asc_n_io_port);
13588 ret = -ENODEV;
13589 goto err_shost;
13591 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
13592 ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
13595 * Even though it isn't used to access wide boards, other
13596 * than for the debug line below, save I/O Port address so
13597 * that it can be reported.
13599 boardp->ioport = iop;
13601 ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
13602 (ushort)inp(iop + 1), (ushort)inpw(iop));
13603 #endif /* CONFIG_PCI */
13606 #ifdef CONFIG_PROC_FS
13608 * Allocate buffer for printing information from
13609 * /proc/scsi/advansys/[0...].
13611 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13612 if (!boardp->prtbuf) {
13613 shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n",
13614 ASC_PRTBUF_SIZE);
13615 ret = -ENOMEM;
13616 goto err_unmap;
13618 #endif /* CONFIG_PROC_FS */
13620 if (ASC_NARROW_BOARD(boardp)) {
13622 * Set the board bus type and PCI IRQ before
13623 * calling AscInitGetConfig().
13625 switch (asc_dvc_varp->bus_type) {
13626 #ifdef CONFIG_ISA
13627 case ASC_IS_ISA:
13628 shost->unchecked_isa_dma = TRUE;
13629 share_irq = 0;
13630 break;
13631 case ASC_IS_VL:
13632 shost->unchecked_isa_dma = FALSE;
13633 share_irq = 0;
13634 break;
13635 case ASC_IS_EISA:
13636 shost->unchecked_isa_dma = FALSE;
13637 share_irq = IRQF_SHARED;
13638 break;
13639 #endif /* CONFIG_ISA */
13640 #ifdef CONFIG_PCI
13641 case ASC_IS_PCI:
13642 shost->unchecked_isa_dma = FALSE;
13643 share_irq = IRQF_SHARED;
13644 break;
13645 #endif /* CONFIG_PCI */
13646 default:
13647 shost_printk(KERN_ERR, shost, "unknown adapter type: "
13648 "%d\n", asc_dvc_varp->bus_type);
13649 shost->unchecked_isa_dma = TRUE;
13650 share_irq = 0;
13651 break;
13655 * NOTE: AscInitGetConfig() may change the board's
13656 * bus_type value. The bus_type value should no
13657 * longer be used. If the bus_type field must be
13658 * referenced only use the bit-wise AND operator "&".
13660 ASC_DBG(2, "AscInitGetConfig()\n");
13661 ret = AscInitGetConfig(shost) ? -ENODEV : 0;
13662 } else {
13663 #ifdef CONFIG_PCI
13665 * For Wide boards set PCI information before calling
13666 * AdvInitGetConfig().
13668 shost->unchecked_isa_dma = FALSE;
13669 share_irq = IRQF_SHARED;
13670 ASC_DBG(2, "AdvInitGetConfig()\n");
13672 ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0;
13673 #endif /* CONFIG_PCI */
13676 if (ret)
13677 goto err_free_proc;
13680 * Save the EEPROM configuration so that it can be displayed
13681 * from /proc/scsi/advansys/[0...].
13683 if (ASC_NARROW_BOARD(boardp)) {
13685 ASCEEP_CONFIG *ep;
13688 * Set the adapter's target id bit in the 'init_tidmask' field.
13690 boardp->init_tidmask |=
13691 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
13694 * Save EEPROM settings for the board.
13696 ep = &boardp->eep_config.asc_eep;
13698 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
13699 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
13700 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
13701 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
13702 ep->start_motor = asc_dvc_varp->start_motor;
13703 ep->cntl = asc_dvc_varp->dvc_cntl;
13704 ep->no_scam = asc_dvc_varp->no_scam;
13705 ep->max_total_qng = asc_dvc_varp->max_total_qng;
13706 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
13707 /* 'max_tag_qng' is set to the same value for every device. */
13708 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
13709 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
13710 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
13711 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
13712 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
13713 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
13714 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
13717 * Modify board configuration.
13719 ASC_DBG(2, "AscInitSetConfig()\n");
13720 ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
13721 if (ret)
13722 goto err_free_proc;
13723 } else {
13724 ADVEEP_3550_CONFIG *ep_3550;
13725 ADVEEP_38C0800_CONFIG *ep_38C0800;
13726 ADVEEP_38C1600_CONFIG *ep_38C1600;
13729 * Save Wide EEP Configuration Information.
13731 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13732 ep_3550 = &boardp->eep_config.adv_3550_eep;
13734 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
13735 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
13736 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13737 ep_3550->termination = adv_dvc_varp->cfg->termination;
13738 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
13739 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
13740 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
13741 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
13742 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
13743 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
13744 ep_3550->start_motor = adv_dvc_varp->start_motor;
13745 ep_3550->scsi_reset_delay =
13746 adv_dvc_varp->scsi_reset_wait;
13747 ep_3550->serial_number_word1 =
13748 adv_dvc_varp->cfg->serial1;
13749 ep_3550->serial_number_word2 =
13750 adv_dvc_varp->cfg->serial2;
13751 ep_3550->serial_number_word3 =
13752 adv_dvc_varp->cfg->serial3;
13753 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13754 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
13756 ep_38C0800->adapter_scsi_id =
13757 adv_dvc_varp->chip_scsi_id;
13758 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
13759 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13760 ep_38C0800->termination_lvd =
13761 adv_dvc_varp->cfg->termination;
13762 ep_38C0800->disc_enable =
13763 adv_dvc_varp->cfg->disc_enable;
13764 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
13765 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
13766 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13767 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13768 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13769 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13770 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13771 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13772 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
13773 ep_38C0800->scsi_reset_delay =
13774 adv_dvc_varp->scsi_reset_wait;
13775 ep_38C0800->serial_number_word1 =
13776 adv_dvc_varp->cfg->serial1;
13777 ep_38C0800->serial_number_word2 =
13778 adv_dvc_varp->cfg->serial2;
13779 ep_38C0800->serial_number_word3 =
13780 adv_dvc_varp->cfg->serial3;
13781 } else {
13782 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
13784 ep_38C1600->adapter_scsi_id =
13785 adv_dvc_varp->chip_scsi_id;
13786 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
13787 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13788 ep_38C1600->termination_lvd =
13789 adv_dvc_varp->cfg->termination;
13790 ep_38C1600->disc_enable =
13791 adv_dvc_varp->cfg->disc_enable;
13792 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
13793 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
13794 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13795 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13796 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13797 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13798 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13799 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13800 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
13801 ep_38C1600->scsi_reset_delay =
13802 adv_dvc_varp->scsi_reset_wait;
13803 ep_38C1600->serial_number_word1 =
13804 adv_dvc_varp->cfg->serial1;
13805 ep_38C1600->serial_number_word2 =
13806 adv_dvc_varp->cfg->serial2;
13807 ep_38C1600->serial_number_word3 =
13808 adv_dvc_varp->cfg->serial3;
13812 * Set the adapter's target id bit in the 'init_tidmask' field.
13814 boardp->init_tidmask |=
13815 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
13819 * Channels are numbered beginning with 0. For AdvanSys one host
13820 * structure supports one channel. Multi-channel boards have a
13821 * separate host structure for each channel.
13823 shost->max_channel = 0;
13824 if (ASC_NARROW_BOARD(boardp)) {
13825 shost->max_id = ASC_MAX_TID + 1;
13826 shost->max_lun = ASC_MAX_LUN + 1;
13827 shost->max_cmd_len = ASC_MAX_CDB_LEN;
13829 shost->io_port = asc_dvc_varp->iop_base;
13830 boardp->asc_n_io_port = ASC_IOADR_GAP;
13831 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
13833 /* Set maximum number of queues the adapter can handle. */
13834 shost->can_queue = asc_dvc_varp->max_total_qng;
13835 } else {
13836 shost->max_id = ADV_MAX_TID + 1;
13837 shost->max_lun = ADV_MAX_LUN + 1;
13838 shost->max_cmd_len = ADV_MAX_CDB_LEN;
13841 * Save the I/O Port address and length even though
13842 * I/O ports are not used to access Wide boards.
13843 * Instead the Wide boards are accessed with
13844 * PCI Memory Mapped I/O.
13846 shost->io_port = iop;
13848 shost->this_id = adv_dvc_varp->chip_scsi_id;
13850 /* Set maximum number of queues the adapter can handle. */
13851 shost->can_queue = adv_dvc_varp->max_host_qng;
13855 * Following v1.3.89, 'cmd_per_lun' is no longer needed
13856 * and should be set to zero.
13858 * But because of a bug introduced in v1.3.89 if the driver is
13859 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
13860 * SCSI function 'allocate_device' will panic. To allow the driver
13861 * to work as a module in these kernels set 'cmd_per_lun' to 1.
13863 * Note: This is wrong. cmd_per_lun should be set to the depth
13864 * you want on untagged devices always.
13865 #ifdef MODULE
13867 shost->cmd_per_lun = 1;
13868 /* #else
13869 shost->cmd_per_lun = 0;
13870 #endif */
13873 * Set the maximum number of scatter-gather elements the
13874 * adapter can handle.
13876 if (ASC_NARROW_BOARD(boardp)) {
13878 * Allow two commands with 'sg_tablesize' scatter-gather
13879 * elements to be executed simultaneously. This value is
13880 * the theoretical hardware limit. It may be decreased
13881 * below.
13883 shost->sg_tablesize =
13884 (((asc_dvc_varp->max_total_qng - 2) / 2) *
13885 ASC_SG_LIST_PER_Q) + 1;
13886 } else {
13887 shost->sg_tablesize = ADV_MAX_SG_LIST;
13891 * The value of 'sg_tablesize' can not exceed the SCSI
13892 * mid-level driver definition of SG_ALL. SG_ALL also
13893 * must not be exceeded, because it is used to define the
13894 * size of the scatter-gather table in 'struct asc_sg_head'.
13896 if (shost->sg_tablesize > SG_ALL) {
13897 shost->sg_tablesize = SG_ALL;
13900 ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
13902 /* BIOS start address. */
13903 if (ASC_NARROW_BOARD(boardp)) {
13904 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
13905 asc_dvc_varp->bus_type);
13906 } else {
13908 * Fill-in BIOS board variables. The Wide BIOS saves
13909 * information in LRAM that is used by the driver.
13911 AdvReadWordLram(adv_dvc_varp->iop_base,
13912 BIOS_SIGNATURE, boardp->bios_signature);
13913 AdvReadWordLram(adv_dvc_varp->iop_base,
13914 BIOS_VERSION, boardp->bios_version);
13915 AdvReadWordLram(adv_dvc_varp->iop_base,
13916 BIOS_CODESEG, boardp->bios_codeseg);
13917 AdvReadWordLram(adv_dvc_varp->iop_base,
13918 BIOS_CODELEN, boardp->bios_codelen);
13920 ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
13921 boardp->bios_signature, boardp->bios_version);
13923 ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
13924 boardp->bios_codeseg, boardp->bios_codelen);
13927 * If the BIOS saved a valid signature, then fill in
13928 * the BIOS code segment base address.
13930 if (boardp->bios_signature == 0x55AA) {
13932 * Convert x86 realmode code segment to a linear
13933 * address by shifting left 4.
13935 shost->base = ((ulong)boardp->bios_codeseg << 4);
13936 } else {
13937 shost->base = 0;
13942 * Register Board Resources - I/O Port, DMA, IRQ
13945 /* Register DMA Channel for Narrow boards. */
13946 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
13947 #ifdef CONFIG_ISA
13948 if (ASC_NARROW_BOARD(boardp)) {
13949 /* Register DMA channel for ISA bus. */
13950 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
13951 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
13952 ret = request_dma(shost->dma_channel, DRV_NAME);
13953 if (ret) {
13954 shost_printk(KERN_ERR, shost, "request_dma() "
13955 "%d failed %d\n",
13956 shost->dma_channel, ret);
13957 goto err_free_proc;
13959 AscEnableIsaDma(shost->dma_channel);
13962 #endif /* CONFIG_ISA */
13964 /* Register IRQ Number. */
13965 ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
13967 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
13968 DRV_NAME, shost);
13970 if (ret) {
13971 if (ret == -EBUSY) {
13972 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13973 "already in use\n", boardp->irq);
13974 } else if (ret == -EINVAL) {
13975 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13976 "not valid\n", boardp->irq);
13977 } else {
13978 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13979 "failed with %d\n", boardp->irq, ret);
13981 goto err_free_dma;
13985 * Initialize board RISC chip and enable interrupts.
13987 if (ASC_NARROW_BOARD(boardp)) {
13988 ASC_DBG(2, "AscInitAsc1000Driver()\n");
13989 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
13991 if (warn_code || asc_dvc_varp->err_code) {
13992 shost_printk(KERN_ERR, shost, "error: init_state 0x%x, "
13993 "warn 0x%x, error 0x%x\n",
13994 asc_dvc_varp->init_state, warn_code,
13995 asc_dvc_varp->err_code);
13996 if (asc_dvc_varp->err_code)
13997 ret = -ENODEV;
13999 } else {
14000 if (advansys_wide_init_chip(shost))
14001 ret = -ENODEV;
14004 if (ret)
14005 goto err_free_wide_mem;
14007 ASC_DBG_PRT_SCSI_HOST(2, shost);
14009 ret = scsi_add_host(shost, boardp->dev);
14010 if (ret)
14011 goto err_free_wide_mem;
14013 scsi_scan_host(shost);
14014 return 0;
14016 err_free_wide_mem:
14017 advansys_wide_free_mem(boardp);
14018 free_irq(boardp->irq, shost);
14019 err_free_dma:
14020 if (shost->dma_channel != NO_ISA_DMA)
14021 free_dma(shost->dma_channel);
14022 err_free_proc:
14023 kfree(boardp->prtbuf);
14024 err_unmap:
14025 if (boardp->ioremap_addr)
14026 iounmap(boardp->ioremap_addr);
14027 err_shost:
14028 return ret;
14032 * advansys_release()
14034 * Release resources allocated for a single AdvanSys adapter.
14036 static int advansys_release(struct Scsi_Host *shost)
14038 struct asc_board *boardp = shost_priv(shost);
14039 ASC_DBG(1, "begin\n");
14040 scsi_remove_host(shost);
14041 free_irq(boardp->irq, shost);
14042 if (shost->dma_channel != NO_ISA_DMA) {
14043 ASC_DBG(1, "free_dma()\n");
14044 free_dma(shost->dma_channel);
14046 if (!ASC_NARROW_BOARD(boardp)) {
14047 iounmap(boardp->ioremap_addr);
14048 advansys_wide_free_mem(boardp);
14050 kfree(boardp->prtbuf);
14051 scsi_host_put(shost);
14052 ASC_DBG(1, "end\n");
14053 return 0;
14056 #define ASC_IOADR_TABLE_MAX_IX 11
14058 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14059 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14060 0x0210, 0x0230, 0x0250, 0x0330
14064 * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw. It decodes as:
14065 * 00: 10
14066 * 01: 11
14067 * 10: 12
14068 * 11: 15
14070 static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
14072 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14073 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
14074 if (chip_irq == 13)
14075 chip_irq = 15;
14076 return chip_irq;
14079 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14081 int err = -ENODEV;
14082 PortAddr iop_base = _asc_def_iop_base[id];
14083 struct Scsi_Host *shost;
14084 struct asc_board *board;
14086 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14087 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
14088 return -ENODEV;
14090 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
14091 if (!AscFindSignature(iop_base))
14092 goto release_region;
14093 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14094 goto release_region;
14096 err = -ENOMEM;
14097 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14098 if (!shost)
14099 goto release_region;
14101 board = shost_priv(shost);
14102 board->irq = advansys_isa_irq_no(iop_base);
14103 board->dev = dev;
14105 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
14106 if (err)
14107 goto free_host;
14109 dev_set_drvdata(dev, shost);
14110 return 0;
14112 free_host:
14113 scsi_host_put(shost);
14114 release_region:
14115 release_region(iop_base, ASC_IOADR_GAP);
14116 return err;
14119 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14121 int ioport = _asc_def_iop_base[id];
14122 advansys_release(dev_get_drvdata(dev));
14123 release_region(ioport, ASC_IOADR_GAP);
14124 return 0;
14127 static struct isa_driver advansys_isa_driver = {
14128 .probe = advansys_isa_probe,
14129 .remove = __devexit_p(advansys_isa_remove),
14130 .driver = {
14131 .owner = THIS_MODULE,
14132 .name = DRV_NAME,
14137 * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw. It decodes as:
14138 * 000: invalid
14139 * 001: 10
14140 * 010: 11
14141 * 011: 12
14142 * 100: invalid
14143 * 101: 14
14144 * 110: 15
14145 * 111: invalid
14147 static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
14149 unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14150 unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
14151 if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
14152 return 0;
14153 return chip_irq;
14156 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14158 int err = -ENODEV;
14159 PortAddr iop_base = _asc_def_iop_base[id];
14160 struct Scsi_Host *shost;
14161 struct asc_board *board;
14163 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14164 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
14165 return -ENODEV;
14167 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
14168 if (!AscFindSignature(iop_base))
14169 goto release_region;
14171 * I don't think this condition can actually happen, but the old
14172 * driver did it, and the chances of finding a VLB setup in 2007
14173 * to do testing with is slight to none.
14175 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14176 goto release_region;
14178 err = -ENOMEM;
14179 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14180 if (!shost)
14181 goto release_region;
14183 board = shost_priv(shost);
14184 board->irq = advansys_vlb_irq_no(iop_base);
14185 board->dev = dev;
14187 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14188 if (err)
14189 goto free_host;
14191 dev_set_drvdata(dev, shost);
14192 return 0;
14194 free_host:
14195 scsi_host_put(shost);
14196 release_region:
14197 release_region(iop_base, ASC_IOADR_GAP);
14198 return -ENODEV;
14201 static struct isa_driver advansys_vlb_driver = {
14202 .probe = advansys_vlb_probe,
14203 .remove = __devexit_p(advansys_isa_remove),
14204 .driver = {
14205 .owner = THIS_MODULE,
14206 .name = "advansys_vlb",
14210 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14211 { "ABP7401" },
14212 { "ABP7501" },
14213 { "" }
14216 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14219 * EISA is a little more tricky than PCI; each EISA device may have two
14220 * channels, and this driver is written to make each channel its own Scsi_Host
14222 struct eisa_scsi_data {
14223 struct Scsi_Host *host[2];
14227 * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw. It decodes as:
14228 * 000: 10
14229 * 001: 11
14230 * 010: 12
14231 * 011: invalid
14232 * 100: 14
14233 * 101: 15
14234 * 110: invalid
14235 * 111: invalid
14237 static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14239 unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
14240 unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
14241 if ((chip_irq == 13) || (chip_irq > 15))
14242 return 0;
14243 return chip_irq;
14246 static int __devinit advansys_eisa_probe(struct device *dev)
14248 int i, ioport, irq = 0;
14249 int err;
14250 struct eisa_device *edev = to_eisa_device(dev);
14251 struct eisa_scsi_data *data;
14253 err = -ENOMEM;
14254 data = kzalloc(sizeof(*data), GFP_KERNEL);
14255 if (!data)
14256 goto fail;
14257 ioport = edev->base_addr + 0xc30;
14259 err = -ENODEV;
14260 for (i = 0; i < 2; i++, ioport += 0x20) {
14261 struct asc_board *board;
14262 struct Scsi_Host *shost;
14263 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
14264 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14265 ioport + ASC_IOADR_GAP - 1);
14266 continue;
14268 if (!AscFindSignature(ioport)) {
14269 release_region(ioport, ASC_IOADR_GAP);
14270 continue;
14274 * I don't know why we need to do this for EISA chips, but
14275 * not for any others. It looks to be equivalent to
14276 * AscGetChipCfgMsw, but I may have overlooked something,
14277 * so I'm not converting it until I get an EISA board to
14278 * test with.
14280 inw(ioport + 4);
14282 if (!irq)
14283 irq = advansys_eisa_irq_no(edev);
14285 err = -ENOMEM;
14286 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14287 if (!shost)
14288 goto release_region;
14290 board = shost_priv(shost);
14291 board->irq = irq;
14292 board->dev = dev;
14294 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14295 if (!err) {
14296 data->host[i] = shost;
14297 continue;
14300 scsi_host_put(shost);
14301 release_region:
14302 release_region(ioport, ASC_IOADR_GAP);
14303 break;
14306 if (err)
14307 goto free_data;
14308 dev_set_drvdata(dev, data);
14309 return 0;
14311 free_data:
14312 kfree(data->host[0]);
14313 kfree(data->host[1]);
14314 kfree(data);
14315 fail:
14316 return err;
14319 static __devexit int advansys_eisa_remove(struct device *dev)
14321 int i;
14322 struct eisa_scsi_data *data = dev_get_drvdata(dev);
14324 for (i = 0; i < 2; i++) {
14325 int ioport;
14326 struct Scsi_Host *shost = data->host[i];
14327 if (!shost)
14328 continue;
14329 ioport = shost->io_port;
14330 advansys_release(shost);
14331 release_region(ioport, ASC_IOADR_GAP);
14334 kfree(data);
14335 return 0;
14338 static struct eisa_driver advansys_eisa_driver = {
14339 .id_table = advansys_eisa_table,
14340 .driver = {
14341 .name = DRV_NAME,
14342 .probe = advansys_eisa_probe,
14343 .remove = __devexit_p(advansys_eisa_remove),
14347 /* PCI Devices supported by this driver */
14348 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
14349 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14350 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14351 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14352 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14353 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14354 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14355 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14356 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14357 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14358 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14359 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14360 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14364 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
14366 static void __devinit advansys_set_latency(struct pci_dev *pdev)
14368 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14369 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14370 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14371 } else {
14372 u8 latency;
14373 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14374 if (latency < 0x20)
14375 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14379 static int __devinit
14380 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14382 int err, ioport;
14383 struct Scsi_Host *shost;
14384 struct asc_board *board;
14386 err = pci_enable_device(pdev);
14387 if (err)
14388 goto fail;
14389 err = pci_request_regions(pdev, DRV_NAME);
14390 if (err)
14391 goto disable_device;
14392 pci_set_master(pdev);
14393 advansys_set_latency(pdev);
14395 err = -ENODEV;
14396 if (pci_resource_len(pdev, 0) == 0)
14397 goto release_region;
14399 ioport = pci_resource_start(pdev, 0);
14401 err = -ENOMEM;
14402 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14403 if (!shost)
14404 goto release_region;
14406 board = shost_priv(shost);
14407 board->irq = pdev->irq;
14408 board->dev = &pdev->dev;
14410 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14411 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14412 pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
14413 board->flags |= ASC_IS_WIDE_BOARD;
14416 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14417 if (err)
14418 goto free_host;
14420 pci_set_drvdata(pdev, shost);
14421 return 0;
14423 free_host:
14424 scsi_host_put(shost);
14425 release_region:
14426 pci_release_regions(pdev);
14427 disable_device:
14428 pci_disable_device(pdev);
14429 fail:
14430 return err;
14433 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14435 advansys_release(pci_get_drvdata(pdev));
14436 pci_release_regions(pdev);
14437 pci_disable_device(pdev);
14440 static struct pci_driver advansys_pci_driver = {
14441 .name = DRV_NAME,
14442 .id_table = advansys_pci_tbl,
14443 .probe = advansys_pci_probe,
14444 .remove = __devexit_p(advansys_pci_remove),
14447 static int __init advansys_init(void)
14449 int error;
14451 error = isa_register_driver(&advansys_isa_driver,
14452 ASC_IOADR_TABLE_MAX_IX);
14453 if (error)
14454 goto fail;
14456 error = isa_register_driver(&advansys_vlb_driver,
14457 ASC_IOADR_TABLE_MAX_IX);
14458 if (error)
14459 goto unregister_isa;
14461 error = eisa_driver_register(&advansys_eisa_driver);
14462 if (error)
14463 goto unregister_vlb;
14465 error = pci_register_driver(&advansys_pci_driver);
14466 if (error)
14467 goto unregister_eisa;
14469 return 0;
14471 unregister_eisa:
14472 eisa_driver_unregister(&advansys_eisa_driver);
14473 unregister_vlb:
14474 isa_unregister_driver(&advansys_vlb_driver);
14475 unregister_isa:
14476 isa_unregister_driver(&advansys_isa_driver);
14477 fail:
14478 return error;
14481 static void __exit advansys_exit(void)
14483 pci_unregister_driver(&advansys_pci_driver);
14484 eisa_driver_unregister(&advansys_eisa_driver);
14485 isa_unregister_driver(&advansys_vlb_driver);
14486 isa_unregister_driver(&advansys_isa_driver);
14489 module_init(advansys_init);
14490 module_exit(advansys_exit);
14492 MODULE_LICENSE("GPL");