]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/scsi/advansys.c
[SCSI] advansys: Make sdtr_period_tbl a pointer
[mirror_ubuntu-jammy-kernel.git] / drivers / scsi / advansys.c
CommitLineData
01fbfe0b 1#define DRV_NAME "advansys"
8c6af9e1 2#define ASC_VERSION "3.4" /* AdvanSys Driver Version */
1da177e4
LT
3
4/*
5 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6 *
7 * Copyright (c) 1995-2000 Advanced System Products, Inc.
8 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8c6af9e1 9 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
1da177e4
LT
10 * All Rights Reserved.
11 *
8c6af9e1
MW
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.
16 */
17
18/*
1da177e4
LT
19 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
20 * changed its name to ConnectCom Solutions, Inc.
8c6af9e1 21 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
1da177e4
LT
22 */
23
1da177e4 24#include <linux/module.h>
1da177e4
LT
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>
c304ec94 36#include <linux/isa.h>
b09e05a7 37#include <linux/eisa.h>
8c6af9e1 38#include <linux/pci.h>
1da177e4
LT
39#include <linux/spinlock.h>
40#include <linux/dma-mapping.h>
41
42#include <asm/io.h>
43#include <asm/system.h>
44#include <asm/dma.h>
45
8c6af9e1
MW
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>
51
4bd6d7f3 52/* FIXME:
1da177e4 53 *
4bd6d7f3
MW
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
349d2c44
MW
67 * 6. Use scsi_transport_spi
68 * 7. advansys_info is not safe against multiple simultaneous callers
9d0e96eb 69 * 8. Add module_param to override ISA/VLB ioport array
1da177e4
LT
70 */
71#warning this driver is still not properly converted to the DMA API
72
1da177e4
LT
73/* Enable driver /proc statistics. */
74#define ADVANSYS_STATS
75
76/* Enable driver tracing. */
b352f923 77#undef ADVANSYS_DEBUG
1da177e4 78
1da177e4
LT
79/*
80 * Portable Data Types
81 *
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.
87 */
27c868c2
MW
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. */
1da177e4
LT
92
93/*
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.
100 */
101#define ASC_VADDR_TO_U32 virt_to_bus
102#define ASC_U32_TO_VADDR bus_to_virt
103
104typedef unsigned char uchar;
105
106#ifndef TRUE
107#define TRUE (1)
108#endif
109#ifndef FALSE
110#define FALSE (0)
111#endif
112
1da177e4
LT
113#define ERR (-1)
114#define UW_ERR (uint)(0xFFFF)
115#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
1da177e4 116
2672ea86
DJ
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
124
1da177e4
LT
125/*
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.
130 */
131#define CC_VERY_LONG_SG_LIST 0
132#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
133
27c868c2 134#define PortAddr unsigned short /* port address size */
1da177e4
LT
135#define inp(port) inb(port)
136#define outp(port, byte) outb((byte), (port))
137
138#define inpw(port) inw(port)
139#define outpw(port, word) outw((word), (port))
140
141#define ASC_MAX_SG_QUEUE 7
142#define ASC_MAX_SG_LIST 255
143
144#define ASC_CS_TYPE unsigned short
145
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)
1da177e4
LT
154#define ASC_IS_WIDESCSI_16 (0x0100)
155#define ASC_IS_WIDESCSI_32 (0x0200)
156#define ASC_IS_BIG_ENDIAN (0x8000)
95c9f162 157
1da177e4
LT
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)
1da177e4 176#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
1da177e4 177#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
1da177e4 178#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
1da177e4
LT
179
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
1da177e4
LT
189#define ASC_SCSI_RESET_HOLD_TIME_US 60
190
f05ec594
MW
191/*
192 * Narrow boards only support 12-byte commands, while wide boards
193 * extend to 16-byte commands.
194 */
195#define ASC_MAX_CDB_LEN 12
196#define ADV_MAX_CDB_LEN 16
197
1da177e4 198#define MS_SDTR_LEN 0x03
1da177e4 199#define MS_WDTR_LEN 0x02
1da177e4
LT
200
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))
313
314typedef struct asc_scsiq_1 {
27c868c2
MW
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;
1da177e4
LT
326} ASC_SCSIQ_1;
327
328typedef struct asc_scsiq_2 {
27c868c2
MW
329 ASC_VADDR srb_ptr;
330 uchar target_ix;
331 uchar flag;
332 uchar cdb_len;
333 uchar tag_code;
334 ushort vm_id;
1da177e4
LT
335} ASC_SCSIQ_2;
336
337typedef struct asc_scsiq_3 {
27c868c2
MW
338 uchar done_stat;
339 uchar host_stat;
340 uchar scsi_stat;
341 uchar scsi_msg;
1da177e4
LT
342} ASC_SCSIQ_3;
343
344typedef struct asc_scsiq_4 {
27c868c2
MW
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;
1da177e4
LT
354} ASC_SCSIQ_4;
355
356typedef struct asc_q_done_info {
27c868c2
MW
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;
1da177e4
LT
366} ASC_QDONE_INFO;
367
368typedef struct asc_sg_list {
27c868c2
MW
369 ASC_PADDR addr;
370 ASC_DCNT bytes;
1da177e4
LT
371} ASC_SG_LIST;
372
373typedef struct asc_sg_head {
27c868c2
MW
374 ushort entry_cnt;
375 ushort queue_cnt;
376 ushort entry_to_copy;
377 ushort res;
05848b6e 378 ASC_SG_LIST sg_list[0];
1da177e4
LT
379} ASC_SG_HEAD;
380
1da177e4 381typedef struct asc_scsi_q {
27c868c2
MW
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;
1da177e4
LT
388} ASC_SCSI_Q;
389
390typedef struct asc_scsi_req_q {
27c868c2
MW
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];
1da177e4
LT
399} ASC_SCSI_REQ_Q;
400
401typedef struct asc_scsi_bios_req_q {
27c868c2
MW
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];
1da177e4
LT
410} ASC_SCSI_BIOS_REQ_Q;
411
412typedef struct asc_risc_q {
27c868c2
MW
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;
1da177e4
LT
419} ASC_RISC_Q;
420
421typedef struct asc_sg_list_q {
27c868c2
MW
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;
1da177e4
LT
428} ASC_SG_LIST_Q;
429
430typedef struct asc_risc_sg_list_q {
27c868c2
MW
431 uchar fwd;
432 uchar bwd;
433 ASC_SG_LIST_Q sg;
434 ASC_SG_LIST sg_list[7];
1da177e4
LT
435} ASC_RISC_SG_LIST_Q;
436
1da177e4 437#define ASCQ_ERR_Q_STATUS 0x0D
1da177e4
LT
438#define ASCQ_ERR_CUR_QNG 0x17
439#define ASCQ_ERR_SG_Q_LINKS 0x18
1da177e4
LT
440#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
441#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
442#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1da177e4
LT
443
444/*
445 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
446 */
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
1da177e4
LT
455
456/*
720349a8 457 * Error code values are set in {ASC/ADV}_DVC_VAR 'err_code'.
1da177e4 458 */
720349a8
MW
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 */
1da177e4 473
1da177e4
LT
474#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
475#define ASC_MIN_TAG_Q_PER_DVC (0x04)
95c9f162 476#define ASC_MIN_FREE_Q (0x02)
1da177e4
LT
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
1da177e4 483#define ASC_IOADR_GAP 0x10
1da177e4
LT
484#define ASC_SYN_MAX_OFFSET 0x0F
485#define ASC_DEF_SDTR_OFFSET 0x0F
1da177e4 486#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
afbb68c3
MW
487#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
488
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.
492 */
493static const unsigned char asc_syn_xfer_period[8] = {
494 25, 30, 35, 40, 50, 60, 70, 85
495};
496
497static 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
499};
1da177e4
LT
500
501typedef struct ext_msg {
27c868c2
MW
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;
1da177e4
LT
521} EXT_MSG;
522
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
530
531typedef struct asc_dvc_cfg {
27c868c2
MW
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;
27c868c2
MW
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];
27c868c2 545 uchar adapter_info[6];
1da177e4
LT
546} ASC_DVC_CFG;
547
548#define ASC_DEF_DVC_CNTL 0xFFFF
549#define ASC_DEF_CHIP_SCSI_ID 7
550#define ASC_DEF_ISA_DMA_SPEED 4
1da177e4
LT
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
1da177e4
LT
561#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
562#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1da177e4
LT
563#define ASC_MIN_TAGGED_CMD 7
564#define ASC_MAX_SCSI_RESET_WAIT 30
565
27c868c2 566struct asc_dvc_var; /* Forward Declaration. */
1da177e4 567
1da177e4 568typedef struct asc_dvc_var {
27c868c2
MW
569 PortAddr iop_base;
570 ushort err_code;
571 ushort dvc_cntl;
572 ushort bug_fix_cntl;
573 ushort bus_type;
27c868c2
MW
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;
27c868c2
MW
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];
afbb68c3 592 const uchar *sdtr_period_tbl;
27c868c2
MW
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;
afbb68c3 601 uchar min_sdtr_index;
27c868c2 602 uchar max_sdtr_index;
27c868c2
MW
603 struct asc_board *drv_ptr;
604 ASC_DCNT uc_break;
1da177e4
LT
605} ASC_DVC_VAR;
606
607typedef struct asc_dvc_inq_info {
27c868c2 608 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
609} ASC_DVC_INQ_INFO;
610
611typedef struct asc_cap_info {
27c868c2
MW
612 ASC_DCNT lba;
613 ASC_DCNT blk_size;
1da177e4
LT
614} ASC_CAP_INFO;
615
616typedef struct asc_cap_info_array {
27c868c2 617 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
618} ASC_CAP_INFO_ARRAY;
619
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
1da177e4 640#define ASC_EEP_MAX_RETRY 20
1da177e4
LT
641
642/*
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.
647 */
648
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)
655
656typedef struct asceep_config {
27c868c2
MW
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;
1da177e4
LT
674} ASCEEP_CONFIG;
675
1da177e4
LT
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
1da177e4
LT
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
695
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
1da177e4 857#define ASC_EISA_REV_IOP_MASK (0x0C83)
1da177e4
LT
858#define ASC_EISA_CFG_IOP_MASK (0x0C86)
859#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1da177e4
LT
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
866
867typedef struct asc_mc_saved {
27c868c2
MW
868 ushort data[ASC_MC_SAVE_DATA_WSIZE];
869 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
870} ASC_MC_SAVED;
871
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)
51219358
MW
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))
1da177e4
LT
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)
939
1da177e4
LT
940/*
941 * Portable Data Types
942 *
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.
948 */
27c868c2
MW
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. */
1da177e4
LT
953
954/*
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.
961 */
962#define ADV_VADDR_TO_U32 virt_to_bus
963#define ADV_U32_TO_VADDR bus_to_virt
964
27c868c2 965#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
966
967/*
968 * Define Adv Library required memory access macros.
969 */
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)
975
976#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
977
1da177e4
LT
978/*
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.
986 *
987 */
988#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
989
990/*
991 * Define Adv Library required maximum number of scatter-gather
992 * elements per request.
993 */
994#define ADV_MAX_SG_LIST 255
995
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)
999
1000/* Total contiguous memory needed for SG blocks. */
1001#define ADV_SG_TOTAL_MEM_SIZE \
1002 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1003
1004#define ADV_PAGE_SIZE PAGE_SIZE
1005
1006#define ADV_NUM_PAGE_CROSSING \
1007 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1008
1da177e4
LT
1009#define ADV_EEP_DVC_CFG_BEGIN (0x00)
1010#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 1011#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
1012#define ADV_EEP_MAX_WORD_ADDR (0x1E)
1013
1014#define ADV_EEP_DELAY_MS 100
1015
27c868c2
MW
1016#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1017#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
1018/*
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.
1022 */
27c868c2
MW
1023#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1024#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
1025/*
1026 * ASC38C1600 Bit 11
1027 *
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.
1031 *
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.
1035 */
27c868c2
MW
1036#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1037
1038typedef struct adveep_3550_config {
1039 /* Word Offset, Description */
1040
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 */
1053
1054 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1055 uchar bios_boot_delay; /* power up wait */
1056
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 */
1061
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 */
1067
1068 uchar reserved1; /* reserved byte (not used) */
1069
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 */
1da177e4
LT
1105} ADVEEP_3550_CONFIG;
1106
27c868c2
MW
1107typedef struct adveep_38C0800_config {
1108 /* Word Offset, Description */
1109
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 */
1122
1123 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1124 uchar bios_boot_delay; /* power up wait */
1125
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 */
1130
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 */
1136
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 */
1142
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 */
1da177e4
LT
1205} ADVEEP_38C0800_CONFIG;
1206
27c868c2
MW
1207typedef struct adveep_38C1600_config {
1208 /* Word Offset, Description */
1209
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 */
1224
1225 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1226 uchar bios_boot_delay; /* power up wait */
1227
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 */
1232
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 */
1238
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 */
1244
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 */
1da177e4
LT
1307} ADVEEP_38C1600_CONFIG;
1308
1309/*
1310 * EEPROM Commands
1311 */
1312#define ASC_EEP_CMD_DONE 0x0200
1da177e4
LT
1313
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
1327
27c868c2 1328#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1da177e4 1329
27c868c2 1330#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1331
1332/*
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.
1336 *
1337 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1338 */
27c868c2 1339#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1340
1341/*
1342 * Byte I/O register address from base of 'iop_base'.
1343 */
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
1408
1409/*
1410 * Word I/O register address from base of 'iop_base'.
1411 */
27c868c2
MW
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 */
1da177e4 1416#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
1417#define IOPW_RISC_CSR 0x0A /* CSR */
1418#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1419#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 1420#define IOPW_RES_ADDR_10 0x10
27c868c2 1421#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 1422#define IOPW_RES_ADDR_14 0x14
27c868c2 1423#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 1424#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
1425#define IOPW_EE_CMD 0x1A /* EC */
1426#define IOPW_EE_DATA 0x1C /* ED */
1427#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 1428#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
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 */
1da177e4
LT
1434#define IOPW_RES_ADDR_2C 0x2C
1435#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
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 */
1da177e4 1443#define IOPW_RES_ADDR_3C 0x3C
27c868c2 1444#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
1445
1446/*
1447 * Doubleword I/O register address from base of 'iop_base'.
1448 */
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
1465
1466#define ADV_CHIP_ID_BYTE 0x25
1467#define ADV_CHIP_ID_WORD 0x04C1
1468
1da177e4
LT
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
1477
1478#define ADV_INTR_STATUS_INTRA 0x01
1479#define ADV_INTR_STATUS_INTRB 0x02
1480#define ADV_INTR_STATUS_INTRC 0x04
1481
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)
1486
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
1496
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
1502
1503#define ADV_TICKLE_NOP 0x00
1504#define ADV_TICKLE_A 0x01
1505#define ADV_TICKLE_B 0x02
1506#define ADV_TICKLE_C 0x03
1507
1da177e4
LT
1508#define AdvIsIntPending(port) \
1509 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1510
1511/*
1512 * SCSI_CFG0 Register bit definitions
1513 */
27c868c2
MW
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 */
1da177e4
LT
1525
1526/*
1527 * SCSI_CFG1 Register bit definitions
1528 */
27c868c2
MW
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 */
1da177e4
LT
1544
1545/*
1546 * Addendum for ASC-38C0800 Chip
1547 *
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.
1555 */
27c868c2
MW
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 */
1da177e4
LT
1573
1574#define CABLE_ILLEGAL_A 0x7
1575 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1576
1577#define CABLE_ILLEGAL_B 0xB
1578 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1579
1580/*
1581 * MEM_CFG Register bit definitions
1582 */
27c868c2
MW
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 */
1da177e4
LT
1592
1593/*
1594 * DMA_CFG0 Register bit definitions
1595 *
1596 * This register is only accessible to the host.
1597 */
27c868c2
MW
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) */
1da177e4
LT
1616
1617/*
1618 * ASC-38C0800 RAM BIST Register bit definitions
1619 */
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
1632
1633/*
1634 * ASC38C1600 Definitions
1635 *
1636 * IOPB_PCI_INT_CFG Bit Field Definitions
1637 */
1638
27c868c2 1639#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
1640
1641/*
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.
1646 */
1647#define TOTEMPOLE 0x02
1648
1649/*
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.
1654 *
1655 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1656 * value specified in the PCI Configuration Space.
1657 */
1658#define INTAB 0x01
1659
1da177e4
LT
1660/*
1661 * Adv Library Status Definitions
1662 */
1663#define ADV_TRUE 1
1664#define ADV_FALSE 0
1da177e4
LT
1665#define ADV_SUCCESS 1
1666#define ADV_BUSY 0
1667#define ADV_ERROR (-1)
1668
1da177e4
LT
1669/*
1670 * ADV_DVC_VAR 'warn_code' values
1671 */
27c868c2
MW
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 */
27c868c2 1675#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 1676
27c868c2
MW
1677#define ADV_MAX_TID 15 /* max. target identifier */
1678#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4 1679
1da177e4
LT
1680/*
1681 * Fixed locations of microcode operating variables.
1682 */
27c868c2
MW
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 */
1da177e4
LT
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
27c868c2 1713#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 1714#define ASC_MC_WDTR_DONE 0x0124
27c868c2 1715#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
1716#define ASC_MC_ICQ 0x0160
1717#define ASC_MC_IRQ 0x0164
1718#define ASC_MC_PPR_ABLE 0x017A
1719
1720/*
1721 * BIOS LRAM variable absolute offsets.
1722 */
1723#define BIOS_CODESEG 0x54
1724#define BIOS_CODELEN 0x56
1725#define BIOS_SIGNATURE 0x58
1726#define BIOS_VERSION 0x5A
1727
1728/*
1729 * Microcode Control Flags
1730 *
1731 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1732 * and handled by the microcode.
1733 */
27c868c2
MW
1734#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1735#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
1736
1737/*
1738 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1739 */
1740#define HSHK_CFG_WIDE_XFR 0x8000
1741#define HSHK_CFG_RATE 0x0F00
1742#define HSHK_CFG_OFFSET 0x001F
1743
27c868c2
MW
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) */
1748
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 */
1754
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. */
1da177e4
LT
1760/*
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.
1763 */
27c868c2
MW
1764#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
1765#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
1766
1767/*
1768 * All fields here are accessed by the board microcode and need to be
1769 * little-endian.
1770 */
27c868c2
MW
1771typedef 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 */
1775 /*
1776 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
1777 *
1778 * next_vpa [3:1] Reserved Bits
1779 * next_vpa [0] Done Flag set in Response Queue.
1780 */
1781 ADV_VADDR next_vpa;
1da177e4
LT
1782} ADV_CARR_T;
1783
1784/*
1785 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1786 */
1787#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
1788
1789#define ASC_RQ_DONE 0x00000001
1790#define ASC_RQ_GOOD 0x00000002
1791#define ASC_CQ_STOPPER 0x00000000
1792
1793#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1794
1795#define ADV_CARRIER_NUM_PAGE_CROSSING \
1796 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
1797 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1798
1799#define ADV_CARRIER_BUFSIZE \
1800 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1801
1802/*
1803 * ASC_SCSI_REQ_Q 'a_flag' definitions
1804 *
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.
1807 */
27c868c2
MW
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 */
1da177e4 1811
27c868c2
MW
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 */
1da177e4
LT
1815
1816/*
1817 * Adapter temporary configuration structure
1818 *
1819 * This structure can be discarded after initialization. Don't add
1820 * fields here needed after initialization.
1821 *
1822 * Field naming convention:
1823 *
1824 * *_enable indicates the field enables or disables a feature. The
1825 * value of the field is never reset.
1826 */
1827typedef struct adv_dvc_cfg {
27c868c2
MW
1828 ushort disc_enable; /* enable disconnection */
1829 uchar chip_version; /* chip version */
1830 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
27c868c2
MW
1831 ushort control_flag; /* Microcode Control Flag */
1832 ushort mcode_date; /* Microcode date */
1833 ushort mcode_version; /* Microcode version */
27c868c2
MW
1834 ushort serial1; /* EEPROM serial number word 1 */
1835 ushort serial2; /* EEPROM serial number word 2 */
1836 ushort serial3; /* EEPROM serial number word 3 */
1da177e4
LT
1837} ADV_DVC_CFG;
1838
1839struct adv_dvc_var;
1840struct adv_scsi_req_q;
1841
1da177e4
LT
1842/*
1843 * Adapter operation variable structure.
1844 *
1845 * One structure is required per host adapter.
1846 *
1847 * Field naming convention:
1848 *
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.
1853 */
1854typedef struct adv_dvc_var {
27c868c2
MW
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 */
27c868c2
MW
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 */
27c868c2
MW
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. */
1882 /*
1883 * Note: The following fields will not be used after initialization. The
1884 * driver may discard the buffer after initialization is done.
1885 */
1886 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
1887} ADV_DVC_VAR;
1888
1889#define NO_OF_SG_PER_BLOCK 15
1890
1891typedef struct asc_sg_block {
27c868c2
MW
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];
1da177e4
LT
1901} ADV_SG_BLOCK;
1902
1903/*
1904 * ADV_SCSI_REQ_Q - microcode request structure
1905 *
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.
1910 *
1911 * All fields accessed by microcode must be maintained in little_endian
1912 * order.
1913 */
1914typedef struct adv_scsi_req_q {
27c868c2
MW
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;
1937 /*
1938 * End of microcode structure - 60 bytes. The rest of the structure
1939 * is used by the Adv Library and ignored by the microcode.
1940 */
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. */
1da177e4
LT
1946} ADV_SCSI_REQ_Q;
1947
1948/*
1949 * Microcode idle loop commands
1950 */
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
27c868c2
MW
1957#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
1958#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
1959#define IDLE_CMD_SCSIREQ 0x0080
1960
1961#define IDLE_CMD_STATUS_SUCCESS 0x0001
1962#define IDLE_CMD_STATUS_FAILURE 0x0002
1963
1964/*
1965 * AdvSendIdleCmd() flag definitions.
1966 */
1967#define ADV_NOWAIT 0x01
1968
1969/*
1970 * Wait loop time out values.
1971 */
27c868c2
MW
1972#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
1973#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
27c868c2 1974#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 1975
27c868c2
MW
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. */
1da177e4 1980
27c868c2 1981#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4 1982
1da177e4
LT
1983/* Read byte from a register. */
1984#define AdvReadByteRegister(iop_base, reg_off) \
1985 (ADV_MEM_READB((iop_base) + (reg_off)))
1986
1987/* Write byte to a register. */
1988#define AdvWriteByteRegister(iop_base, reg_off, byte) \
1989 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
1990
1991/* Read word (2 bytes) from a register. */
1992#define AdvReadWordRegister(iop_base, reg_off) \
1993 (ADV_MEM_READW((iop_base) + (reg_off)))
1994
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)))
1998
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)))
2002
2003/* Read byte from LRAM. */
2004#define AdvReadByteLram(iop_base, addr, byte) \
2005do { \
2006 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2007 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2008} while (0)
2009
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)))
2014
2015/* Read word (2 bytes) from LRAM. */
2016#define AdvReadWordLram(iop_base, addr, word) \
2017do { \
2018 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2019 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2020} while (0)
2021
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)))
2026
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)))))
2036
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))
2040
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)))
2044
1da177e4
LT
2045/*
2046 * Define macro to check for Condor signature.
2047 *
2048 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2049 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2050 */
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)
2056
2057/*
2058 * Define macro to Return the version number of the chip at 'iop_base'.
2059 *
2060 * The second parameter 'bus_type' is currently unused.
2061 */
2062#define AdvGetChipVersion(iop_base, bus_type) \
2063 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2064
2065/*
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.
2068 *
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.
2072 *
2073 * Return value:
2074 * ADV_TRUE(1) - Queue was successfully aborted.
2075 * ADV_FALSE(0) - Queue was not found on the active queue list.
2076 */
2077#define AdvAbortQueue(asc_dvc, scsiq) \
2078 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2079 (ADV_DCNT) (scsiq))
2080
2081/*
2082 * Send a Bus Device Reset Message to the specified target ID.
2083 *
2084 * All outstanding commands will be purged if sending the
2085 * Bus Device Reset Message is successful.
2086 *
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.
2091 */
2092#define AdvResetDevice(asc_dvc, target_id) \
2093 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2094 (ADV_DCNT) (target_id))
2095
2096/*
2097 * SCSI Wide Type definition.
2098 */
2099#define ADV_SCSI_BIT_ID_TYPE ushort
2100
2101/*
2102 * AdvInitScsiTarget() 'cntl_flag' options.
2103 */
2104#define ADV_SCAN_LUN 0x01
2105#define ADV_CAPINFO_NOLUN 0x02
2106
2107/*
2108 * Convert target id to target id bit mask.
2109 */
2110#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2111
2112/*
2113 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2114 */
2115
27c868c2 2116#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
2117#define QD_NO_ERROR 0x01
2118#define QD_ABORTED_BY_HOST 0x02
2119#define QD_WITH_ERROR 0x04
2120
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
27c868c2
MW
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 */
1da177e4 2133/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
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 */
1da177e4
LT
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
27c868c2
MW
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 */
1da177e4 2149
1da177e4
LT
2150/*
2151 * DvcGetPhyAddr() flag arguments
2152 */
27c868c2
MW
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 */
1da177e4
LT
2159
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)
2164
2165/*
2166 * Total contiguous memory needed for driver SG blocks.
2167 *
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.
2171 */
2172
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))
2176
d2411495 2177/* struct asc_board flags */
27c868c2 2178#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
2179
2180#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
1da177e4 2181
27c868c2 2182#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 2183
27c868c2 2184#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
2185
2186#ifdef CONFIG_PROC_FS
2187/* /proc/scsi/advansys/[0...] related definitions */
2188#define ASC_PRTBUF_SIZE 2048
2189#define ASC_PRTLINE_SIZE 160
2190
2191#define ASC_PRT_NEXT() \
2192 if (cp) { \
2193 totlen += len; \
2194 leftlen -= len; \
2195 if (leftlen == 0) { \
2196 return totlen; \
2197 } \
2198 cp += len; \
2199 }
2200#endif /* CONFIG_PROC_FS */
2201
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)
2208
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)
2214
d2411495 2215#define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
1da177e4 2216#ifndef ADVANSYS_STATS
27c868c2 2217#define ASC_STATS_ADD(shost, counter, count)
1da177e4 2218#else /* ADVANSYS_STATS */
27c868c2 2219#define ASC_STATS_ADD(shost, counter, count) \
d2411495 2220 (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
1da177e4
LT
2221#endif /* ADVANSYS_STATS */
2222
2223#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2224
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)))))
2229
2230/*
2231 * Display a message to the console.
2232 */
2233#define ASC_PRINT(s) \
2234 { \
2235 printk("advansys: "); \
2236 printk(s); \
2237 }
2238
2239#define ASC_PRINT1(s, a1) \
2240 { \
2241 printk("advansys: "); \
2242 printk((s), (a1)); \
2243 }
2244
2245#define ASC_PRINT2(s, a1, a2) \
2246 { \
2247 printk("advansys: "); \
2248 printk((s), (a1), (a2)); \
2249 }
2250
2251#define ASC_PRINT3(s, a1, a2, a3) \
2252 { \
2253 printk("advansys: "); \
2254 printk((s), (a1), (a2), (a3)); \
2255 }
2256
2257#define ASC_PRINT4(s, a1, a2, a3, a4) \
2258 { \
2259 printk("advansys: "); \
2260 printk((s), (a1), (a2), (a3), (a4)); \
2261 }
2262
1da177e4
LT
2263#ifndef ADVANSYS_DEBUG
2264
b352f923 2265#define ASC_DBG(lvl, s...)
1da177e4 2266#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
1da177e4
LT
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)
2275
2276#else /* ADVANSYS_DEBUG */
2277
2278/*
2279 * Debugging Message Levels:
2280 * 0: Errors Only
2281 * 1: High-Level Tracing
2282 * 2-N: Verbose Tracing
2283 */
2284
b352f923
MW
2285#define ASC_DBG(lvl, format, arg...) { \
2286 if (asc_dbglvl >= (lvl)) \
2287 printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \
2288 __FUNCTION__ , ## arg); \
2289}
1da177e4
LT
2290
2291#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2292 { \
2293 if (asc_dbglvl >= (lvl)) { \
2294 asc_prt_scsi_host(s); \
2295 } \
2296 }
2297
1da177e4
LT
2298#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2299 { \
2300 if (asc_dbglvl >= (lvl)) { \
2301 asc_prt_asc_scsi_q(scsiqp); \
2302 } \
2303 }
2304
2305#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2306 { \
2307 if (asc_dbglvl >= (lvl)) { \
2308 asc_prt_asc_qdone_info(qdone); \
2309 } \
2310 }
2311
2312#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2313 { \
2314 if (asc_dbglvl >= (lvl)) { \
2315 asc_prt_adv_scsi_req_q(scsiqp); \
2316 } \
2317 }
2318
2319#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2320 { \
2321 if (asc_dbglvl >= (lvl)) { \
2322 asc_prt_hex((name), (start), (length)); \
2323 } \
2324 }
2325
2326#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2327 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2328
2329#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2330 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2331
2332#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2333 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2334#endif /* ADVANSYS_DEBUG */
2335
1da177e4
LT
2336#ifdef ADVANSYS_STATS
2337
2338/* Per board statistics structure */
2339struct asc_stats {
27c868c2
MW
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 */
1da177e4
LT
2361};
2362#endif /* ADVANSYS_STATS */
2363
1da177e4
LT
2364/*
2365 * Adv Library Request Structures
2366 *
2367 * The following two structures are used to process Wide Board requests.
2368 *
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.
2373 *
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.
2378 *
2379 * Both structures must be 32 byte aligned.
2380 */
2381typedef struct adv_sgblk {
27c868c2
MW
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. */
1da177e4
LT
2385} adv_sgblk_t;
2386
2387typedef struct adv_req {
27c868c2
MW
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. */
1da177e4
LT
2393} adv_req_t;
2394
2395/*
2396 * Structure allocated for each board.
2397 *
8dfb5379 2398 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
2399 * of the 'Scsi_Host' structure starting at the 'hostdata'
2400 * field. It is guaranteed to be allocated from DMA-able memory.
2401 */
d2411495 2402struct asc_board {
394dbf3f 2403 struct device *dev;
27c868c2 2404 uint flags; /* Board flags */
d361db48 2405 unsigned int irq;
27c868c2
MW
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. */
27c868c2 2415 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
27c868c2
MW
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 */
27c868c2
MW
2426 /* /proc/scsi/advansys/[0...] */
2427 char *prtbuf; /* /proc print buffer */
1da177e4 2428#ifdef ADVANSYS_STATS
27c868c2
MW
2429 struct asc_stats asc_stats; /* Board statistics */
2430#endif /* ADVANSYS_STATS */
2431 /*
2432 * The following fields are used only for Narrow Boards.
2433 */
27c868c2
MW
2434 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2435 /*
2436 * The following fields are used only for Wide Boards.
2437 */
2438 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2439 ushort ioport; /* I/O Port address. */
b2c16f58 2440 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
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. */
d2411495 2448};
1da177e4 2449
13ac2d9c
MW
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)
2453
1da177e4 2454/* Overrun buffer used by all narrow boards. */
27c868c2 2455static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4 2456
1da177e4 2457#ifdef ADVANSYS_DEBUG
27c868c2 2458static int asc_dbglvl = 3;
1da177e4 2459
1da177e4 2460/*
51219358 2461 * asc_prt_asc_dvc_var()
1da177e4 2462 */
51219358 2463static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 2464{
51219358 2465 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
27c868c2 2466
51219358
MW
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);
2469
2470 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2471 (unsigned)h->init_sdtr);
2472
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);
2477
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);
2481
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);
2486
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);
2491
d361db48 2492 printk(" cfg 0x%lx\n", (ulong)h->cfg);
1da177e4
LT
2493}
2494
51219358
MW
2495/*
2496 * asc_prt_asc_dvc_cfg()
2497 */
2498static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
6ed1ef07 2499{
51219358 2500 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
6ed1ef07 2501
51219358
MW
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);
6ed1ef07 2506
b08fc565
MW
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);
51219358 2510
b352f923 2511 printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n",
b08fc565 2512 h->mcode_date, h->mcode_version, h->overrun_buf);
6ed1ef07
MW
2513}
2514
1da177e4 2515/*
51219358 2516 * asc_prt_adv_dvc_var()
1da177e4 2517 *
51219358 2518 * Display an ADV_DVC_VAR structure.
1da177e4 2519 */
51219358 2520static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 2521{
51219358 2522 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
27c868c2 2523
51219358
MW
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);
1da177e4 2526
b352f923
MW
2527 printk(" sdtr_able 0x%x, wdtr_able 0x%x\n",
2528 (unsigned)h->sdtr_able, (unsigned)h->wdtr_able);
1da177e4 2529
d361db48
MW
2530 printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n",
2531 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
1da177e4 2532
51219358
MW
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);
1da177e4 2536
51219358
MW
2537 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
2538 (ulong)h->icq_sp, (ulong)h->irq_sp);
1da177e4 2539
51219358
MW
2540 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
2541 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
1da177e4 2542
51219358
MW
2543 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
2544 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2545}
1da177e4 2546
51219358
MW
2547/*
2548 * asc_prt_adv_dvc_cfg()
2549 *
2550 * Display an ADV_DVC_CFG structure.
2551 */
2552static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2553{
2554 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
27c868c2 2555
51219358
MW
2556 printk(" disc_enable 0x%x, termination 0x%x\n",
2557 h->disc_enable, h->termination);
1da177e4 2558
51219358
MW
2559 printk(" chip_version 0x%x, mcode_date 0x%x\n",
2560 h->chip_version, h->mcode_date);
27c868c2 2561
b352f923
MW
2562 printk(" mcode_version 0x%x, control_flag 0x%x\n",
2563 h->mcode_version, h->control_flag);
1da177e4
LT
2564}
2565
2566/*
b352f923 2567 * asc_prt_scsi_host()
1da177e4 2568 */
b352f923 2569static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 2570{
b352f923 2571 struct asc_board *boardp = shost_priv(s);
51219358 2572
b352f923
MW
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);
51219358 2576
b352f923
MW
2577 printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
2578 (ulong)s->base, (ulong)s->io_port, boardp->irq);
51219358 2579
b352f923
MW
2580 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2581 s->dma_channel, s->this_id, s->can_queue);
1da177e4 2582
b352f923
MW
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);
27c868c2 2585
b352f923
MW
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);
074c8fe4 2592 }
1da177e4
LT
2593}
2594
51219358
MW
2595/*
2596 * asc_prt_hex()
2597 *
2598 * Print hexadecimal output in 4 byte groupings 32 bytes
2599 * or 8 double-words per line.
2600 */
2601static void asc_prt_hex(char *f, uchar *s, int l)
47d853cc 2602{
51219358
MW
2603 int i;
2604 int j;
2605 int k;
2606 int m;
47d853cc 2607
51219358
MW
2608 printk("%s: (%d bytes)\n", f, l);
2609
2610 for (i = 0; i < l; i += 32) {
2611
2612 /* Display a maximum of 8 double-words per line. */
2613 if ((k = (l - i) / 4) >= 8) {
2614 k = 8;
2615 m = 0;
47d853cc 2616 } else {
51219358 2617 m = (l - i) % 4;
47d853cc
MW
2618 }
2619
51219358
MW
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]);
47d853cc 2626 }
47d853cc 2627
51219358
MW
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;
2646 }
47d853cc 2647
51219358 2648 printk("\n");
47d853cc
MW
2649 }
2650}
b352f923
MW
2651
2652/*
2653 * asc_prt_asc_scsi_q()
2654 */
2655static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2656{
2657 ASC_SG_HEAD *sgp;
2658 int i;
2659
2660 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2661
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);
2666
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);
2672
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);
2676
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));
2686 }
2687
2688 }
2689}
2690
2691/*
2692 * asc_prt_asc_qdone_info()
2693 */
2694static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2695{
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);
2703}
2704
2705/*
2706 * asc_prt_adv_sgblock()
2707 *
2708 * Display an ADV_SG_BLOCK structure.
2709 */
2710static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2711{
2712 int i;
2713
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);
2725 }
2726}
2727
2728/*
2729 * asc_prt_adv_scsi_req_q()
2730 *
2731 * Display an ADV_SCSI_REQ_Q structure.
2732 */
2733static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2734{
2735 int sg_blk_cnt;
2736 struct asc_sg_block *sg_ptr;
2737
2738 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2739
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);
2742
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);
2745
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);
2749
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);
2753
2754 printk(" sg_working_ix 0x%x, target_cmd %u\n",
2755 q->sg_working_ix, q->target_cmd);
2756
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);
2760
2761 /* Display the request's ADV_SG_BLOCK structures. */
2762 if (q->sg_list_ptr != NULL) {
2763 sg_blk_cnt = 0;
2764 while (1) {
2765 /*
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'.
2769 *
2770 * XXX - Assumes all SG physical blocks are virtually contiguous.
2771 */
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;
2777 }
2778 sg_blk_cnt++;
2779 }
2780 }
2781}
51219358 2782#endif /* ADVANSYS_DEBUG */
47d853cc 2783
1da177e4 2784/*
51219358 2785 * advansys_info()
47d853cc 2786 *
51219358
MW
2787 * Return suitable for printing on the console with the argument
2788 * adapter's configuration information.
2789 *
2790 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2791 * otherwise the static 'info' array will be overrun.
1da177e4 2792 */
51219358 2793static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 2794{
51219358 2795 static char info[ASC_INFO_SIZE];
d2411495 2796 struct asc_board *boardp = shost_priv(shost);
51219358
MW
2797 ASC_DVC_VAR *asc_dvc_varp;
2798 ADV_DVC_VAR *adv_dvc_varp;
2799 char *busname;
2800 char *widename = NULL;
1da177e4 2801
51219358
MW
2802 if (ASC_NARROW_BOARD(boardp)) {
2803 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
b352f923 2804 ASC_DBG(1, "begin\n");
51219358
MW
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";
2811 }
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,
d361db48 2817 boardp->irq, shost->dma_channel);
51219358
MW
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";
2829 }
2830 } else {
2831 busname = "?";
9d0e96eb
MW
2832 shost_printk(KERN_ERR, shost, "unknown bus "
2833 "type %d\n", asc_dvc_varp->bus_type);
51219358
MW
2834 }
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,
d361db48 2839 boardp->irq);
51219358
MW
2840 }
2841 } else {
2842 /*
2843 * Wide Adapter Information
2844 *
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.
2848 */
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";
2856 }
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,
d361db48 2860 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
51219358
MW
2861 }
2862 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
b352f923 2863 ASC_DBG(1, "end\n");
51219358 2864 return info;
47d853cc
MW
2865}
2866
51219358 2867#ifdef CONFIG_PROC_FS
47d853cc 2868/*
51219358 2869 * asc_prt_line()
47d853cc 2870 *
51219358
MW
2871 * If 'cp' is NULL print to the console, otherwise print to a buffer.
2872 *
2873 * Return 0 if printing to the console, otherwise return the number of
2874 * bytes written to the buffer.
2875 *
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.
47d853cc 2878 */
51219358 2879static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
47d853cc 2880{
51219358
MW
2881 va_list args;
2882 int ret;
2883 char s[ASC_PRTLINE_SIZE];
47d853cc 2884
51219358
MW
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);
2894 }
2895 va_end(args);
2896 return ret;
47d853cc
MW
2897}
2898
2899/*
51219358 2900 * asc_prt_board_devices()
47d853cc 2901 *
51219358
MW
2902 * Print driver information for devices attached to the board.
2903 *
2904 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
2905 * cf. asc_prt_line().
2906 *
2907 * Return the number of characters copied into 'cp'. No more than
2908 * 'cplen' characters will be copied to 'cp'.
47d853cc 2909 */
51219358 2910static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
47d853cc 2911{
d2411495 2912 struct asc_board *boardp = shost_priv(shost);
51219358
MW
2913 int leftlen;
2914 int totlen;
2915 int len;
2916 int chip_scsi_id;
2917 int i;
47d853cc 2918
51219358
MW
2919 leftlen = cplen;
2920 totlen = len = 0;
47d853cc 2921
51219358
MW
2922 len = asc_prt_line(cp, leftlen,
2923 "\nDevice Information for AdvanSys SCSI Host %d:\n",
2924 shost->host_no);
2925 ASC_PRT_NEXT();
47d853cc 2926
51219358
MW
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;
47d853cc
MW
2931 }
2932
51219358
MW
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();
2939 }
27c868c2 2940 }
51219358
MW
2941 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
2942 ASC_PRT_NEXT();
2943
2944 return totlen;
47d853cc
MW
2945}
2946
2947/*
51219358 2948 * Display Wide Board BIOS Information.
47d853cc 2949 */
51219358 2950static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
47d853cc 2951{
d2411495 2952 struct asc_board *boardp = shost_priv(shost);
51219358
MW
2953 int leftlen;
2954 int totlen;
2955 int len;
2956 ushort major, minor, letter;
2957
51219358
MW
2958 leftlen = cplen;
2959 totlen = len = 0;
2960
2961 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
2962 ASC_PRT_NEXT();
47d853cc
MW
2963
2964 /*
51219358
MW
2965 * If the BIOS saved a valid signature, then fill in
2966 * the BIOS code segment base address.
47d853cc 2967 */
51219358
MW
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);
47d853cc 2981
51219358
MW
2982 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
2983 major, minor,
2984 letter >= 26 ? '?' : letter + 'A');
2985 ASC_PRT_NEXT();
47d853cc 2986
51219358
MW
2987 /*
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.
2991 */
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();
3000 }
3001 }
3002
3003 return totlen;
1da177e4
LT
3004}
3005
1da177e4 3006/*
51219358
MW
3007 * Add serial number to information bar if signature AAh
3008 * is found in at bit 15-9 (7 bits) of word 1.
1da177e4 3009 *
51219358 3010 * Serial Number consists fo 12 alpha-numeric digits.
1da177e4 3011 *
51219358
MW
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: " "
1da177e4 3016 *
51219358
MW
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)
1da177e4 3020 *
51219358 3021 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
1da177e4 3022 *
51219358 3023 * Note 1: Only production cards will have a serial number.
1da177e4 3024 *
51219358 3025 * Note 2: Signature is most significant 7 bits (0xFE).
1da177e4 3026 *
51219358 3027 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
1da177e4 3028 */
51219358 3029static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 3030{
51219358 3031 ushort w, num;
27c868c2 3032
51219358
MW
3033 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3034 return ASC_FALSE;
3035 } else {
3036 /*
3037 * First word - 6 digits.
3038 */
3039 w = serialnum[0];
27c868c2 3040
51219358
MW
3041 /* Product type - 1st digit. */
3042 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3043 /* Product type is P=Prototype */
3044 *cp += 0x8;
3045 }
3046 cp++;
3047
3048 /* Manufacturing location - 2nd digit. */
3049 *cp++ = 'A' + ((w & 0x1C00) >> 10);
3050
3051 /* Product ID - 3rd, 4th digits. */
3052 num = w & 0x3FF;
3053 *cp++ = '0' + (num / 100);
3054 num %= 100;
3055 *cp++ = '0' + (num / 10);
3056
3057 /* Product revision - 5th digit. */
3058 *cp++ = 'A' + (num % 10);
27c868c2 3059
27c868c2 3060 /*
51219358 3061 * Second word
27c868c2 3062 */
51219358 3063 w = serialnum[1];
27c868c2
MW
3064
3065 /*
51219358 3066 * Year - 6th digit.
27c868c2 3067 *
51219358
MW
3068 * If bit 15 of third word is set, then the
3069 * last digit of the year is greater than 7.
27c868c2 3070 */
51219358
MW
3071 if (serialnum[2] & 0x8000) {
3072 *cp++ = '8' + ((w & 0x1C0) >> 6);
3073 } else {
3074 *cp++ = '0' + ((w & 0x1C0) >> 6);
27c868c2
MW
3075 }
3076
51219358
MW
3077 /* Week of year - 7th, 8th digits. */
3078 num = w & 0x003F;
3079 *cp++ = '0' + num / 10;
3080 num %= 10;
3081 *cp++ = '0' + num;
27c868c2
MW
3082
3083 /*
51219358 3084 * Third word
27c868c2 3085 */
51219358 3086 w = serialnum[2] & 0x7FFF;
1da177e4 3087
51219358
MW
3088 /* Serial number - 9th digit. */
3089 *cp++ = 'A' + (w / 1000);
27c868c2 3090
51219358
MW
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;
3098
3099 *cp = '\0'; /* Null Terminate the string. */
3100 return ASC_TRUE;
3101 }
1da177e4
LT
3102}
3103
3104/*
51219358 3105 * asc_prt_asc_board_eeprom()
1da177e4 3106 *
51219358 3107 * Print board EEPROM configuration.
1da177e4 3108 *
51219358
MW
3109 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3110 * cf. asc_prt_line().
3111 *
3112 * Return the number of characters copied into 'cp'. No more than
3113 * 'cplen' characters will be copied to 'cp'.
1da177e4 3114 */
51219358 3115static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3116{
d2411495 3117 struct asc_board *boardp = shost_priv(shost);
51219358
MW
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];
27c868c2 3128
51219358
MW
3129 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3130 ep = &boardp->eep_config.asc_eep;
27c868c2 3131
51219358
MW
3132 leftlen = cplen;
3133 totlen = len = 0;
27c868c2 3134
51219358
MW
3135 len = asc_prt_line(cp, leftlen,
3136 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3137 shost->host_no);
3138 ASC_PRT_NEXT();
1da177e4 3139
51219358
MW
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();
27c868c2 3146 } else {
51219358
MW
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();
27c868c2 3155 }
51219358 3156 }
27c868c2 3157
51219358
MW
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();
1da177e4 3163
51219358
MW
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();
27c868c2 3167
51219358
MW
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();
3173 }
3174 len = asc_prt_line(cp, leftlen, "\n");
3175 ASC_PRT_NEXT();
1da177e4 3176
51219358
MW
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();
27c868c2 3185 }
51219358
MW
3186 len = asc_prt_line(cp, leftlen, "\n");
3187 ASC_PRT_NEXT();
1da177e4 3188
51219358
MW
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();
3197 }
3198 len = asc_prt_line(cp, leftlen, "\n");
3199 ASC_PRT_NEXT();
1da177e4 3200
51219358
MW
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();
3209 }
3210 len = asc_prt_line(cp, leftlen, "\n");
3211 ASC_PRT_NEXT();
3212
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();
3221 }
3222 len = asc_prt_line(cp, leftlen, "\n");
3223 ASC_PRT_NEXT();
3224
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();
3231 }
3232#endif /* CONFIG_ISA */
3233
3234 return totlen;
1da177e4
LT
3235}
3236
3237/*
51219358 3238 * asc_prt_adv_board_eeprom()
1da177e4 3239 *
51219358 3240 * Print board EEPROM configuration.
1da177e4 3241 *
51219358
MW
3242 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3243 * cf. asc_prt_line().
3244 *
3245 * Return the number of characters copied into 'cp'. No more than
3246 * 'cplen' characters will be copied to 'cp'.
1da177e4 3247 */
51219358 3248static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3249{
d2411495 3250 struct asc_board *boardp = shost_priv(shost);
51219358
MW
3251 ADV_DVC_VAR *adv_dvc_varp;
3252 int leftlen;
3253 int totlen;
3254 int len;
27c868c2 3255 int i;
51219358
MW
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;
27c868c2 3264
51219358
MW
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;
27c868c2 3270 } else {
51219358 3271 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
27c868c2 3272 }
1da177e4 3273
51219358
MW
3274 leftlen = cplen;
3275 totlen = len = 0;
27c868c2 3276
51219358
MW
3277 len = asc_prt_line(cp, leftlen,
3278 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3279 shost->host_no);
3280 ASC_PRT_NEXT();
27c868c2 3281
51219358
MW
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;
3288 }
27c868c2 3289
51219358
MW
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();
3299 }
27c868c2 3300
51219358
MW
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();
27c868c2 3321 }
51219358
MW
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;
3328 }
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;
27c868c2 3343 }
1da177e4 3344
51219358
MW
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();
3363 }
1da177e4 3364
51219358
MW
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();
3370 }
3371 len = asc_prt_line(cp, leftlen, "\n");
3372 ASC_PRT_NEXT();
1da177e4 3373
51219358
MW
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;
3380 }
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();
3387 }
3388 len = asc_prt_line(cp, leftlen, "\n");
3389 ASC_PRT_NEXT();
1da177e4 3390
51219358
MW
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;
3397 }
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();
3404 }
3405 len = asc_prt_line(cp, leftlen, "\n");
3406 ASC_PRT_NEXT();
1da177e4 3407
51219358
MW
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;
27c868c2 3412 } else {
51219358
MW
3413 word = ep_38C1600->start_motor;
3414 }
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();
3421 }
3422 len = asc_prt_line(cp, leftlen, "\n");
3423 ASC_PRT_NEXT();
27c868c2 3424
51219358
MW
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();
27c868c2 3434 }
51219358
MW
3435 len = asc_prt_line(cp, leftlen, "\n");
3436 ASC_PRT_NEXT();
3437 }
27c868c2 3438
51219358
MW
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();
27c868c2 3448 }
51219358
MW
3449 len = asc_prt_line(cp, leftlen, "\n");
3450 ASC_PRT_NEXT();
3451 }
27c868c2 3452
51219358
MW
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;
3459 }
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();
27c868c2 3466 }
51219358
MW
3467 len = asc_prt_line(cp, leftlen, "\n");
3468 ASC_PRT_NEXT();
1da177e4 3469
51219358
MW
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;
1da177e4 3477
51219358
MW
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;
3486 }
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;
3509 }
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();
3515 }
3516 sdtr_speed >>= 4;
3517 }
3518 len = asc_prt_line(cp, leftlen, "\n");
3519 ASC_PRT_NEXT();
3520 }
1da177e4 3521
51219358 3522 return totlen;
1da177e4
LT
3523}
3524
3525/*
51219358 3526 * asc_prt_driver_conf()
1da177e4 3527 *
51219358
MW
3528 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3529 * cf. asc_prt_line().
1da177e4 3530 *
51219358
MW
3531 * Return the number of characters copied into 'cp'. No more than
3532 * 'cplen' characters will be copied to 'cp'.
1da177e4 3533 */
51219358 3534static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3535{
d2411495 3536 struct asc_board *boardp = shost_priv(shost);
51219358
MW
3537 int leftlen;
3538 int totlen;
3539 int len;
3540 int chip_scsi_id;
27c868c2 3541
51219358
MW
3542 leftlen = cplen;
3543 totlen = len = 0;
27c868c2 3544
51219358
MW
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();
95c9f162 3549
51219358
MW
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();
95c9f162 3555
51219358
MW
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();
95c9f162 3561
51219358
MW
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();
27c868c2 3566
51219358
MW
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();
27c868c2 3572
51219358
MW
3573 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3574 ASC_PRT_NEXT();
27c868c2 3575
51219358
MW
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;
27c868c2 3580 }
51219358
MW
3581
3582 return totlen;
1da177e4
LT
3583}
3584
3585/*
51219358 3586 * asc_prt_asc_board_info()
1da177e4 3587 *
51219358
MW
3588 * Print dynamic board configuration information.
3589 *
3590 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3591 * cf. asc_prt_line().
3592 *
3593 * Return the number of characters copied into 'cp'. No more than
3594 * 'cplen' characters will be copied to 'cp'.
1da177e4 3595 */
51219358 3596static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3597{
d2411495 3598 struct asc_board *boardp = shost_priv(shost);
51219358
MW
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;
27c868c2 3607
51219358
MW
3608 v = &boardp->dvc_var.asc_dvc_var;
3609 c = &boardp->dvc_cfg.asc_dvc_cfg;
3610 chip_scsi_id = c->chip_scsi_id;
27c868c2 3611
51219358
MW
3612 leftlen = cplen;
3613 totlen = len = 0;
27c868c2 3614
51219358
MW
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();
27c868c2 3619
b08fc565
MW
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);
51219358 3624 ASC_PRT_NEXT();
1da177e4 3625
51219358
MW
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();
1da177e4 3630
51219358
MW
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;
27c868c2 3637 }
51219358
MW
3638 len = asc_prt_line(cp, leftlen, " %X:%c",
3639 i,
3640 (v->
3641 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3642 'Y' : 'N');
3643 ASC_PRT_NEXT();
3644 }
3645 len = asc_prt_line(cp, leftlen, "\n");
3646 ASC_PRT_NEXT();
27c868c2 3647
51219358
MW
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;
27c868c2 3655 }
51219358
MW
3656 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3657 ASC_PRT_NEXT();
27c868c2 3658 }
51219358
MW
3659 len = asc_prt_line(cp, leftlen, "\n");
3660 ASC_PRT_NEXT();
1da177e4 3661
51219358
MW
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;
3669 }
3670 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3671 ASC_PRT_NEXT();
27c868c2 3672 }
51219358
MW
3673 len = asc_prt_line(cp, leftlen, "\n");
3674 ASC_PRT_NEXT();
1da177e4 3675
51219358
MW
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;
3683 }
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);
3689 }
3690 ASC_PRT_NEXT();
3691 }
3692 len = asc_prt_line(cp, leftlen, "\n");
3693 ASC_PRT_NEXT();
1da177e4 3694
51219358
MW
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;
3701 }
3702 len = asc_prt_line(cp, leftlen, " %X:%c",
3703 i,
3704 (v->
3705 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3706 'N');
3707 ASC_PRT_NEXT();
27c868c2 3708 }
51219358
MW
3709 len = asc_prt_line(cp, leftlen, "\n");
3710 ASC_PRT_NEXT();
1da177e4 3711
51219358
MW
3712 for (i = 0; i <= ASC_MAX_TID; i++) {
3713 uchar syn_period_ix;
1da177e4 3714
51219358
MW
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;
27c868c2 3719 }
27c868c2 3720
51219358
MW
3721 len = asc_prt_line(cp, leftlen, " %X:", i);
3722 ASC_PRT_NEXT();
27c868c2 3723
51219358
MW
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 -
3730 1);
27c868c2 3731
51219358
MW
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,
3738 v->
3739 sdtr_period_tbl
3740 [syn_period_ix]));
3741 ASC_PRT_NEXT();
27c868c2 3742
51219358
MW
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();
3747 }
1da177e4 3748
51219358
MW
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");
3754 }
3755 ASC_PRT_NEXT();
27c868c2 3756 }
1da177e4 3757
51219358
MW
3758 if (renegotiate) {
3759 len = asc_prt_line(cp, leftlen,
3760 " * = Re-negotiation pending before next command.\n");
3761 ASC_PRT_NEXT();
27c868c2 3762 }
1da177e4 3763
51219358 3764 return totlen;
1da177e4
LT
3765}
3766
1da177e4 3767/*
51219358 3768 * asc_prt_adv_board_info()
1da177e4 3769 *
51219358 3770 * Print dynamic board configuration information.
1da177e4
LT
3771 *
3772 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3773 * cf. asc_prt_line().
3774 *
3775 * Return the number of characters copied into 'cp'. No more than
3776 * 'cplen' characters will be copied to 'cp'.
3777 */
51219358 3778static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3779{
d2411495 3780 struct asc_board *boardp = shost_priv(shost);
27c868c2
MW
3781 int leftlen;
3782 int totlen;
3783 int len;
27c868c2 3784 int i;
51219358
MW
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;
27c868c2 3796
51219358
MW
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;
3801
27c868c2
MW
3802 leftlen = cplen;
3803 totlen = len = 0;
3804
3805 len = asc_prt_line(cp, leftlen,
51219358 3806 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
27c868c2
MW
3807 shost->host_no);
3808 ASC_PRT_NEXT();
3809
51219358
MW
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();
1da177e4 3817
b08fc565
MW
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);
51219358
MW
3821 ASC_PRT_NEXT();
3822
3823 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3824 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
27c868c2
MW
3825 ASC_PRT_NEXT();
3826 for (i = 0; i <= ADV_MAX_TID; i++) {
51219358
MW
3827 if ((chip_scsi_id == i) ||
3828 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3829 continue;
27c868c2 3830 }
51219358
MW
3831
3832 len = asc_prt_line(cp, leftlen, " %X:%c",
3833 i,
3834 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3835 'N');
3836 ASC_PRT_NEXT();
27c868c2 3837 }
51219358 3838 len = asc_prt_line(cp, leftlen, "\n");
27c868c2 3839 ASC_PRT_NEXT();
1da177e4 3840
51219358
MW
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;
3847 }
1da177e4 3848
51219358
MW
3849 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3850 lrambyte);
27c868c2 3851
51219358
MW
3852 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3853 ASC_PRT_NEXT();
3854 }
3855 len = asc_prt_line(cp, leftlen, "\n");
3856 ASC_PRT_NEXT();
27c868c2 3857
51219358 3858 len = asc_prt_line(cp, leftlen, " Command Pending:");
27c868c2 3859 ASC_PRT_NEXT();
51219358
MW
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;
3864 }
27c868c2 3865
51219358
MW
3866 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
3867 lrambyte);
1da177e4 3868
51219358 3869 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
27c868c2 3870 ASC_PRT_NEXT();
51219358
MW
3871 }
3872 len = asc_prt_line(cp, leftlen, "\n");
3873 ASC_PRT_NEXT();
1da177e4 3874
51219358
MW
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;
27c868c2 3882 }
51219358
MW
3883
3884 len = asc_prt_line(cp, leftlen, " %X:%c",
3885 i,
3886 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3887 'N');
3888 ASC_PRT_NEXT();
27c868c2 3889 }
51219358
MW
3890 len = asc_prt_line(cp, leftlen, "\n");
3891 ASC_PRT_NEXT();
1da177e4 3892
51219358
MW
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;
3900 }
1da177e4 3901
51219358
MW
3902 AdvReadWordLram(iop_base,
3903 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3904 lramword);
27c868c2 3905
51219358
MW
3906 len = asc_prt_line(cp, leftlen, " %X:%d",
3907 i, (lramword & 0x8000) ? 16 : 8);
3908 ASC_PRT_NEXT();
27c868c2 3909
51219358
MW
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;
27c868c2 3915 }
51219358
MW
3916 }
3917 len = asc_prt_line(cp, leftlen, "\n");
3918 ASC_PRT_NEXT();
27c868c2 3919
51219358
MW
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;
3927 }
27c868c2 3928
51219358
MW
3929 len = asc_prt_line(cp, leftlen, " %X:%c",
3930 i,
3931 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3932 'N');
3933 ASC_PRT_NEXT();
3934 }
3935 len = asc_prt_line(cp, leftlen, "\n");
3936 ASC_PRT_NEXT();
27c868c2 3937
51219358
MW
3938 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
3939 for (i = 0; i <= ADV_MAX_TID; i++) {
27c868c2 3940
51219358
MW
3941 AdvReadWordLram(iop_base,
3942 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3943 lramword);
3944 lramword &= ~0x8000;
27c868c2 3945
51219358
MW
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;
27c868c2
MW
3950 }
3951
51219358
MW
3952 len = asc_prt_line(cp, leftlen, " %X:", i);
3953 ASC_PRT_NEXT();
27c868c2 3954
51219358
MW
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();
27c868c2 3963
51219358
MW
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. */
27c868c2 3973
51219358
MW
3974 period = (((lramword >> 8) * 25) + 50) / 4;
3975
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();
3988 }
3989 }
3990
3991 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3992 lramword & 0x1F);
3993 ASC_PRT_NEXT();
3994 }
3995
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");
4001 }
4002 ASC_PRT_NEXT();
27c868c2 4003 }
51219358
MW
4004
4005 if (renegotiate) {
4006 len = asc_prt_line(cp, leftlen,
4007 " * = Re-negotiation pending before next command.\n");
4008 ASC_PRT_NEXT();
4009 }
4010
4011 return totlen;
1da177e4
LT
4012}
4013
4014/*
51219358 4015 * asc_proc_copy()
1da177e4 4016 *
51219358
MW
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.
4019 */
4020static int
4021asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4022 char *cp, int cplen)
4023{
4024 int cnt = 0;
4025
b352f923 4026 ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n",
51219358
MW
4027 (unsigned)offset, (unsigned)advoffset, cplen);
4028 if (offset <= advoffset) {
4029 /* Read offset below current offset, copy everything. */
4030 cnt = min(cplen, leftlen);
b352f923 4031 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
51219358
MW
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);
b352f923 4039 ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
51219358
MW
4040 (ulong)curbuf, (ulong)cp, cnt);
4041 memcpy(curbuf, cp, cnt);
4042 }
4043 return cnt;
4044}
4045
4046#ifdef ADVANSYS_STATS
4047/*
4048 * asc_prt_board_stats()
1da177e4
LT
4049 *
4050 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4051 * cf. asc_prt_line().
4052 *
4053 * Return the number of characters copied into 'cp'. No more than
4054 * 'cplen' characters will be copied to 'cp'.
4055 */
51219358 4056static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4057{
d2411495
MW
4058 struct asc_board *boardp = shost_priv(shost);
4059 struct asc_stats *s = &boardp->asc_stats;
27c868c2 4060
d2411495
MW
4061 int leftlen = cplen;
4062 int len, totlen = 0;
51219358 4063
27c868c2 4064 len = asc_prt_line(cp, leftlen,
51219358 4065 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
27c868c2
MW
4066 shost->host_no);
4067 ASC_PRT_NEXT();
4068
27c868c2 4069 len = asc_prt_line(cp, leftlen,
51219358
MW
4070 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4071 s->queuecommand, s->reset, s->biosparam,
4072 s->interrupt);
27c868c2
MW
4073 ASC_PRT_NEXT();
4074
4075 len = asc_prt_line(cp, leftlen,
51219358
MW
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);
27c868c2
MW
4079 ASC_PRT_NEXT();
4080
51219358
MW
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);
27c868c2 4085 ASC_PRT_NEXT();
51219358
MW
4086
4087 /*
4088 * Display data transfer statistics.
4089 */
4090 if (s->cont_cnt > 0) {
4091 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
27c868c2 4092 ASC_PRT_NEXT();
27c868c2 4093
51219358
MW
4094 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
4095 s->cont_xfer / 2,
4096 ASC_TENTHS(s->cont_xfer, 2));
27c868c2 4097 ASC_PRT_NEXT();
27c868c2 4098
51219358
MW
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));
27c868c2
MW
4103 ASC_PRT_NEXT();
4104 }
27c868c2 4105
51219358
MW
4106 if (s->sg_cnt > 0) {
4107
4108 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
4109 s->sg_cnt, s->sg_elem);
27c868c2 4110 ASC_PRT_NEXT();
27c868c2 4111
51219358
MW
4112 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
4113 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
27c868c2 4114 ASC_PRT_NEXT();
1da177e4 4115
51219358
MW
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();
4121
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();
4126
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));
27c868c2
MW
4130 ASC_PRT_NEXT();
4131 }
51219358
MW
4132
4133 /*
4134 * Display request queuing statistics.
4135 */
4136 len = asc_prt_line(cp, leftlen,
4137 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
4138 HZ);
4139 ASC_PRT_NEXT();
1da177e4 4140
27c868c2 4141 return totlen;
1da177e4 4142}
51219358 4143#endif /* ADVANSYS_STATS */
1da177e4
LT
4144
4145/*
51219358 4146 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4 4147 *
51219358
MW
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
1da177e4 4154 *
51219358
MW
4155 * Return the number of bytes read from or written to a
4156 * /proc/scsi/advansys/[0...] file.
1da177e4 4157 *
51219358
MW
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.
1da177e4 4164 */
51219358
MW
4165static int
4166advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4167 off_t offset, int length, int inout)
1da177e4 4168{
d2411495 4169 struct asc_board *boardp = shost_priv(shost);
51219358
MW
4170 char *cp;
4171 int cplen;
4172 int cnt;
4173 int totcnt;
27c868c2 4174 int leftlen;
51219358
MW
4175 char *curbuf;
4176 off_t advoffset;
27c868c2 4177
b352f923 4178 ASC_DBG(1, "begin\n");
51219358
MW
4179
4180 /*
4181 * User write not supported.
4182 */
d2411495
MW
4183 if (inout == TRUE)
4184 return -ENOSYS;
1da177e4 4185
51219358
MW
4186 /*
4187 * User read of /proc/scsi/advansys/[0...] file.
4188 */
1da177e4 4189
51219358
MW
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;
4196
4197 /*
4198 * Get board configuration information.
4199 *
4200 * advansys_info() returns the board string from its own static buffer.
4201 */
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) {
b352f923 4210 ASC_DBG(1, "totcnt %d\n", totcnt);
51219358 4211 return totcnt;
27c868c2 4212 }
51219358
MW
4213 advoffset += cplen;
4214 curbuf += cnt;
1da177e4 4215
51219358
MW
4216 /*
4217 * Display Wide Board BIOS Information.
4218 */
9a256fa5 4219 if (!ASC_NARROW_BOARD(boardp)) {
51219358
MW
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) {
b352f923 4228 ASC_DBG(1, "totcnt %d\n", totcnt);
51219358
MW
4229 return totcnt;
4230 }
4231 advoffset += cplen;
4232 curbuf += cnt;
27c868c2 4233 }
1da177e4 4234
51219358
MW
4235 /*
4236 * Display driver information for each device attached to the board.
4237 */
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) {
b352f923 4245 ASC_DBG(1, "totcnt %d\n", totcnt);
51219358 4246 return totcnt;
27c868c2 4247 }
51219358
MW
4248 advoffset += cplen;
4249 curbuf += cnt;
4250
4251 /*
4252 * Display EEPROM configuration for the board.
4253 */
4254 cp = boardp->prtbuf;
4255 if (ASC_NARROW_BOARD(boardp)) {
4256 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4257 } else {
51219358 4258 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4259 }
51219358
MW
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) {
b352f923 4265 ASC_DBG(1, "totcnt %d\n", totcnt);
51219358 4266 return totcnt;
27c868c2 4267 }
51219358
MW
4268 advoffset += cplen;
4269 curbuf += cnt;
1da177e4 4270
51219358
MW
4271 /*
4272 * Display driver configuration and information for the board.
4273 */
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) {
b352f923 4281 ASC_DBG(1, "totcnt %d\n", totcnt);
51219358 4282 return totcnt;
27c868c2 4283 }
51219358
MW
4284 advoffset += cplen;
4285 curbuf += cnt;
1da177e4 4286
51219358
MW
4287#ifdef ADVANSYS_STATS
4288 /*
4289 * Display driver statistics for the board.
4290 */
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) {
b352f923 4298 ASC_DBG(1, "totcnt %d\n", totcnt);
51219358 4299 return totcnt;
27c868c2 4300 }
51219358
MW
4301 advoffset += cplen;
4302 curbuf += cnt;
4303#endif /* ADVANSYS_STATS */
1da177e4 4304
51219358
MW
4305 /*
4306 * Display Asc Library dynamic configuration information
4307 * for the board.
4308 */
4309 cp = boardp->prtbuf;
4310 if (ASC_NARROW_BOARD(boardp)) {
4311 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4312 } else {
51219358 4313 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4314 }
51219358
MW
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) {
b352f923 4320 ASC_DBG(1, "totcnt %d\n", totcnt);
51219358 4321 return totcnt;
27c868c2 4322 }
51219358
MW
4323 advoffset += cplen;
4324 curbuf += cnt;
1da177e4 4325
b352f923 4326 ASC_DBG(1, "totcnt %d\n", totcnt);
27c868c2 4327
51219358
MW
4328 return totcnt;
4329}
4330#endif /* CONFIG_PROC_FS */
4331
4332static void asc_scsi_done(struct scsi_cmnd *scp)
4333{
d2411495 4334 struct asc_board *boardp = shost_priv(scp->device->host);
51219358
MW
4335
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);
4343
4344 ASC_STATS(scp->device->host, done);
4345
4346 scp->scsi_done(scp);
4347}
4348
4349static void AscSetBank(PortAddr iop_base, uchar bank)
4350{
4351 uchar val;
4352
4353 val = AscGetChipControl(iop_base) &
4354 (~
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;
27c868c2 4361 } else {
51219358 4362 val &= ~CC_BANK_ONE;
27c868c2 4363 }
51219358 4364 AscSetChipControl(iop_base, val);
51219358
MW
4365}
4366
4367static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4368{
4369 AscSetBank(iop_base, 1);
4370 AscWriteChipIH(iop_base, ins_code);
4371 AscSetBank(iop_base, 0);
51219358
MW
4372}
4373
4374static int AscStartChip(PortAddr iop_base)
4375{
4376 AscSetChipControl(iop_base, 0);
4377 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4378 return (0);
27c868c2 4379 }
51219358
MW
4380 return (1);
4381}
27c868c2 4382
51219358
MW
4383static int AscStopChip(PortAddr iop_base)
4384{
4385 uchar cc_val;
4386
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);
27c868c2 4395 }
51219358
MW
4396 return (1);
4397}
27c868c2 4398
51219358
MW
4399static int AscIsChipHalted(PortAddr iop_base)
4400{
4401 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4402 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4403 return (1);
27c868c2 4404 }
27c868c2 4405 }
51219358
MW
4406 return (0);
4407}
27c868c2 4408
51219358
MW
4409static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4410{
4411 PortAddr iop_base;
4412 int i = 10;
4413
4414 iop_base = asc_dvc->iop_base;
4415 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4416 && (i-- > 0)) {
4417 mdelay(100);
27c868c2 4418 }
51219358
MW
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));
4430}
27c868c2 4431
51219358
MW
4432static int AscFindSignature(PortAddr iop_base)
4433{
4434 ushort sig_word;
27c868c2 4435
b352f923 4436 ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n",
51219358
MW
4437 iop_base, AscGetChipSignatureByte(iop_base));
4438 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
b352f923 4439 ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n",
51219358
MW
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);
27c868c2 4445 }
27c868c2 4446 }
51219358 4447 return (0);
27c868c2
MW
4448}
4449
51219358 4450static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 4451{
51219358 4452 ushort cfg;
27c868c2 4453
51219358
MW
4454 cfg = AscGetChipCfgLsw(iop_base);
4455 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
51219358 4456}
27c868c2 4457
51219358
MW
4458static void AscDisableInterrupt(PortAddr iop_base)
4459{
4460 ushort cfg;
27c868c2 4461
51219358
MW
4462 cfg = AscGetChipCfgLsw(iop_base);
4463 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
51219358 4464}
27c868c2 4465
51219358
MW
4466static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4467{
4468 unsigned char byte_data;
4469 unsigned short word_data;
27c868c2 4470
51219358
MW
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;
4479 }
4480 return byte_data;
4481}
27c868c2 4482
51219358
MW
4483static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4484{
4485 ushort word_data;
27c868c2 4486
51219358
MW
4487 AscSetChipLramAddr(iop_base, addr);
4488 word_data = AscGetChipLramData(iop_base);
4489 return (word_data);
4490}
27c868c2 4491
51219358
MW
4492#if CC_VERY_LONG_SG_LIST
4493static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4494{
4495 ushort val_low, val_high;
4496 ASC_DCNT dword_data;
27c868c2 4497
51219358
MW
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);
4503}
4504#endif /* CC_VERY_LONG_SG_LIST */
4505
4506static void
4507AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4508{
4509 int i;
4510
4511 AscSetChipLramAddr(iop_base, s_addr);
4512 for (i = 0; i < words; i++) {
4513 AscSetChipLramData(iop_base, set_wval);
27c868c2 4514 }
51219358 4515}
1da177e4 4516
51219358
MW
4517static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4518{
4519 AscSetChipLramAddr(iop_base, addr);
4520 AscSetChipLramData(iop_base, word_val);
51219358
MW
4521}
4522
4523static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4524{
4525 ushort word_data;
4526
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);
4536 }
4537 AscWriteLramWord(iop_base, addr, word_data);
1da177e4
LT
4538}
4539
4540/*
51219358 4541 * Copy 2 bytes to LRAM.
1da177e4 4542 *
51219358
MW
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.
1da177e4 4545 */
51219358
MW
4546static void
4547AscMemWordCopyPtrToLram(PortAddr iop_base,
4548 ushort s_addr, uchar *s_buffer, int words)
1da177e4 4549{
27c868c2 4550 int i;
27c868c2 4551
51219358
MW
4552 AscSetChipLramAddr(iop_base, s_addr);
4553 for (i = 0; i < 2 * words; i += 2) {
4554 /*
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.
4561 */
4562 outpw(iop_base + IOP_RAM_DATA,
4563 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4564 }
51219358 4565}
27c868c2 4566
51219358
MW
4567/*
4568 * Copy 4 bytes to LRAM.
4569 *
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.
4572 */
4573static void
4574AscMemDWordCopyPtrToLram(PortAddr iop_base,
4575 ushort s_addr, uchar *s_buffer, int dwords)
4576{
4577 int i;
27c868c2 4578
51219358
MW
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 */
4583 }
51219358 4584}
27c868c2 4585
51219358
MW
4586/*
4587 * Copy 2 bytes from LRAM.
4588 *
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.
4591 */
4592static void
4593AscMemWordCopyPtrFromLram(PortAddr iop_base,
4594 ushort s_addr, uchar *d_buffer, int words)
4595{
4596 int i;
4597 ushort word;
27c868c2 4598
51219358
MW
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;
27c868c2 4604 }
51219358 4605}
27c868c2 4606
51219358
MW
4607static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4608{
4609 ASC_DCNT sum;
4610 int i;
27c868c2 4611
51219358
MW
4612 sum = 0L;
4613 for (i = 0; i < words; i++, s_addr += 2) {
4614 sum += AscReadLramWord(iop_base, s_addr);
27c868c2 4615 }
51219358
MW
4616 return (sum);
4617}
27c868c2 4618
51219358
MW
4619static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4620{
4621 uchar i;
4622 ushort s_addr;
4623 PortAddr iop_base;
4624 ushort warn_code;
27c868c2 4625
51219358
MW
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);
27c868c2 4648 }
51219358
MW
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);
27c868c2 4665 }
51219358 4666 return warn_code;
1da177e4
LT
4667}
4668
51219358
MW
4669static ASC_DCNT
4670AscLoadMicroCode(PortAddr iop_base,
4671 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 4672{
51219358
MW
4673 ASC_DCNT chksum;
4674 ushort mcode_word_size;
4675 ushort mcode_chksum;
27c868c2 4676
51219358
MW
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);
27c868c2 4681
51219358 4682 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
b352f923 4683 ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum);
51219358
MW
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));
b352f923 4690 ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum);
51219358
MW
4691 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4692 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
b352f923 4693 return chksum;
51219358 4694}
27c868c2 4695
51219358
MW
4696/* Microcode buffer is kept after initialization for error recovery. */
4697static 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,
4890};
27c868c2 4891
51219358
MW
4892static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
4893static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4 4894
1da177e4 4895/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
4896static unsigned char _adv_asc3550_buf[] = {
4897 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
629d688d
MW
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,
27c868c2 4901 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
629d688d
MW
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,
27c868c2 4905 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
629d688d
MW
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,
27c868c2 4909 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
629d688d
MW
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,
27c868c2 4913 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
629d688d
MW
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,
27c868c2 4917 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
629d688d
MW
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,
27c868c2 4921 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
629d688d
MW
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,
27c868c2 4925 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
629d688d
MW
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,
27c868c2 4929 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
629d688d
MW
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,
27c868c2 4933 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
629d688d
MW
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,
27c868c2 4937 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
629d688d
MW
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,
27c868c2 4941 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
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,
27c868c2 4945 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
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,
27c868c2 4949 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
629d688d
MW
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,
27c868c2 4953 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
629d688d
MW
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,
27c868c2 4957 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
629d688d
MW
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,
27c868c2 4961 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
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,
27c868c2 4965 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
629d688d
MW
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,
27c868c2 4969 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
629d688d
MW
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,
27c868c2 4973 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
629d688d
MW
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,
27c868c2 4977 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
629d688d
MW
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,
27c868c2 4981 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
629d688d
MW
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,
27c868c2 4985 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
629d688d
MW
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,
27c868c2 4989 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
629d688d
MW
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,
27c868c2 4993 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
629d688d
MW
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,
27c868c2 4997 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
629d688d
MW
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,
27c868c2 5001 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
629d688d
MW
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,
27c868c2 5005 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
629d688d
MW
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,
27c868c2 5009 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
629d688d
MW
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,
27c868c2 5013 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
629d688d
MW
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,
27c868c2 5017 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
629d688d
MW
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,
27c868c2 5021 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
629d688d
MW
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,
27c868c2 5025 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
629d688d
MW
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,
27c868c2 5029 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
629d688d
MW
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,
27c868c2 5033 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
629d688d
MW
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,
27c868c2 5037 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
629d688d
MW
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,
27c868c2 5041 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
629d688d
MW
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,
27c868c2 5045 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
629d688d
MW
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,
27c868c2 5049 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
629d688d
MW
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,
27c868c2 5053 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
629d688d
MW
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,
27c868c2 5057 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
629d688d
MW
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,
27c868c2 5061 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
629d688d
MW
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,
27c868c2 5065 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
629d688d
MW
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,
27c868c2 5069 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
629d688d
MW
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,
27c868c2 5073 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
629d688d
MW
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,
27c868c2 5077 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
629d688d
MW
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,
27c868c2 5081 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
629d688d
MW
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,
27c868c2 5085 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
629d688d
MW
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,
27c868c2 5089 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
629d688d
MW
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,
27c868c2 5093 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
629d688d
MW
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,
27c868c2 5097 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
629d688d
MW
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,
27c868c2 5101 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
629d688d
MW
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,
27c868c2 5105 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
629d688d
MW
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,
27c868c2 5109 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
629d688d
MW
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,
27c868c2 5113 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
629d688d
MW
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,
27c868c2 5117 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
629d688d
MW
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,
27c868c2 5121 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
629d688d
MW
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,
27c868c2 5125 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
629d688d
MW
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,
27c868c2 5129 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
629d688d
MW
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,
27c868c2 5133 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
629d688d
MW
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,
27c868c2 5137 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
629d688d
MW
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,
27c868c2 5141 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
629d688d
MW
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,
27c868c2 5145 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
629d688d
MW
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,
27c868c2 5149 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
629d688d
MW
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,
27c868c2 5153 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
629d688d
MW
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,
27c868c2 5157 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
629d688d
MW
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,
27c868c2 5161 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
629d688d
MW
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,
27c868c2 5165 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
629d688d
MW
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,
27c868c2 5169 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
629d688d
MW
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,
27c868c2 5173 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
629d688d
MW
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,
27c868c2 5177 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
629d688d
MW
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,
27c868c2 5181 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
629d688d
MW
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,
27c868c2 5185 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
629d688d
MW
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,
27c868c2 5189 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
629d688d
MW
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,
27c868c2 5193 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
629d688d
MW
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,
27c868c2 5197 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
629d688d
MW
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,
27c868c2 5201 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
629d688d
MW
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,
27c868c2 5205 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
629d688d
MW
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,
27c868c2 5209 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
629d688d
MW
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,
27c868c2 5213 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
629d688d
MW
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,
27c868c2 5217 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
629d688d
MW
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,
27c868c2 5221 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
629d688d
MW
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,
27c868c2 5225 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
629d688d
MW
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,
27c868c2 5229 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
629d688d
MW
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,
27c868c2 5233 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
629d688d
MW
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,
27c868c2 5237 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
629d688d
MW
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,
27c868c2 5241 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
629d688d
MW
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,
27c868c2 5245 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
629d688d
MW
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,
27c868c2 5249 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
629d688d
MW
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,
27c868c2 5253 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
629d688d
MW
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,
27c868c2 5257 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
629d688d
MW
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,
27c868c2 5261 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
629d688d
MW
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,
27c868c2 5265 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
629d688d
MW
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,
27c868c2 5269 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
629d688d
MW
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,
27c868c2 5273 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
629d688d
MW
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,
27c868c2 5277 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
629d688d
MW
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,
27c868c2 5281 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
629d688d
MW
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,
27c868c2 5285 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
629d688d
MW
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,
27c868c2 5289 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
629d688d
MW
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,
27c868c2 5293 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
629d688d
MW
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,
27c868c2 5297 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
629d688d
MW
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,
27c868c2 5301 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
629d688d
MW
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,
27c868c2 5305 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
629d688d
MW
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,
27c868c2 5309 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
629d688d
MW
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,
27c868c2 5313 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
629d688d
MW
5314 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5315 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
1da177e4
LT
5316};
5317
27c868c2
MW
5318static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
5319static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
5320
5321/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
5322static unsigned char _adv_asc38C0800_buf[] = {
5323 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
629d688d
MW
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,
27c868c2 5327 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
629d688d
MW
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,
27c868c2 5331 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
629d688d
MW
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,
27c868c2 5335 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
629d688d
MW
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,
27c868c2 5339 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
629d688d
MW
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,
27c868c2 5343 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
629d688d
MW
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,
27c868c2 5347 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
629d688d
MW
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,
27c868c2 5351 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
629d688d
MW
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,
27c868c2 5355 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
629d688d
MW
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,
27c868c2 5359 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
629d688d
MW
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,
27c868c2 5363 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
629d688d
MW
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,
27c868c2 5367 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
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,
27c868c2 5371 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
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,
27c868c2 5375 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
629d688d
MW
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,
27c868c2 5379 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
629d688d
MW
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,
27c868c2 5383 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
629d688d
MW
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,
27c868c2 5387 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
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,
27c868c2 5391 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
629d688d
MW
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,
27c868c2 5395 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
629d688d
MW
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,
27c868c2 5399 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
629d688d
MW
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,
27c868c2 5403 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
629d688d
MW
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,
27c868c2 5407 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
629d688d
MW
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,
27c868c2 5411 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
629d688d
MW
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,
27c868c2 5415 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
629d688d
MW
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,
27c868c2 5419 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
629d688d
MW
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,
27c868c2 5423 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
629d688d
MW
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,
27c868c2 5427 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
629d688d
MW
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,
27c868c2 5431 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
629d688d
MW
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,
27c868c2 5435 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
629d688d
MW
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,
27c868c2 5439 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
629d688d
MW
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,
27c868c2 5443 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
629d688d
MW
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,
27c868c2 5447 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
629d688d
MW
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,
27c868c2 5451 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
629d688d
MW
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,
27c868c2 5455 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
629d688d
MW
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,
27c868c2 5459 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
629d688d
MW
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,
27c868c2 5463 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
629d688d
MW
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,
27c868c2 5467 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
629d688d
MW
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,
27c868c2 5471 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
629d688d
MW
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,
27c868c2 5475 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
629d688d
MW
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,
27c868c2 5479 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
629d688d
MW
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,
27c868c2 5483 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
629d688d
MW
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,
27c868c2 5487 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
629d688d
MW
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,
27c868c2 5491 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
629d688d
MW
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,
27c868c2 5495 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
629d688d
MW
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,
27c868c2 5499 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
629d688d
MW
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,
27c868c2 5503 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
629d688d
MW
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,
27c868c2 5507 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
629d688d
MW
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,
27c868c2 5511 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
629d688d
MW
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,
27c868c2 5515 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
629d688d
MW
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,
27c868c2 5519 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
629d688d
MW
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,
27c868c2 5523 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
629d688d
MW
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,
27c868c2 5527 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
629d688d
MW
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,
27c868c2 5531 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
629d688d
MW
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,
27c868c2 5535 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
629d688d
MW
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,
27c868c2 5539 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
629d688d
MW
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,
27c868c2 5543 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
629d688d
MW
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,
27c868c2 5547 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
629d688d
MW
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,
27c868c2 5551 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
629d688d
MW
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,
27c868c2 5555 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
629d688d
MW
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,
27c868c2 5559 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
629d688d
MW
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,
27c868c2 5563 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
629d688d
MW
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,
27c868c2 5567 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
629d688d
MW
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,
27c868c2 5571 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
629d688d
MW
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,
27c868c2 5575 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
629d688d
MW
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,
27c868c2 5579 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
629d688d
MW
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,
27c868c2 5583 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
629d688d
MW
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,
27c868c2 5587 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
629d688d
MW
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,
27c868c2 5591 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
629d688d
MW
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,
27c868c2 5595 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
629d688d
MW
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,
27c868c2 5599 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
629d688d
MW
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,
27c868c2 5603 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
629d688d
MW
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,
27c868c2 5607 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
629d688d
MW
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,
27c868c2 5611 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
629d688d
MW
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,
27c868c2 5615 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
629d688d
MW
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,
27c868c2 5619 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
629d688d
MW
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,
27c868c2 5623 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
629d688d
MW
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,
27c868c2 5627 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
629d688d
MW
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,
27c868c2 5631 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
629d688d
MW
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,
27c868c2 5635 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
629d688d
MW
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,
27c868c2 5639 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
629d688d
MW
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,
27c868c2 5643 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
629d688d
MW
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,
27c868c2 5647 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
629d688d
MW
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,
27c868c2 5651 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
629d688d
MW
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,
27c868c2 5655 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
629d688d
MW
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,
27c868c2 5659 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
629d688d
MW
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,
27c868c2 5663 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
629d688d
MW
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,
27c868c2 5667 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
629d688d
MW
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,
27c868c2 5671 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
629d688d
MW
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,
27c868c2 5675 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
629d688d
MW
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,
27c868c2 5679 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
629d688d
MW
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,
27c868c2 5683 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
629d688d
MW
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,
27c868c2 5687 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
629d688d
MW
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,
27c868c2 5691 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
629d688d
MW
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,
27c868c2 5695 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
629d688d
MW
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,
27c868c2 5699 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
629d688d
MW
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,
27c868c2 5703 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
629d688d
MW
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,
27c868c2 5707 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
629d688d
MW
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,
27c868c2 5711 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
629d688d
MW
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,
27c868c2 5715 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
629d688d
MW
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,
27c868c2 5719 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
629d688d
MW
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,
27c868c2 5723 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
629d688d
MW
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,
27c868c2 5727 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
629d688d
MW
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,
27c868c2 5731 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
629d688d
MW
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,
27c868c2 5735 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
629d688d
MW
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,
27c868c2 5739 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
629d688d
MW
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,
27c868c2 5743 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
629d688d
MW
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,
27c868c2 5747 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
629d688d
MW
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,
27c868c2 5751 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
629d688d
MW
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,
27c868c2 5755 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
629d688d
MW
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,
27c868c2 5759 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
629d688d
MW
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,
27c868c2 5763 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
629d688d
MW
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,
27c868c2 5767 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
5768};
5769
27c868c2
MW
5770static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
5771static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
5772
5773/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
5774static unsigned char _adv_asc38C1600_buf[] = {
5775 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
629d688d
MW
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,
27c868c2 5779 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
629d688d
MW
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,
27c868c2 5783 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
629d688d
MW
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,
27c868c2 5787 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
629d688d
MW
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,
27c868c2 5791 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
629d688d
MW
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,
27c868c2 5795 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
629d688d
MW
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,
27c868c2 5799 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
629d688d
MW
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,
27c868c2 5803 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
629d688d
MW
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,
27c868c2 5807 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
629d688d
MW
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,
27c868c2 5811 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
629d688d
MW
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,
27c868c2 5815 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
629d688d
MW
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,
27c868c2 5819 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
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,
27c868c2 5823 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
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,
27c868c2 5827 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
629d688d
MW
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,
27c868c2 5831 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
629d688d
MW
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,
27c868c2 5835 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
629d688d
MW
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,
27c868c2 5839 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
629d688d
MW
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,
27c868c2 5843 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
629d688d
MW
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,
27c868c2 5847 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
629d688d
MW
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,
27c868c2 5851 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
629d688d
MW
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,
27c868c2 5855 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
629d688d
MW
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,
27c868c2 5859 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
629d688d
MW
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,
27c868c2 5863 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
629d688d
MW
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,
27c868c2 5867 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
629d688d
MW
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,
27c868c2 5871 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
629d688d
MW
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,
27c868c2 5875 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
629d688d
MW
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,
27c868c2 5879 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
629d688d
MW
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,
27c868c2 5883 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
629d688d
MW
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,
27c868c2 5887 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
629d688d
MW
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,
27c868c2 5891 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
629d688d
MW
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,
27c868c2 5895 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
629d688d
MW
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,
27c868c2 5899 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
629d688d
MW
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,
27c868c2 5903 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
629d688d
MW
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,
27c868c2 5907 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
629d688d
MW
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,
27c868c2 5911 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
629d688d
MW
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,
27c868c2 5915 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
629d688d
MW
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,
27c868c2 5919 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
629d688d
MW
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,
27c868c2 5923 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
629d688d
MW
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,
27c868c2 5927 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
629d688d
MW
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,
27c868c2 5931 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
629d688d
MW
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,
27c868c2 5935 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
629d688d
MW
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,
27c868c2 5939 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
629d688d
MW
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,
27c868c2 5943 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
629d688d
MW
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,
27c868c2 5947 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
629d688d
MW
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,
27c868c2 5951 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
629d688d
MW
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,
27c868c2 5955 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
629d688d
MW
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,
27c868c2 5959 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
629d688d
MW
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,
27c868c2 5963 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
629d688d
MW
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,
27c868c2 5967 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
629d688d
MW
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,
27c868c2 5971 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
629d688d
MW
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,
27c868c2 5975 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
629d688d
MW
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,
27c868c2 5979 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
629d688d
MW
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,
27c868c2 5983 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
629d688d
MW
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,
27c868c2 5987 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
629d688d
MW
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,
27c868c2 5991 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
629d688d
MW
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,
27c868c2 5995 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
629d688d
MW
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,
27c868c2 5999 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
629d688d
MW
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,
27c868c2 6003 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
629d688d
MW
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,
27c868c2 6007 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
629d688d
MW
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,
27c868c2 6011 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
629d688d
MW
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,
27c868c2 6015 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
629d688d
MW
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,
27c868c2 6019 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
629d688d
MW
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,
27c868c2 6023 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
629d688d
MW
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,
27c868c2 6027 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
629d688d
MW
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,
27c868c2 6031 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
629d688d
MW
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,
27c868c2 6035 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
629d688d
MW
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,
27c868c2 6039 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
629d688d
MW
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,
27c868c2 6043 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
629d688d
MW
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,
27c868c2 6047 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
629d688d
MW
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,
27c868c2 6051 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
629d688d
MW
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,
27c868c2 6055 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
629d688d
MW
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,
27c868c2 6059 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
629d688d
MW
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,
27c868c2 6063 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
629d688d
MW
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,
27c868c2 6067 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
629d688d
MW
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,
27c868c2 6071 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
629d688d
MW
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,
27c868c2 6075 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
629d688d
MW
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,
27c868c2 6079 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
629d688d
MW
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,
27c868c2 6083 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
629d688d
MW
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,
27c868c2 6087 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
629d688d
MW
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,
27c868c2 6091 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
629d688d
MW
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,
27c868c2 6095 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
629d688d
MW
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,
27c868c2 6099 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
629d688d
MW
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,
27c868c2 6103 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
629d688d
MW
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,
27c868c2 6107 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
629d688d
MW
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,
27c868c2 6111 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
629d688d
MW
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,
27c868c2 6115 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
629d688d
MW
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,
27c868c2 6119 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
629d688d
MW
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,
27c868c2 6123 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
629d688d
MW
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,
27c868c2 6127 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
629d688d
MW
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,
27c868c2 6131 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
629d688d
MW
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,
27c868c2 6135 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
629d688d
MW
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,
27c868c2 6139 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
629d688d
MW
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,
27c868c2 6143 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
629d688d
MW
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,
27c868c2 6147 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
629d688d
MW
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,
27c868c2 6151 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
629d688d
MW
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,
27c868c2 6155 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
629d688d
MW
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,
27c868c2 6159 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
629d688d
MW
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,
27c868c2 6163 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
629d688d
MW
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,
27c868c2 6167 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
629d688d
MW
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,
27c868c2 6171 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
629d688d
MW
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,
27c868c2 6175 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
629d688d
MW
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,
27c868c2 6179 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
629d688d
MW
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,
27c868c2 6183 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
629d688d
MW
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,
27c868c2 6187 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
629d688d
MW
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,
27c868c2 6191 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
629d688d
MW
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,
27c868c2 6195 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
629d688d
MW
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,
27c868c2 6199 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
629d688d
MW
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,
27c868c2 6203 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
629d688d
MW
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,
27c868c2 6207 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
629d688d
MW
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,
27c868c2 6211 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
629d688d
MW
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,
27c868c2 6215 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
629d688d
MW
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,
27c868c2 6219 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
629d688d
MW
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,
27c868c2 6223 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
629d688d
MW
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,
27c868c2 6227 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
629d688d
MW
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,
27c868c2 6231 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
629d688d
MW
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,
27c868c2 6235 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
629d688d
MW
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,
27c868c2 6239 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
629d688d
MW
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,
27c868c2 6243 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
629d688d
MW
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,
27c868c2 6247 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
629d688d
MW
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,
27c868c2 6251 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
629d688d
MW
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,
27c868c2 6255 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
629d688d
MW
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,
27c868c2 6259 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
629d688d
MW
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,
27c868c2 6263 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
629d688d
MW
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,
27c868c2 6267 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
629d688d
MW
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,
27c868c2 6271 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
629d688d
MW
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,
27c868c2 6275 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
629d688d
MW
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,
27c868c2 6279 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
629d688d
MW
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,
27c868c2 6283 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
629d688d
MW
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,
27c868c2 6287 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
629d688d
MW
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,
27c868c2 6291 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
629d688d
MW
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,
27c868c2 6295 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
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,
27c868c2 6299 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
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,
1da177e4
LT
6303};
6304
51219358
MW
6305static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
6306static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
6307
6308static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6309{
6310 PortAddr iop_base;
6311 int i;
6312 ushort lram_addr;
6313
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);
6334 }
6335}
6336
6337static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6338{
6339 int i;
6340 ushort warn_code;
6341 PortAddr iop_base;
6342 ASC_PADDR phy_addr;
6343 ASC_DCNT phy_size;
6344
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]);
6350 }
6351
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));
6357
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);
6366
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);
6371
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;
6376 }
6377 if (AscStartChip(iop_base) != 1) {
6378 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6379 return warn_code;
6380 }
6381
6382 return warn_code;
6383}
6384
6385static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6386{
6387 ushort warn_code;
6388 PortAddr iop_base;
6389
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? */
6396 }
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;
6403 }
6404 AscDisableInterrupt(iop_base);
6405 warn_code |= AscInitLram(asc_dvc);
6406 if (asc_dvc->err_code != 0)
6407 return UW_ERR;
b352f923 6408 ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
51219358
MW
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;
6413 }
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;
6418}
6419
6420/*
6421 * Load the Microcode
6422 *
6423 * Write the microcode image to RISC memory starting at address 0.
6424 *
6425 * The microcode is stored compressed in the following format:
6426 *
6427 * 254 word (508 byte) table indexed by byte code followed
6428 * by the following byte codes:
6429 *
6430 * 1-Byte Code:
6431 * 00: Emit word 0 in table.
6432 * 01: Emit word 1 in table.
6433 * .
6434 * FD: Emit word 253 in table.
6435 *
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.
6439 *
6440 * Returns 0 or an error if the checksum doesn't match
6441 */
6442static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6443 int memsize, int chksum)
6444{
6445 int i, j, end, len = 0;
6446 ADV_DCNT sum;
6447
6448 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6449
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;
6456 }
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;
6468 }
6469 }
6470
6471 end = len;
6472
6473 while (len < memsize) {
6474 AdvWriteWordAutoIncLram(iop_base, 0);
6475 len += 2;
6476 }
6477
6478 /* Verify the microcode checksum. */
6479 sum = 0;
6480 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6481
6482 for (len = 0; len < end; len += 2) {
6483 sum += AdvReadWordAutoIncLram(iop_base);
6484 }
6485
6486 if (sum != chksum)
6487 return ASC_IERR_MCODE_CHKSUM;
6488
6489 return 0;
6490}
6491
6492/*
6493 * DvcGetPhyAddr()
6494 *
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.
6499 *
6500 * Note: Because Linux currently doesn't page the kernel and all
6501 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6502 */
6503ADV_PADDR
6504DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
6505 uchar *vaddr, ADV_SDCNT *lenp, int flag)
6506{
6507 ADV_PADDR paddr = virt_to_bus(vaddr);
6508
b352f923 6509 ASC_DBG(4, "vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n",
51219358
MW
6510 vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr);
6511
6512 return paddr;
6513}
6514
6515static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6516{
6517 ADV_CARR_T *carrp;
6518 ADV_SDCNT buf_size;
6519 ADV_PADDR carr_paddr;
6520
6521 BUG_ON(!asc_dvc->carrier_buf);
6522
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);
6529 }
6530
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));
6538
6539 buf_size -= sizeof(ADV_CARR_T);
6540
6541 /*
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.
6545 */
6546 if (contig_len < sizeof(ADV_CARR_T)) {
6547 carrp++;
6548 continue;
6549 }
6550
6551 carrp->carr_pa = carr_paddr;
6552 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6553
6554 /*
6555 * Insert the carrier at the beginning of the freelist.
6556 */
6557 carrp->next_vpa =
6558 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6559 asc_dvc->carr_freelist = carrp;
6560
6561 carrp++;
6562 } while (buf_size > 0);
6563}
6564
6565/*
6566 * Send an idle command to the chip and wait for completion.
6567 *
6568 * Command completion is polled for once per microsecond.
6569 *
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.
6573 *
6574 * Return Values:
6575 * ADV_TRUE - command completed successfully
6576 * ADV_FALSE - command failed
6577 * ADV_ERROR - command timed out
6578 */
6579static int
6580AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6581 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6582{
6583 int result;
6584 ADV_DCNT i, j;
6585 AdvPortAddr iop_base;
6586
6587 iop_base = asc_dvc->iop_base;
6588
6589 /*
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
6593 */
6594 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6595
6596 /*
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.
6601 */
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);
6605
6606 /*
6607 * Tickle the RISC to tell it to process the idle command.
6608 */
6609 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6610 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6611 /*
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.
6615 */
6616 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6617 }
6618
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);
6628 }
6629 }
6630
6631 BUG(); /* The idle command should never timeout. */
6632 return ADV_ERROR;
6633}
6634
6635/*
6636 * Reset SCSI Bus and purge all outstanding requests.
6637 *
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.
6643 */
6644static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6645{
6646 int status;
6647
6648 /*
6649 * Send the SCSI Bus Reset idle start idle command which asserts
6650 * the SCSI Bus Reset signal.
6651 */
6652 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6653 if (status != ADV_TRUE) {
6654 return status;
6655 }
6656
6657 /*
6658 * Delay for the specified SCSI Bus Reset hold time.
6659 *
6660 * The hold time delay is done on the host because the RISC has no
6661 * microsecond accurate timer.
6662 */
6663 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6664
6665 /*
6666 * Send the SCSI Bus Reset end idle command which de-asserts
6667 * the SCSI Bus Reset signal and purges any pending requests.
6668 */
6669 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6670 if (status != ADV_TRUE) {
6671 return status;
6672 }
6673
6674 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6675
6676 return status;
6677}
6678
6679/*
6680 * Initialize the ASC-3550.
6681 *
6682 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6683 *
6684 * For a non-fatal error return a warning code. If there are no warnings
6685 * then 0 is returned.
6686 *
6687 * Needed after initialization for error recovery.
6688 */
6689static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6690{
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];
6703
6704 /* If there is already an error, don't continue. */
6705 if (asc_dvc->err_code != 0)
6706 return ADV_ERROR;
6707
6708 /*
6709 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6710 */
6711 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6712 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6713 return ADV_ERROR;
6714 }
6715
6716 warn_code = 0;
6717 iop_base = asc_dvc->iop_base;
6718
6719 /*
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.
6723 *
6724 * Note: This code makes the assumption, which is currently true,
6725 * that a chip reset does not clear RISC LRAM.
6726 */
6727 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6728 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6729 bios_mem[i]);
6730 }
6731
6732 /*
6733 * Save current per TID negotiated values.
6734 */
6735 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6736 ushort bios_version, major, minor;
6737
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);
6747 }
6748 }
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]);
6754 }
6755
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;
6761
6762 /*
6763 * Restore the RISC memory BIOS region.
6764 */
6765 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6766 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6767 bios_mem[i]);
6768 }
6769
6770 /*
6771 * Calculate and write the microcode code checksum to the microcode
6772 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6773 */
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);
6780 }
6781 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6782
6783 /*
6784 * Read and save microcode version and date.
6785 */
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);
6790
6791 /*
6792 * Set the chip type to indicate the ASC3550.
6793 */
6794 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6795
6796 /*
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.
6801 */
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);
6806 }
6807
6808 /*
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.
6811 */
6812 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6813 START_CTL_EMFU | READ_CMD_MRM);
6814
6815 /*
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.
6819 *
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.
6826 */
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);
6832 }
6833
6834 /*
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.
6839 *
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.
6843 *
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
6853 * .
6854 * 1111b (0xF) Undefined
6855 */
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)));
6864 }
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. */
6877 }
6878 }
6879
6880 /*
6881 * Set microcode operating variable for the disconnect per TID bitmask.
6882 */
6883 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
6884 asc_dvc->cfg->disc_enable);
6885
6886 /*
6887 * Set SCSI_CFG0 Microcode Default Value.
6888 *
6889 * The microcode will set the SCSI_CFG0 register using this value
6890 * after it is started below.
6891 */
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);
6895
6896 /*
6897 * Determine SCSI_CFG1 Microcode Default Value.
6898 *
6899 * The microcode will set the SCSI_CFG1 register using this value
6900 * after it is started below.
6901 */
6902
6903 /* Read current SCSI_CFG1 Register value. */
6904 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
6905
6906 /*
6907 * If all three connectors are in use, return an error.
6908 */
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;
6913 }
6914
6915 /*
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.
6919 */
6920 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
6921 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
6922 return ADV_ERROR;
6923 }
6924
6925 /*
6926 * If this is a differential board and a single-ended device
6927 * is attached to one of the connectors, return an error.
6928 */
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;
6932 }
6933
6934 /*
6935 * If automatic termination control is enabled, then set the
6936 * termination value based on a table listed in a_condor.h.
6937 *
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.
6941 */
6942 if (asc_dvc->cfg->termination == 0) {
6943 /*
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.
6946 */
6947 asc_dvc->cfg->termination |= TERM_CTL_SEL;
6948
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;
6959
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;
6968
6969 /* TERM_CTL_H: off, TERM_CTL_L: off */
6970 case 0x2:
6971 case 0x6:
6972 break;
6973 }
6974 }
6975
6976 /*
6977 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
6978 */
6979 scsi_cfg1 &= ~TERM_CTL;
6980
6981 /*
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.
6986 */
6987 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
6988
6989 /*
6990 * Set SCSI_CFG1 Microcode Default Value
6991 *
6992 * Set filter value and possibly modified termination control
6993 * bits in the Microcode SCSI_CFG1 Register Value.
6994 *
6995 * The microcode will set the SCSI_CFG1 register using this value
6996 * after it is started below.
6997 */
6998 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
6999 FLTR_DISABLE | scsi_cfg1);
7000
7001 /*
7002 * Set MEM_CFG Microcode Default Value
7003 *
7004 * The microcode will set the MEM_CFG register using this value
7005 * after it is started below.
7006 *
7007 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7008 * are defined.
7009 *
7010 * ASC-3550 has 8KB internal memory.
7011 */
7012 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7013 BIOS_EN | RAM_SZ_8KB);
7014
7015 /*
7016 * Set SEL_MASK Microcode Default Value
7017 *
7018 * The microcode will set the SEL_MASK register using this value
7019 * after it is started below.
7020 */
7021 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7022 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7023
7024 AdvBuildCarrierFreelist(asc_dvc);
7025
7026 /*
7027 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7028 */
7029
7030 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7031 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7032 return ADV_ERROR;
7033 }
7034 asc_dvc->carr_freelist = (ADV_CARR_T *)
7035 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7036
7037 /*
7038 * The first command issued will be placed in the stopper carrier.
7039 */
7040 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7041
7042 /*
7043 * Set RISC ICQ physical address start value.
7044 */
7045 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7046
7047 /*
7048 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7049 */
7050 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7051 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7052 return ADV_ERROR;
7053 }
7054 asc_dvc->carr_freelist = (ADV_CARR_T *)
7055 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7056
7057 /*
7058 * The first command completed by the RISC will be placed in
7059 * the stopper.
7060 *
7061 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7062 * completed the RISC will set the ASC_RQ_STOPPER bit.
7063 */
7064 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7065
7066 /*
7067 * Set RISC IRQ physical address start value.
7068 */
7069 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7070 asc_dvc->carr_pending_cnt = 0;
7071
7072 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7073 (ADV_INTR_ENABLE_HOST_INTR |
7074 ADV_INTR_ENABLE_GLOBAL_INTR));
7075
7076 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7077 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7078
7079 /* finally, finally, gentlemen, start your engine */
7080 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7081
7082 /*
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.
7086 */
7087 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7088 /*
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.
7092 */
7093 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7094 0x55AA) {
7095 /*
7096 * Restore per TID negotiated values.
7097 */
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]);
7106 }
7107 } else {
7108 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7109 warn_code = ASC_WARN_BUSRESET_ERROR;
7110 }
7111 }
7112 }
7113
7114 return warn_code;
7115}
7116
7117/*
7118 * Initialize the ASC-38C0800.
7119 *
7120 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7121 *
7122 * For a non-fatal error return a warning code. If there are no warnings
7123 * then 0 is returned.
7124 *
7125 * Needed after initialization for error recovery.
7126 */
7127static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7128{
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];
7142
7143 /* If there is already an error, don't continue. */
7144 if (asc_dvc->err_code != 0)
7145 return ADV_ERROR;
7146
7147 /*
7148 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7149 */
7150 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7151 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7152 return ADV_ERROR;
7153 }
7154
7155 warn_code = 0;
7156 iop_base = asc_dvc->iop_base;
7157
7158 /*
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.
7162 *
7163 * Note: This code makes the assumption, which is currently true,
7164 * that a chip reset does not clear RISC LRAM.
7165 */
7166 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7167 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7168 bios_mem[i]);
7169 }
7170
7171 /*
7172 * Save current per TID negotiated values.
7173 */
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]);
7180 }
7181
7182 /*
7183 * RAM BIST (RAM Built-In Self Test)
7184 *
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
7198 *
7199 * Note: RAM BIST code should be put right here, before loading the
7200 * microcode and after saving the RISC memory BIOS region.
7201 */
7202
7203 /*
7204 * LRAM Pre-test
7205 *
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.
7210 */
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;
7219 }
7220
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;
7227 }
7228 }
7229
7230 /*
7231 * LRAM Test - It takes about 1.5 ms to run through the test.
7232 *
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.
7236 */
7237 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7238 mdelay(10); /* Wait for 10ms before checking status. */
7239
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;
7246 }
7247
7248 /* We need to reset back to normal mode after LRAM test passes. */
7249 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7250
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;
7256
7257 /*
7258 * Restore the RISC memory BIOS region.
7259 */
7260 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7261 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7262 bios_mem[i]);
7263 }
7264
7265 /*
7266 * Calculate and write the microcode code checksum to the microcode
7267 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7268 */
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);
7275 }
7276 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7277
7278 /*
7279 * Read microcode version and date.
7280 */
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);
7285
7286 /*
7287 * Set the chip type to indicate the ASC38C0800.
7288 */
7289 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7290
7291 /*
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].
7295 *
7296 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7297 * Microcode Default Value' section below.
7298 */
7299 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7300 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7301 scsi_cfg1 | DIS_TERM_DRV);
7302
7303 /*
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.
7308 */
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);
7313 }
7314
7315 /*
7316 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7317 * bits for the default FIFO threshold.
7318 *
7319 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7320 *
7321 * For DMA Errata #4 set the BC_THRESH_ENB bit.
7322 */
7323 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7324 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7325 READ_CMD_MRM);
7326
7327 /*
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.
7331 *
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.
7338 */
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);
7344 }
7345
7346 /*
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.
7350 *
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.
7354 */
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);
7361
7362 /*
7363 * Set SCSI_CFG0 Microcode Default Value.
7364 *
7365 * The microcode will set the SCSI_CFG0 register using this value
7366 * after it is started below.
7367 */
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);
7371
7372 /*
7373 * Determine SCSI_CFG1 Microcode Default Value.
7374 *
7375 * The microcode will set the SCSI_CFG1 register using this value
7376 * after it is started below.
7377 */
7378
7379 /* Read current SCSI_CFG1 Register value. */
7380 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7381
7382 /*
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.
7386 */
7387 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7388 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7389 return ADV_ERROR;
7390 }
7391
7392 /*
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.
7398 *
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.
7402 */
7403 if (scsi_cfg1 & HVD) {
7404 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7405 return ADV_ERROR;
7406 }
7407
7408 /*
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.
7411 *
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.
7415 */
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;
7425
7426 /* TERM_SE_HI: on, TERM_SE_LO: off */
7427 case 0x0:
7428 asc_dvc->cfg->termination |= TERM_SE_HI;
7429 break;
7430 }
7431 }
7432
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;
7442
7443 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7444 case 0x0:
7445 break;
7446 }
7447 }
7448
7449 /*
7450 * Clear any set TERM_SE and TERM_LVD bits.
7451 */
7452 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7453
7454 /*
7455 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7456 */
7457 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7458
7459 /*
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.
7463 */
7464 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7465
7466 /*
7467 * Set SCSI_CFG1 Microcode Default Value
7468 *
7469 * Set possibly modified termination control and reset DIS_TERM_DRV
7470 * bits in the Microcode SCSI_CFG1 Register Value.
7471 *
7472 * The microcode will set the SCSI_CFG1 register using this value
7473 * after it is started below.
7474 */
7475 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7476
7477 /*
7478 * Set MEM_CFG Microcode Default Value
7479 *
7480 * The microcode will set the MEM_CFG register using this value
7481 * after it is started below.
7482 *
7483 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7484 * are defined.
7485 *
7486 * ASC-38C0800 has 16KB internal memory.
7487 */
7488 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7489 BIOS_EN | RAM_SZ_16KB);
7490
7491 /*
7492 * Set SEL_MASK Microcode Default Value
7493 *
7494 * The microcode will set the SEL_MASK register using this value
7495 * after it is started below.
7496 */
7497 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7498 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7499
7500 AdvBuildCarrierFreelist(asc_dvc);
7501
7502 /*
7503 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7504 */
7505
7506 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7507 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7508 return ADV_ERROR;
7509 }
7510 asc_dvc->carr_freelist = (ADV_CARR_T *)
7511 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7512
7513 /*
7514 * The first command issued will be placed in the stopper carrier.
7515 */
7516 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7517
7518 /*
7519 * Set RISC ICQ physical address start value.
7520 * carr_pa is LE, must be native before write
7521 */
7522 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7523
7524 /*
7525 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7526 */
7527 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7528 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7529 return ADV_ERROR;
7530 }
7531 asc_dvc->carr_freelist = (ADV_CARR_T *)
7532 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7533
7534 /*
7535 * The first command completed by the RISC will be placed in
7536 * the stopper.
7537 *
7538 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7539 * completed the RISC will set the ASC_RQ_STOPPER bit.
7540 */
7541 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7542
7543 /*
7544 * Set RISC IRQ physical address start value.
7545 *
7546 * carr_pa is LE, must be native before write *
7547 */
7548 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7549 asc_dvc->carr_pending_cnt = 0;
7550
7551 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7552 (ADV_INTR_ENABLE_HOST_INTR |
7553 ADV_INTR_ENABLE_GLOBAL_INTR));
7554
7555 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7556 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7557
7558 /* finally, finally, gentlemen, start your engine */
7559 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7560
7561 /*
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.
7565 */
7566 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7567 /*
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.
7571 */
7572 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7573 0x55AA) {
7574 /*
7575 * Restore per TID negotiated values.
7576 */
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]);
7585 }
7586 } else {
7587 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7588 warn_code = ASC_WARN_BUSRESET_ERROR;
7589 }
7590 }
7591 }
7592
7593 return warn_code;
7594}
7595
7596/*
7597 * Initialize the ASC-38C1600.
7598 *
7599 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7600 *
7601 * For a non-fatal error return a warning code. If there are no warnings
7602 * then 0 is returned.
7603 *
7604 * Needed after initialization for error recovery.
7605 */
7606static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7607{
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];
7621
7622 /* If there is already an error, don't continue. */
7623 if (asc_dvc->err_code != 0) {
7624 return ADV_ERROR;
7625 }
7626
7627 /*
7628 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7629 */
7630 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7631 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7632 return ADV_ERROR;
7633 }
7634
7635 warn_code = 0;
7636 iop_base = asc_dvc->iop_base;
7637
7638 /*
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.
7642 *
7643 * Note: This code makes the assumption, which is currently true,
7644 * that a chip reset does not clear RISC LRAM.
7645 */
7646 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7647 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7648 bios_mem[i]);
7649 }
7650
7651 /*
7652 * Save current per TID negotiated values.
7653 */
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]);
7661 }
7662
7663 /*
7664 * RAM BIST (Built-In Self Test)
7665 *
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
7679 *
7680 * Note: RAM BIST code should be put right here, before loading the
7681 * microcode and after saving the RISC memory BIOS region.
7682 */
7683
7684 /*
7685 * LRAM Pre-test
7686 *
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.
7691 */
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;
7700 }
7701
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;
7708 }
7709 }
7710
7711 /*
7712 * LRAM Test - It takes about 1.5 ms to run through the test.
7713 *
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.
7717 */
7718 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7719 mdelay(10); /* Wait for 10ms before checking status. */
7720
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;
7727 }
7728
7729 /* We need to reset back to normal mode after LRAM test passes. */
7730 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7731
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;
7737
7738 /*
7739 * Restore the RISC memory BIOS region.
7740 */
7741 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7742 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7743 bios_mem[i]);
7744 }
7745
7746 /*
7747 * Calculate and write the microcode code checksum to the microcode
7748 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7749 */
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);
7756 }
7757 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7758
7759 /*
7760 * Read microcode version and date.
7761 */
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);
7766
7767 /*
7768 * Set the chip type to indicate the ASC38C1600.
7769 */
7770 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7771
7772 /*
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].
7776 *
7777 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7778 * Microcode Default Value' section below.
7779 */
7780 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7781 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7782 scsi_cfg1 | DIS_TERM_DRV);
7783
7784 /*
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.
7789 */
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);
7794 }
7795
7796 /*
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.
7801 */
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);
7806 }
7807
7808 /*
7809 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7810 * and START_CTL_TH [3:2].
7811 */
7812 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7813 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7814
7815 /*
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.
7819 *
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.
7826 */
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);
7832 }
7833
7834 /*
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.
7838 *
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.
7842 */
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);
7849
7850 /*
7851 * Set SCSI_CFG0 Microcode Default Value.
7852 *
7853 * The microcode will set the SCSI_CFG0 register using this value
7854 * after it is started below.
7855 */
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);
7859
7860 /*
7861 * Calculate SCSI_CFG1 Microcode Default Value.
7862 *
7863 * The microcode will set the SCSI_CFG1 register using this value
7864 * after it is started below.
7865 *
7866 * Each ASC-38C1600 function has only two cable detect bits.
7867 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
7868 */
7869 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7870
7871 /*
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.
7875 */
7876 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7877 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7878 return ADV_ERROR;
7879 }
7880
7881 /*
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.
7886 *
7887 * If an HVD device is attached, return an error.
7888 */
7889 if (scsi_cfg1 & HVD) {
7890 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
7891 return ADV_ERROR;
7892 }
7893
7894 /*
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.
7902 *
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.
7906 */
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;
7917
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;
7924 }
7925 break;
7926 }
7927 }
7928
7929 /*
7930 * Clear any set TERM_SE bits.
7931 */
7932 scsi_cfg1 &= ~TERM_SE;
7933
7934 /*
7935 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
7936 */
7937 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
7938
7939 /*
7940 * Clear Big Endian and Terminator Polarity bits and set possibly
7941 * modified termination control bits in the Microcode SCSI_CFG1
7942 * Register Value.
7943 *
7944 * Big Endian bit is not used even on big endian machines.
7945 */
7946 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
7947
7948 /*
7949 * Set SCSI_CFG1 Microcode Default Value
7950 *
7951 * Set possibly modified termination control bits in the Microcode
7952 * SCSI_CFG1 Register Value.
7953 *
7954 * The microcode will set the SCSI_CFG1 register using this value
7955 * after it is started below.
7956 */
7957 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7958
7959 /*
7960 * Set MEM_CFG Microcode Default Value
7961 *
7962 * The microcode will set the MEM_CFG register using this value
7963 * after it is started below.
7964 *
7965 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7966 * are defined.
7967 *
7968 * ASC-38C1600 has 32KB internal memory.
7969 *
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.
7974 *
7975 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7976 * BIOS_EN | RAM_SZ_32KB);
7977 */
7978 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7979 BIOS_EN | RAM_SZ_16KB);
7980
7981 /*
7982 * Set SEL_MASK Microcode Default Value
7983 *
7984 * The microcode will set the SEL_MASK register using this value
7985 * after it is started below.
7986 */
7987 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7988 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7989
7990 AdvBuildCarrierFreelist(asc_dvc);
7991
7992 /*
7993 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7994 */
7995 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7996 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7997 return ADV_ERROR;
7998 }
7999 asc_dvc->carr_freelist = (ADV_CARR_T *)
8000 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
8001
8002 /*
8003 * The first command issued will be placed in the stopper carrier.
8004 */
8005 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8006
8007 /*
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.
8011 */
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));
8015
8016 /*
8017 * Set-up the RISC->Host Initiator Response Queue (IRQ).
8018 */
8019 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
8020 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8021 return ADV_ERROR;
8022 }
8023 asc_dvc->carr_freelist = (ADV_CARR_T *)
8024 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
8025
8026 /*
8027 * The first command completed by the RISC will be placed in
8028 * the stopper.
8029 *
8030 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
8031 * completed the RISC will set the ASC_RQ_STOPPER bit.
8032 */
8033 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8034
8035 /*
8036 * Set RISC IRQ physical address start value.
8037 */
8038 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
8039 asc_dvc->carr_pending_cnt = 0;
8040
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);
8046
8047 /* finally, finally, gentlemen, start your engine */
8048 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
8049
8050 /*
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.
8054 */
8055 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
8056 /*
8057 * If the BIOS Signature is present in memory, restore the
8058 * per TID microcode operating variables.
8059 */
8060 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8061 0x55AA) {
8062 /*
8063 * Restore per TID negotiated values.
8064 */
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]);
8074 }
8075 } else {
8076 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8077 warn_code = ASC_WARN_BUSRESET_ERROR;
8078 }
8079 }
8080 }
8081
8082 return warn_code;
8083}
8084
8085/*
8086 * Reset chip and SCSI Bus.
8087 *
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.
8091 */
8092static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8093{
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;
8100
8101 iop_base = asc_dvc->iop_base;
8102
8103 /*
8104 * Save current per TID negotiated values.
8105 */
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);
8110 }
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]);
8115 }
8116
8117 /*
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.
8122 */
8123 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8124 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8125
8126 /*
8127 * Stop chip and reset it.
8128 */
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);
8134
8135 /*
8136 * Reset Adv Library error code, if any, and try
8137 * re-initializing the chip.
8138 */
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);
8146 }
8147
8148 /* Translate initialization return value to status value. */
8149 if (status == 0) {
8150 status = ADV_TRUE;
8151 } else {
8152 status = ADV_FALSE;
8153 }
8154
8155 /*
8156 * Restore the BIOS signature word.
8157 */
8158 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8159
8160 /*
8161 * Restore per TID negotiated values.
8162 */
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);
8167 }
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]);
8172 }
8173
8174 return status;
8175}
8176
8177/*
8178 * adv_async_callback() - Adv Library asynchronous event callback function.
8179 */
8180static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8181{
8182 switch (code) {
8183 case ADV_ASYNC_SCSI_BUS_RESET_DET:
8184 /*
8185 * The firmware detected a SCSI Bus reset.
8186 */
b352f923 8187 ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n");
51219358
MW
8188 break;
8189
8190 case ADV_ASYNC_RDMA_FAILURE:
8191 /*
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.
8195 */
b352f923 8196 ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n");
51219358
MW
8197 AdvResetChipAndSB(adv_dvc_varp);
8198 break;
8199
8200 case ADV_HOST_SCSI_BUS_RESET:
8201 /*
8202 * Host generated SCSI bus reset occurred.
8203 */
b352f923 8204 ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n");
51219358
MW
8205 break;
8206
8207 default:
b352f923 8208 ASC_DBG(0, "unknown code 0x%x\n", code);
51219358
MW
8209 break;
8210 }
8211}
8212
8213/*
8214 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8215 *
8216 * Callback function for the Wide SCSI Adv Library.
8217 */
8218static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8219{
d2411495 8220 struct asc_board *boardp;
51219358
MW
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;
8226
b352f923 8227 ASC_DBG(1, "adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
51219358
MW
8228 (ulong)adv_dvc_varp, (ulong)scsiqp);
8229 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8230
8231 /*
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.
8235 */
8236 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
b352f923 8237 ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
51219358
MW
8238 if (reqp == NULL) {
8239 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8240 return;
8241 }
8242
8243 /*
8244 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8245 * command that has been completed.
8246 *
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.
8250 */
8251 scp = reqp->cmndp;
b352f923 8252 ASC_DBG(1, "scp 0x%p\n", scp);
51219358
MW
8253 if (scp == NULL) {
8254 ASC_PRINT
8255 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8256 return;
8257 }
8258 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8259
8260 shost = scp->device->host;
8261 ASC_STATS(shost, callback);
b352f923 8262 ASC_DBG(1, "shost 0x%p\n", shost);
51219358 8263
d2411495 8264 boardp = shost_priv(shost);
51219358
MW
8265 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8266
8267 /*
8268 * 'done_status' contains the command's ending status.
8269 */
8270 switch (scsiqp->done_status) {
8271 case QD_NO_ERROR:
b352f923 8272 ASC_DBG(2, "QD_NO_ERROR\n");
51219358
MW
8273 scp->result = 0;
8274
8275 /*
8276 * Check for an underrun condition.
8277 *
8278 * If there was no error and an underrun condition, then
8279 * then return the number of underrun bytes.
8280 */
8281 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8282 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
8283 resid_cnt <= scp->request_bufflen) {
b352f923 8284 ASC_DBG(1, "underrun condition %lu bytes\n",
51219358
MW
8285 (ulong)resid_cnt);
8286 scp->resid = resid_cnt;
8287 }
8288 break;
8289
8290 case QD_WITH_ERROR:
b352f923 8291 ASC_DBG(2, "QD_WITH_ERROR\n");
51219358
MW
8292 switch (scsiqp->host_status) {
8293 case QHSTA_NO_ERROR:
8294 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
b352f923 8295 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
51219358
MW
8296 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8297 sizeof(scp->sense_buffer));
8298 /*
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.
8309 */
8310 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8311 STATUS_BYTE(scsiqp->scsi_status);
8312 } else {
8313 scp->result = STATUS_BYTE(scsiqp->scsi_status);
8314 }
8315 break;
8316
8317 default:
8318 /* Some other QHSTA error occurred. */
b352f923 8319 ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
51219358
MW
8320 scp->result = HOST_BYTE(DID_BAD_TARGET);
8321 break;
8322 }
8323 break;
8324
8325 case QD_ABORTED_BY_HOST:
b352f923 8326 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
51219358
MW
8327 scp->result =
8328 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8329 break;
8330
8331 default:
b352f923 8332 ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
51219358
MW
8333 scp->result =
8334 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8335 break;
8336 }
8337
8338 /*
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.
8342 */
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);
8347 }
8348
8349 asc_scsi_done(scp);
8350
8351 /*
8352 * Free all 'adv_sgblk_t' structures allocated for the request.
8353 */
8354 while ((sgblkp = reqp->sgblkp) != NULL) {
8355 /* Remove 'sgblkp' from the request list. */
8356 reqp->sgblkp = sgblkp->next_sgblkp;
8357
8358 /* Add 'sgblkp' to the board free list. */
8359 sgblkp->next_sgblkp = boardp->adv_sgblkp;
8360 boardp->adv_sgblkp = sgblkp;
8361 }
8362
8363 /*
8364 * Free the adv_req_t structure used with the command by adding
8365 * it back to the board free list.
8366 */
8367 reqp->next_reqp = boardp->adv_reqp;
8368 boardp->adv_reqp = reqp;
8369
b352f923 8370 ASC_DBG(1, "done\n");
51219358
MW
8371}
8372
8373/*
8374 * Adv Library Interrupt Service Routine
8375 *
8376 * This function is called by a driver's interrupt service routine.
8377 * The function disables and re-enables interrupts.
8378 *
8379 * When a microcode idle command is completed, the ADV_DVC_VAR
8380 * 'idle_cmd_done' field is set to ADV_TRUE.
8381 *
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.
8387 *
8388 * Return:
8389 * ADV_TRUE(1) - interrupt was pending
8390 * ADV_FALSE(0) - no interrupt was pending
8391 */
8392static int AdvISR(ADV_DVC_VAR *asc_dvc)
8393{
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;
8400
8401 iop_base = asc_dvc->iop_base;
8402
8403 /* Reading the register clears the interrupt. */
8404 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8405
8406 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8407 ADV_INTR_STATUS_INTRC)) == 0) {
8408 return ADV_FALSE;
8409 }
8410
8411 /*
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.
8415 */
8416 if (int_stat & ADV_INTR_STATUS_INTRB) {
8417 uchar intrb_code;
8418
8419 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8420
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);
8431 }
8432 }
8433 }
8434
8435 adv_async_callback(asc_dvc, intrb_code);
8436 }
8437
8438 /*
8439 * Check if the IRQ stopper carrier contains a completed request.
8440 */
8441 while (((irq_next_vpa =
8442 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8443 /*
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.
8446 *
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().
8451 */
8452 scsiq = (ADV_SCSI_REQ_Q *)
8453 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8454
8455 /*
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.
8459 */
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;
8464 }
8465
8466 /*
8467 * Advance the stopper pointer to the next carrier
8468 * ignoring the lower four bits. Free the previous
8469 * stopper carrier.
8470 */
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));
8474
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--;
8479
8480 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8481
8482 /*
8483 * Clear request microcode control flag.
8484 */
8485 scsiq->cntl = 0;
8486
8487 /*
8488 * Notify the driver of the completed request by passing
8489 * the ADV_SCSI_REQ_Q pointer to its callback function.
8490 */
8491 scsiq->a_flag |= ADV_SCSIQ_DONE;
8492 adv_isr_callback(asc_dvc, scsiq);
8493 /*
8494 * Note: After the driver callback function is called, 'scsiq'
8495 * can no longer be referenced.
8496 *
8497 * Fall through and continue processing other completed
8498 * requests...
8499 */
8500 }
8501 return ADV_TRUE;
8502}
8503
8504static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8505{
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);
8510 }
8511 return err_code;
8512}
8513
8514static void AscAckInterrupt(PortAddr iop_base)
8515{
8516 uchar host_flag;
8517 uchar risc_flag;
8518 ushort loop;
8519
8520 loop = 0;
8521 do {
8522 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8523 if (loop++ > 0x7FFF) {
8524 break;
8525 }
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;
8538 }
8539 }
8540 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
51219358
MW
8541}
8542
8543static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8544{
afbb68c3 8545 const uchar *period_table;
51219358
MW
8546 int max_index;
8547 int min_index;
8548 int i;
8549
8550 period_table = asc_dvc->sdtr_period_tbl;
8551 max_index = (int)asc_dvc->max_sdtr_index;
afbb68c3 8552 min_index = (int)asc_dvc->min_sdtr_index;
51219358
MW
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;
8557 }
8558 }
8559 return (uchar)max_index;
8560 } else {
8561 return (uchar)(max_index + 1);
8562 }
8563}
8564
8565static uchar
8566AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8567{
8568 EXT_MSG sdtr_buf;
8569 uchar sdtr_period_index;
8570 PortAddr iop_base;
8571
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;
8591 }
8592}
8593
8594static uchar
8595AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8596{
8597 uchar byte;
8598 uchar sdtr_period_ix;
8599
8600 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
afbb68c3 8601 if (sdtr_period_ix > asc_dvc->max_sdtr_index)
51219358 8602 return 0xFF;
51219358
MW
8603 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8604 return byte;
8605}
8606
8607static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8608{
8609 ASC_SCSI_BIT_ID_TYPE org_id;
8610 int i;
8611 int sta = TRUE;
8612
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;
8618 }
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;
8626 }
8627 } else {
8628 sta = FALSE;
8629 }
8630 AscSetBank(iop_base, 1);
8631 AscWriteChipDvcID(iop_base, org_id);
8632 AscSetBank(iop_base, 0);
8633 return (sta);
8634}
8635
8636static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8637{
8638 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8639 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8640}
8641
8642static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8643{
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;
d2411495 8661 struct asc_board *boardp;
51219358
MW
8662
8663 BUG_ON(!asc_dvc->drv_ptr);
8664 boardp = asc_dvc->drv_ptr;
8665
8666 iop_base = asc_dvc->iop_base;
8667 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8668
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;
8682 }
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;
8687 }
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;
8694 }
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);
8702
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)) {
8708
8709 sdtr_accept = FALSE;
8710 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8711 }
8712 if ((ext_msg.xfer_period <
afbb68c3 8713 asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index])
51219358
MW
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->
afbb68c3 8720 min_sdtr_index];
51219358
MW
8721 }
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)) {
8727
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;
8734 }
8735 }
8736 if (ext_msg.req_ack_offset == 0) {
8737
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)) {
51219358
MW
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 {
51219358
MW
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;
8774 }
8775 }
8776
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) {
8786
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 {
8800
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);
8813 }
8814 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8815
8816 q_cntl |= QC_REQ_SENSE;
8817
8818 if ((asc_dvc->init_sdtr & target_id) != 0) {
8819
8820 asc_dvc->sdtr_done &= ~target_id;
8821
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));
8832 }
8833
8834 AscWriteLramByte(iop_base,
8835 (ushort)(halt_q_addr +
8836 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8837
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)
8844 ) {
8845
8846 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8847 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8848
8849 }
8850 AscWriteLramByte(iop_base,
8851 (ushort)(halt_q_addr +
8852 (ushort)ASC_SCSIQ_B_TAG_CODE),
8853 tag_code);
8854
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);
8863
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);
8867
8868 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8869 return (0);
8870 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8871
8872 AscMemWordCopyPtrFromLram(iop_base,
8873 ASCV_MSGOUT_BEG,
8874 (uchar *)&out_msg,
8875 sizeof(EXT_MSG) >> 1);
8876
8877 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8878 (out_msg.msg_len == MS_SDTR_LEN) &&
8879 (out_msg.msg_req == EXTENDED_SDTR)) {
8880
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;
8885 }
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) {
8893
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)) {
8903
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;
8910
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;
8916
8917 AscWriteLramByte(iop_base,
8918 (ushort)((ushort)
8919 ASCV_MAX_DVC_QNG_BEG
8920 + (ushort)
8921 tid_no),
8922 cur_dvc_qng);
8923
8924 /*
8925 * Set the device queue depth to the
8926 * number of active requests when the
8927 * QUEUE FULL condition was encountered.
8928 */
8929 boardp->queue_full |= target_id;
8930 boardp->queue_full_cnt[tid_no] =
8931 cur_dvc_qng;
8932 }
8933 }
8934 }
8935 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8936 return (0);
8937 }
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;
8951
8952 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8953 if (q_no == ASC_QLINK_END)
8954 return 0;
8955
8956 q_addr = ASC_QNO_TO_QADDR(q_no);
8957
8958 /*
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.
8963 */
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))));
8970
8971 /*
8972 * Get request's first and working SG queue.
8973 */
8974 sg_wk_q_no = AscReadLramByte(iop_base,
8975 (ushort)(q_addr +
8976 ASC_SCSIQ_B_SG_WK_QP));
8977
8978 first_sg_wk_q_no = AscReadLramByte(iop_base,
8979 (ushort)(q_addr +
8980 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8981
8982 /*
8983 * Reset request's working SG queue back to the
8984 * first SG queue.
8985 */
8986 AscWriteLramByte(iop_base,
8987 (ushort)(q_addr +
8988 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8989 first_sg_wk_q_no);
8990
8991 sg_head = scsiq->sg_head;
8992
8993 /*
8994 * Set sg_entry_cnt to the number of SG elements
8995 * that will be completed on this interrupt.
8996 *
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.
9001 */
9002 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
9003 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9004
9005 /*
9006 * Keep track of remaining number of SG elements that
9007 * will need to be handled on the next interrupt.
9008 */
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;
9013 }
9014
9015 /*
9016 * Copy SG elements into the list of allocated SG queues.
9017 *
9018 * Last index completed is saved in scsiq->next_sg_index.
9019 */
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;
9029 /*
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.
9035 */
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 {
9040 /*
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.
9045 */
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;
9050 }
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;
9056 }
9057
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);
9063
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);
9069
9070 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9071
9072 /*
9073 * If the just completed SG queue contained the
9074 * last SG element, then no more SG queues need
9075 * to be written.
9076 */
9077 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9078 break;
9079 }
9080
9081 next_qp = AscReadLramByte(iop_base,
9082 (ushort)(q_addr +
9083 ASC_SCSIQ_B_FWD));
9084 q_addr = ASC_QNO_TO_QADDR(next_qp);
9085 }
9086
9087 /*
9088 * Clear the halt condition so the RISC will be restarted
9089 * after the return.
9090 */
9091 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9092 return (0);
9093 }
9094#endif /* CC_VERY_LONG_SG_LIST */
9095 return (0);
9096}
1da177e4 9097
1da177e4 9098/*
51219358
MW
9099 * void
9100 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
1da177e4 9101 *
51219358
MW
9102 * Calling/Exit State:
9103 * none
1da177e4 9104 *
51219358
MW
9105 * Description:
9106 * Input an ASC_QDONE_INFO structure from the chip
1da177e4 9107 */
51219358
MW
9108static void
9109DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9110{
9111 int i;
9112 ushort word;
9113
9114 AscSetChipLramAddr(iop_base, s_addr);
9115 for (i = 0; i < 2 * words; i += 2) {
9116 if (i == 10) {
9117 continue;
9118 }
9119 word = inpw(iop_base + IOP_RAM_DATA);
9120 inbuf[i] = word & 0xff;
9121 inbuf[i + 1] = (word >> 8) & 0xff;
9122 }
9123 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9124}
9125
9126static uchar
9127_AscCopyLramScsiDoneQ(PortAddr iop_base,
9128 ushort q_addr,
9129 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9130{
9131 ushort _val;
9132 uchar sg_queue_cnt;
9133
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);
9138
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);
9152
9153 /*
9154 * Read high word of remain bytes from alternate location.
9155 */
9156 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9157 (ushort)(q_addr +
9158 (ushort)
9159 ASC_SCSIQ_W_ALT_DC1)))
9160 << 16);
9161 /*
9162 * Read low word of remain bytes from original location.
9163 */
9164 scsiq->remain_bytes += AscReadLramWord(iop_base,
9165 (ushort)(q_addr + (ushort)
9166 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9167
9168 scsiq->remain_bytes &= max_dma_count;
9169 return sg_queue_cnt;
9170}
9171
9172/*
9173 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9174 *
9175 * Interrupt callback function for the Narrow SCSI Asc Library.
9176 */
9177static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9178{
d2411495 9179 struct asc_board *boardp;
51219358
MW
9180 struct scsi_cmnd *scp;
9181 struct Scsi_Host *shost;
9182
b352f923 9183 ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
51219358
MW
9184 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9185
9186 /*
9187 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
9188 * command that has been completed.
9189 */
9190 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
b352f923 9191 ASC_DBG(1, "scp 0x%p\n", scp);
51219358
MW
9192
9193 if (scp == NULL) {
9194 ASC_PRINT("asc_isr_callback: scp is NULL\n");
9195 return;
9196 }
9197 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9198
9199 shost = scp->device->host;
9200 ASC_STATS(shost, callback);
b352f923 9201 ASC_DBG(1, "shost 0x%p\n", shost);
51219358 9202
d2411495 9203 boardp = shost_priv(shost);
51219358
MW
9204 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9205
9206 /*
9207 * 'qdonep' contains the command's ending status.
9208 */
9209 switch (qdonep->d3.done_stat) {
9210 case QD_NO_ERROR:
b352f923 9211 ASC_DBG(2, "QD_NO_ERROR\n");
51219358
MW
9212 scp->result = 0;
9213
9214 /*
9215 * Check for an underrun condition.
9216 *
9217 * If there was no error and an underrun condition, then
9218 * return the number of underrun bytes.
9219 */
9220 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
9221 qdonep->remain_bytes <= scp->request_bufflen) {
b352f923 9222 ASC_DBG(1, "underrun condition %u bytes\n",
51219358
MW
9223 (unsigned)qdonep->remain_bytes);
9224 scp->resid = qdonep->remain_bytes;
9225 }
9226 break;
9227
9228 case QD_WITH_ERROR:
b352f923 9229 ASC_DBG(2, "QD_WITH_ERROR\n");
51219358
MW
9230 switch (qdonep->d3.host_stat) {
9231 case QHSTA_NO_ERROR:
9232 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
b352f923 9233 ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
51219358
MW
9234 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9235 sizeof(scp->sense_buffer));
9236 /*
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.
9247 */
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);
9252 }
9253 break;
9254
9255 default:
9256 /* QHSTA error occurred */
b352f923 9257 ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
51219358
MW
9258 scp->result = HOST_BYTE(DID_BAD_TARGET);
9259 break;
9260 }
9261 break;
9262
9263 case QD_ABORTED_BY_HOST:
b352f923 9264 ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
51219358
MW
9265 scp->result =
9266 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9267 scsi_msg) |
9268 STATUS_BYTE(qdonep->d3.scsi_stat);
9269 break;
9270
9271 default:
b352f923 9272 ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
51219358
MW
9273 scp->result =
9274 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9275 scsi_msg) |
9276 STATUS_BYTE(qdonep->d3.scsi_stat);
9277 break;
9278 }
9279
9280 /*
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.
9284 */
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);
9289 }
1da177e4 9290
51219358 9291 asc_scsi_done(scp);
51219358
MW
9292}
9293
9294static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9295{
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;
9312
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;
9349 }
9350 AscWriteLramByte(iop_base,
9351 (ushort)(sg_q_addr + (ushort)
9352 ASC_SCSIQ_B_STATUS),
9353 QS_FREE);
9354 }
9355 n_q_used = sg_queue_cnt + 1;
9356 AscPutVarDoneQTail(iop_base, sg_list_qp);
9357 }
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;
9373 }
9374 }
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]--;
9379 }
9380 } else {
9381 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9382 scsiq->d3.done_stat = QD_WITH_ERROR;
9383 goto FATAL_ERR_QDONE;
9384 }
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;
9393 }
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;
9409 }
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);
9422 }
9423 }
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;
9435 }
9436 }
9437 }
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);
9444 }
9445 return (0x80);
9446 }
9447 }
9448 return (0);
9449}
1da177e4 9450
51219358
MW
9451static int AscISR(ASC_DVC_VAR *asc_dvc)
9452{
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;
1da177e4 9461
51219358
MW
9462 iop_base = asc_dvc->iop_base;
9463 int_pending = FALSE;
1da177e4 9464
51219358
MW
9465 if (AscIsIntPending(iop_base) == 0)
9466 return int_pending;
9467
9468 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9469 return ERR;
9470 }
9471 if (asc_dvc->in_critical_cnt != 0) {
9472 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9473 return ERR;
9474 }
9475 if (asc_dvc->is_in_int) {
9476 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9477 return ERR;
9478 }
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);
9493 }
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);
9499 }
9500 }
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);
9515 }
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) {
9521 }
9522 } else {
9523 do {
9524 if ((status =
9525 AscIsrQDone(asc_dvc)) == 1) {
9526 break;
9527 }
9528 } while (status == 0x11);
9529 }
9530 if ((status & 0x80) != 0)
9531 int_pending = ERR;
9532 }
9533 }
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;
9539}
1da177e4
LT
9540
9541/*
51219358 9542 * advansys_reset()
1da177e4 9543 *
51219358 9544 * Reset the bus associated with the command 'scp'.
1da177e4 9545 *
51219358
MW
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.
1da177e4 9549 */
51219358 9550static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 9551{
52fa0777 9552 struct Scsi_Host *shost = scp->device->host;
d2411495 9553 struct asc_board *boardp = shost_priv(shost);
52fa0777 9554 unsigned long flags;
27c868c2 9555 int status;
51219358 9556 int ret = SUCCESS;
27c868c2 9557
b352f923 9558 ASC_DBG(1, "0x%p\n", scp);
27c868c2 9559
52fa0777 9560 ASC_STATS(shost, reset);
27c868c2 9561
52fa0777 9562 scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
51219358
MW
9563
9564 if (ASC_NARROW_BOARD(boardp)) {
52fa0777 9565 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
1da177e4 9566
52fa0777 9567 /* Reset the chip and SCSI bus. */
b352f923 9568 ASC_DBG(1, "before AscInitAsc1000Driver()\n");
52fa0777 9569 status = AscInitAsc1000Driver(asc_dvc);
27c868c2 9570
51219358 9571 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
52fa0777
MW
9572 if (asc_dvc->err_code) {
9573 scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9574 "0x%x\n", asc_dvc->err_code);
51219358
MW
9575 ret = FAILED;
9576 } else if (status) {
52fa0777
MW
9577 scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9578 "0x%x\n", status);
27c868c2 9579 } else {
52fa0777
MW
9580 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9581 "successful\n");
27c868c2 9582 }
a9f4a59a 9583
b352f923 9584 ASC_DBG(1, "after AscInitAsc1000Driver()\n");
f092d229 9585 spin_lock_irqsave(shost->host_lock, flags);
a9f4a59a 9586 } else {
a9f4a59a 9587 /*
51219358
MW
9588 * If the suggest reset bus flags are set, then reset the bus.
9589 * Otherwise only reset the device.
a9f4a59a 9590 */
52fa0777 9591 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
a9f4a59a
MW
9592
9593 /*
51219358 9594 * Reset the target's SCSI bus.
a9f4a59a 9595 */
b352f923 9596 ASC_DBG(1, "before AdvResetChipAndSB()\n");
52fa0777 9597 switch (AdvResetChipAndSB(adv_dvc)) {
51219358 9598 case ASC_TRUE:
52fa0777
MW
9599 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9600 "successful\n");
51219358
MW
9601 break;
9602 case ASC_FALSE:
9603 default:
52fa0777 9604 scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
51219358
MW
9605 ret = FAILED;
9606 break;
b9d96614 9607 }
f092d229 9608 spin_lock_irqsave(shost->host_lock, flags);
52fa0777 9609 AdvISR(adv_dvc);
b9d96614
MW
9610 }
9611
51219358
MW
9612 /* Save the time of the most recently completed reset. */
9613 boardp->last_reset = jiffies;
f092d229 9614 spin_unlock_irqrestore(shost->host_lock, flags);
b9d96614 9615
b352f923 9616 ASC_DBG(1, "ret %d\n", ret);
b9d96614 9617
51219358 9618 return ret;
b9d96614
MW
9619}
9620
1da177e4 9621/*
51219358 9622 * advansys_biosparam()
1da177e4 9623 *
51219358
MW
9624 * Translate disk drive geometry if the "BIOS greater than 1 GB"
9625 * support is enabled for a drive.
1da177e4 9626 *
51219358
MW
9627 * ip (information pointer) is an int array with the following definition:
9628 * ip[0]: heads
9629 * ip[1]: sectors
9630 * ip[2]: cylinders
1da177e4 9631 */
51219358
MW
9632static int
9633advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9634 sector_t capacity, int ip[])
1da177e4 9635{
d2411495 9636 struct asc_board *boardp = shost_priv(sdev->host);
1da177e4 9637
b352f923 9638 ASC_DBG(1, "begin\n");
51219358 9639 ASC_STATS(sdev->host, biosparam);
51219358
MW
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;
9648 }
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;
9657 }
27c868c2 9658 }
51219358 9659 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
b352f923 9660 ASC_DBG(1, "end\n");
51219358
MW
9661 return 0;
9662}
1da177e4 9663
51219358
MW
9664/*
9665 * First-level interrupt handler.
9666 *
9667 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9668 */
9669static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9670{
51219358 9671 struct Scsi_Host *shost = dev_id;
d2411495 9672 struct asc_board *boardp = shost_priv(shost);
51219358 9673 irqreturn_t result = IRQ_NONE;
27c868c2 9674
b352f923 9675 ASC_DBG(2, "boardp 0x%p\n", boardp);
f092d229 9676 spin_lock(shost->host_lock);
51219358
MW
9677 if (ASC_NARROW_BOARD(boardp)) {
9678 if (AscIsIntPending(shost->io_port)) {
9679 result = IRQ_HANDLED;
9680 ASC_STATS(shost, interrupt);
b352f923 9681 ASC_DBG(1, "before AscISR()\n");
51219358
MW
9682 AscISR(&boardp->dvc_var.asc_dvc_var);
9683 }
9684 } else {
b352f923 9685 ASC_DBG(1, "before AdvISR()\n");
51219358
MW
9686 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9687 result = IRQ_HANDLED;
9688 ASC_STATS(shost, interrupt);
9689 }
27c868c2 9690 }
f092d229 9691 spin_unlock(shost->host_lock);
1da177e4 9692
b352f923 9693 ASC_DBG(1, "end\n");
51219358
MW
9694 return result;
9695}
27c868c2 9696
51219358
MW
9697static int AscHostReqRiscHalt(PortAddr iop_base)
9698{
9699 int count = 0;
9700 int sta = 0;
9701 uchar saved_stop_code;
9702
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;
27c868c2 9712 }
51219358
MW
9713 mdelay(100);
9714 } while (count++ < 20);
9715 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9716 return (sta);
9717}
1da177e4 9718
51219358
MW
9719static int
9720AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9721{
9722 int sta = FALSE;
1da177e4 9723
51219358
MW
9724 if (AscHostReqRiscHalt(iop_base)) {
9725 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9726 AscStartChip(iop_base);
27c868c2 9727 }
51219358
MW
9728 return sta;
9729}
1da177e4 9730
51219358
MW
9731static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9732{
9733 char type = sdev->type;
9734 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
27c868c2 9735
51219358
MW
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;
27c868c2 9740
51219358
MW
9741 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9742 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
27c868c2 9743
51219358
MW
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;
9748
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);
9752}
1da177e4 9753
51219358
MW
9754static void
9755advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9756{
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;
27c868c2 9759
51219358
MW
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;
9766 }
9767
9768 if (orig_init_sdtr != asc_dvc->init_sdtr)
9769 AscAsyncFix(asc_dvc, sdev);
27c868c2 9770 }
1da177e4 9771
51219358
MW
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;
9777 }
9778 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9779 asc_dvc->max_dvc_qng[sdev->id]);
27c868c2 9780 }
51219358
MW
9781 } else {
9782 if (sdev->lun == 0) {
9783 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9784 asc_dvc->use_tagged_qng &= ~tid_bit;
27c868c2 9785 }
51219358 9786 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
27c868c2 9787 }
1da177e4 9788
51219358
MW
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);
27c868c2 9797
51219358
MW
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]);
9803 }
9804}
27c868c2 9805
51219358
MW
9806/*
9807 * Wide Transfers
9808 *
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.
9812 */
9813static void
9814advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
9815{
9816 unsigned short cfg_word;
9817 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9818 if ((cfg_word & tidmask) != 0)
9819 return;
27c868c2 9820
51219358
MW
9821 cfg_word |= tidmask;
9822 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
27c868c2
MW
9823
9824 /*
51219358
MW
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.
27c868c2 9829 */
51219358
MW
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);
9836}
1da177e4 9837
51219358
MW
9838/*
9839 * Synchronous Transfers
9840 *
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.
9844 */
9845static void
9846advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
9847{
9848 unsigned short cfg_word;
9849 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9850 if ((cfg_word & tidmask) != 0)
9851 return;
1da177e4 9852
51219358
MW
9853 cfg_word |= tidmask;
9854 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
1da177e4 9855
27c868c2 9856 /*
51219358
MW
9857 * Clear the microcode "SDTR negotiation" done indicator for the
9858 * target to cause it to negotiate with the new setting set above.
27c868c2 9859 */
51219358
MW
9860 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9861 cfg_word &= ~tidmask;
9862 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9863}
27c868c2 9864
51219358
MW
9865/*
9866 * PPR (Parallel Protocol Request) Capable
9867 *
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.
9872 */
9873static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
9874 AdvPortAddr iop_base, unsigned short tidmask)
9875{
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);
9879}
27c868c2 9880
51219358
MW
9881static void
9882advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
9883{
9884 AdvPortAddr iop_base = adv_dvc->iop_base;
9885 unsigned short tidmask = 1 << sdev->id;
9886
9887 if (sdev->lun == 0) {
9888 /*
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.
9892 */
27c868c2 9893
51219358
MW
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);
9900
9901 /*
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.
9906 */
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);
27c868c2
MW
9917 }
9918 }
1da177e4 9919
51219358
MW
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);
9925 }
9926}
27c868c2 9927
51219358
MW
9928/*
9929 * Set the number of commands to queue per device for the
9930 * specified host adapter.
9931 */
9932static int advansys_slave_configure(struct scsi_device *sdev)
9933{
d2411495 9934 struct asc_board *boardp = shost_priv(sdev->host);
27c868c2 9935
51219358
MW
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);
1da177e4 9942
51219358
MW
9943 return 0;
9944}
27c868c2 9945
d2411495 9946static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
05848b6e 9947 struct asc_scsi_q *asc_scsi_q)
51219358 9948{
05848b6e 9949 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
27c868c2
MW
9950
9951 /*
51219358 9952 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
27c868c2 9953 */
05848b6e 9954 asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
27c868c2
MW
9955
9956 /*
51219358 9957 * Build the ASC_SCSI_Q request.
27c868c2 9958 */
05848b6e
MW
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 =
51219358 9964 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
05848b6e 9965 asc_scsi_q->q1.sense_addr =
51219358 9966 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
05848b6e 9967 asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
27c868c2
MW
9968
9969 /*
51219358
MW
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.
9975 *
9976 * The request count is incremented below for every successfully
9977 * started request.
27c868c2 9978 *
27c868c2 9979 */
51219358
MW
9980 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
9981 (boardp->reqcnt[scp->device->id] % 255) == 0) {
05848b6e 9982 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
51219358 9983 } else {
05848b6e 9984 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
51219358 9985 }
27c868c2
MW
9986
9987 /*
51219358
MW
9988 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
9989 * buffer command.
27c868c2 9990 */
51219358
MW
9991 if (scp->use_sg == 0) {
9992 /*
9993 * CDB request of single contiguous buffer.
9994 */
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;
05848b6e
MW
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);
51219358
MW
10002 ASC_STATS_ADD(scp->device->host, cont_xfer,
10003 ASC_CEILING(scp->request_bufflen, 512));
05848b6e
MW
10004 asc_scsi_q->q1.sg_queue_cnt = 0;
10005 asc_scsi_q->sg_head = NULL;
51219358
MW
10006 } else {
10007 /*
10008 * CDB scatter-gather request list.
10009 */
10010 int sgcnt;
10011 int use_sg;
10012 struct scatterlist *slp;
05848b6e 10013 struct asc_sg_head *asc_sg_head;
27c868c2 10014
51219358
MW
10015 slp = (struct scatterlist *)scp->request_buffer;
10016 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10017 scp->sc_data_direction);
27c868c2 10018
51219358 10019 if (use_sg > scp->device->host->sg_tablesize) {
9d0e96eb
MW
10020 scmd_printk(KERN_ERR, scp, "use_sg %d > "
10021 "sg_tablesize %d\n", use_sg,
10022 scp->device->host->sg_tablesize);
51219358
MW
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;
10027 }
27c868c2 10028
51219358 10029 ASC_STATS(scp->device->host, sg_cnt);
27c868c2 10030
05848b6e
MW
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;
10038 }
51219358 10039
05848b6e
MW
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;
51219358 10044 /* This is a byte value, otherwise it would need to be swapped. */
05848b6e 10045 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
51219358 10046 ASC_STATS_ADD(scp->device->host, sg_elem,
05848b6e 10047 asc_sg_head->entry_cnt);
51219358
MW
10048
10049 /*
10050 * Convert scatter-gather list into ASC_SG_HEAD list.
10051 */
10052 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
05848b6e 10053 asc_sg_head->sg_list[sgcnt].addr =
51219358 10054 cpu_to_le32(sg_dma_address(slp));
05848b6e 10055 asc_sg_head->sg_list[sgcnt].bytes =
51219358
MW
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));
27c868c2
MW
10059 }
10060 }
1da177e4 10061
b352f923 10062 ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
51219358
MW
10063 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10064
10065 return ASC_NOERROR;
27c868c2 10066}
1da177e4 10067
27c868c2 10068/*
51219358 10069 * Build scatter-gather list for Adv Library (Wide Board).
27c868c2 10070 *
51219358
MW
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.
27c868c2 10075 *
51219358
MW
10076 * Return:
10077 * ADV_SUCCESS(1) - SG List successfully created
10078 * ADV_ERROR(-1) - SG List creation failed
27c868c2 10079 */
51219358 10080static int
d2411495 10081adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
51219358 10082 int use_sg)
27c868c2 10083{
51219358
MW
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;
27c868c2 10090 int i;
27c868c2 10091
51219358
MW
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;
1da177e4 10097
51219358
MW
10098 for (;;) {
10099 /*
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.
10103 */
10104 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
b352f923 10105 ASC_DBG(1, "no free adv_sgblk_t\n");
51219358 10106 ASC_STATS(scp->device->host, adv_build_nosg);
1da177e4 10107
51219358
MW
10108 /*
10109 * Allocation failed. Free 'adv_sgblk_t' structures
10110 * already allocated for the request.
10111 */
10112 while ((sgblkp = reqp->sgblkp) != NULL) {
10113 /* Remove 'sgblkp' from the request list. */
10114 reqp->sgblkp = sgblkp->next_sgblkp;
27c868c2 10115
51219358
MW
10116 /* Add 'sgblkp' to the board free list. */
10117 sgblkp->next_sgblkp = boardp->adv_sgblkp;
10118 boardp->adv_sgblkp = sgblkp;
10119 }
10120 return ASC_BUSY;
10121 }
1da177e4 10122
51219358
MW
10123 /* Complete 'adv_sgblk_t' board allocation. */
10124 boardp->adv_sgblkp = sgblkp->next_sgblkp;
10125 sgblkp->next_sgblkp = NULL;
1da177e4 10126
51219358
MW
10127 /*
10128 * Get 8 byte aligned virtual and physical addresses
10129 * for the allocated ADV_SG_BLOCK structure.
10130 */
10131 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10132 sg_block_paddr = virt_to_bus(sg_block);
27c868c2 10133
51219358
MW
10134 /*
10135 * Check if this is the first 'adv_sgblk_t' for the
10136 * request.
10137 */
10138 if (reqp->sgblkp == NULL) {
10139 /* Request's first scatter-gather block. */
10140 reqp->sgblkp = sgblkp;
27c868c2 10141
51219358
MW
10142 /*
10143 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10144 * address pointers.
10145 */
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;
10152
10153 /*
10154 * Point the previous ADV_SG_BLOCK structure to
10155 * the newly allocated ADV_SG_BLOCK structure.
10156 */
10157 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
27c868c2 10158 }
1da177e4 10159
51219358
MW
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));
27c868c2 10167
51219358
MW
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;
10172 }
10173 slp++;
10174 }
10175 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10176 prev_sg_block = sg_block;
27c868c2 10177 }
51219358 10178}
1da177e4 10179
51219358
MW
10180/*
10181 * Build a request structure for the Adv Library (Wide Board).
10182 *
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.
10185 *
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.
10189 */
10190static int
d2411495 10191adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
51219358
MW
10192 ADV_SCSI_REQ_Q **adv_scsiqpp)
10193{
10194 adv_req_t *reqp;
10195 ADV_SCSI_REQ_Q *scsiqp;
10196 int i;
10197 int ret;
1da177e4 10198
27c868c2 10199 /*
51219358
MW
10200 * Allocate an adv_req_t structure from the board to execute
10201 * the command.
27c868c2 10202 */
51219358 10203 if (boardp->adv_reqp == NULL) {
b352f923 10204 ASC_DBG(1, "no free adv_req_t\n");
51219358
MW
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;
27c868c2 10211 }
1da177e4 10212
27c868c2 10213 /*
51219358 10214 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
27c868c2 10215 */
51219358 10216 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
27c868c2
MW
10217
10218 /*
51219358 10219 * Initialize the structure.
27c868c2 10220 */
51219358 10221 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
27c868c2
MW
10222
10223 /*
51219358 10224 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
27c868c2 10225 */
51219358 10226 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
27c868c2
MW
10227
10228 /*
51219358 10229 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
27c868c2 10230 */
51219358 10231 reqp->cmndp = scp;
27c868c2
MW
10232
10233 /*
51219358 10234 * Build the ADV_SCSI_REQ_Q request.
27c868c2 10235 */
51219358
MW
10236
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];
10242 }
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];
27c868c2 10246 }
1da177e4 10247
51219358
MW
10248 scsiqp->target_id = scp->device->id;
10249 scsiqp->target_lun = scp->device->lun;
10250
10251 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10252 scsiqp->sense_len = sizeof(scp->sense_buffer);
27c868c2
MW
10253
10254 /*
51219358
MW
10255 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
10256 * buffer command.
27c868c2 10257 */
51219358
MW
10258
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));
10262
10263 if (scp->use_sg == 0) {
10264 /*
10265 * CDB request of single contiguous buffer.
10266 */
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;
10278 }
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 {
10286 /*
10287 * CDB scatter-gather request list.
10288 */
10289 struct scatterlist *slp;
10290 int use_sg;
10291
10292 slp = (struct scatterlist *)scp->request_buffer;
10293 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10294 scp->sc_data_direction);
10295
10296 if (use_sg > ADV_MAX_SG_LIST) {
9d0e96eb
MW
10297 scmd_printk(KERN_ERR, scp, "use_sg %d > "
10298 "ADV_MAX_SG_LIST %d\n", use_sg,
51219358
MW
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);
10303
10304 /*
10305 * Free the 'adv_req_t' structure by adding it back
10306 * to the board free list.
10307 */
10308 reqp->next_reqp = boardp->adv_reqp;
10309 boardp->adv_reqp = reqp;
10310
10311 return ASC_ERROR;
10312 }
10313
10314 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10315 if (ret != ADV_SUCCESS) {
10316 /*
10317 * Free the adv_req_t structure by adding it back to
10318 * the board free list.
10319 */
10320 reqp->next_reqp = boardp->adv_reqp;
10321 boardp->adv_reqp = reqp;
10322
10323 return ret;
10324 }
10325
10326 ASC_STATS(scp->device->host, sg_cnt);
10327 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
27c868c2 10328 }
1da177e4 10329
51219358
MW
10330 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10331 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
27c868c2 10332
51219358 10333 *adv_scsiqpp = scsiqp;
27c868c2 10334
51219358
MW
10335 return ASC_NOERROR;
10336}
10337
10338static int AscSgListToQueue(int sg_list)
10339{
10340 int n_sg_list_qs;
10341
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;
10346}
10347
10348static uint
10349AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10350{
10351 uint cur_used_qs;
10352 uint cur_free_qs;
10353 ASC_SCSI_BIT_ID_TYPE target_id;
10354 uchar tid_no;
10355
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;
10361 }
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;
10368 }
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;
10374 }
10375 return cur_free_qs;
10376 }
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;
10381 }
10382 }
10383 return 0;
10384}
10385
10386static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10387{
10388 ushort q_addr;
10389 uchar next_qp;
10390 uchar q_status;
10391
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;
10400}
10401
10402static uchar
10403AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10404{
10405 uchar i;
27c868c2 10406
51219358
MW
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;
10411 }
10412 return free_q_head;
10413}
27c868c2 10414
51219358
MW
10415/*
10416 * void
10417 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10418 *
10419 * Calling/Exit State:
10420 * none
10421 *
10422 * Description:
10423 * Output an ASC_SCSI_Q structure to the chip
10424 */
10425static void
10426DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10427{
10428 int i;
10429
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;
10435 }
10436 outpw(iop_base + IOP_RAM_DATA,
10437 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
27c868c2 10438 }
51219358 10439}
1da177e4 10440
51219358
MW
10441static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10442{
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;
10449
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;
10462 }
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;
27c868c2 10466 }
51219358
MW
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);
10471
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;
10481}
10482
10483static int
10484AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10485{
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;
1da177e4 10498
51219358
MW
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
27c868c2 10506 /*
51219358
MW
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.
27c868c2 10511 */
51219358
MW
10512 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10513 /*
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.
10519 */
10520 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
27c868c2 10521
51219358
MW
10522 /*
10523 * Keep track of remaining number of SG elements that will
10524 * need to be handled from a_isr.c.
10525 */
10526 scsiq->remain_sg_entry_cnt =
10527 sg_head->entry_cnt - ASC_MAX_SG_LIST;
10528 } else {
10529#endif /* CC_VERY_LONG_SG_LIST */
10530 /*
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.
10534 */
10535 sg_entry_cnt = sg_head->entry_cnt - 1;
10536#if CC_VERY_LONG_SG_LIST
10537 }
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;
10561 }
10562 } else {
10563#if CC_VERY_LONG_SG_LIST
10564 /*
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.
10569 */
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
10576 }
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;
10588 }
10589 sg_entry_cnt = 0;
10590 }
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;
27c868c2 10607 }
51219358
MW
10608 } else {
10609 scsiq->q1.cntl &= ~QC_SG_HEAD;
27c868c2 10610 }
51219358
MW
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);
10615}
27c868c2 10616
51219358
MW
10617static int
10618AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10619{
10620 PortAddr iop_base;
10621 uchar free_q_head;
10622 uchar next_qp;
10623 uchar tid_no;
10624 uchar target_ix;
10625 int sta;
27c868c2 10626
51219358
MW
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);
10641 }
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);
27c868c2
MW
10647 }
10648 }
51219358
MW
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]++;
27c868c2 10653 }
51219358
MW
10654 return sta;
10655}
27c868c2 10656
51219358
MW
10657#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10658static 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
10675};
27c868c2 10676
51219358
MW
10677static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10678{
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;
27c868c2 10695
51219358
MW
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;
27c868c2 10703 }
51219358
MW
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);
10721 }
10722 }
10723 if (asc_dvc->in_critical_cnt != 0) {
10724 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10725 return (ERR);
10726 }
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);
10732 }
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);
10737 }
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);
10745 }
10746 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10747 }
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);
10758 }
10759 } else {
10760 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10761 }
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;
10772 }
10773 if (scsi_cmd == disable_cmd) {
10774 disable_syn_offset_one_fix =
10775 TRUE;
10776 break;
10777 }
10778 }
10779 }
10780 }
10781 }
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;
10788 }
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)
10806 &&
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);
10827 }
10828 }
10829 }
10830 }
10831 sg_head->entry_to_copy = sg_head->entry_cnt;
10832#if CC_VERY_LONG_SG_LIST
27c868c2 10833 /*
51219358
MW
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.
27c868c2 10837 */
51219358
MW
10838 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10839 sg_entry_cnt = ASC_MAX_SG_LIST;
10840 }
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);
27c868c2 10851 }
51219358
MW
10852 }
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)
10864 &&
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;
10883 }
10884 }
10885 }
10886 }
10887 }
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);
27c868c2
MW
10895 }
10896 }
10897 }
51219358
MW
10898 asc_dvc->in_critical_cnt--;
10899 return (sta);
1da177e4
LT
10900}
10901
10902/*
51219358 10903 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
1da177e4 10904 *
51219358
MW
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.
10908 *
10909 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
10910 * set to SCSI_MAX_RETRY.
10911 *
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.
10915 *
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.
10922 */
10923static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
10924{
10925 AdvPortAddr iop_base;
10926 ADV_DCNT req_size;
10927 ADV_PADDR req_paddr;
10928 ADV_CARR_T *new_carrp;
1da177e4 10929
27c868c2 10930 /*
51219358 10931 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
27c868c2 10932 */
51219358
MW
10933 if (scsiq->target_id > ADV_MAX_TID) {
10934 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
10935 scsiq->done_status = QD_WITH_ERROR;
27c868c2
MW
10936 return ADV_ERROR;
10937 }
1da177e4 10938
51219358 10939 iop_base = asc_dvc->iop_base;
1da177e4 10940
27c868c2 10941 /*
51219358
MW
10942 * Allocate a carrier ensuring at least one carrier always
10943 * remains on the freelist and initialize fields.
27c868c2 10944 */
51219358
MW
10945 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
10946 return ADV_BUSY;
27c868c2 10947 }
51219358
MW
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++;
1da177e4 10951
27c868c2 10952 /*
51219358
MW
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.
27c868c2 10956 */
51219358 10957 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
27c868c2
MW
10958
10959 /*
51219358 10960 * Clear the ADV_SCSI_REQ_Q done flag.
27c868c2 10961 */
51219358 10962 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
27c868c2 10963
51219358
MW
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);
27c868c2 10967
51219358
MW
10968 BUG_ON(req_paddr & 31);
10969 BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
10970
10971 /* Wait for assertion before making little-endian */
10972 req_paddr = cpu_to_le32(req_paddr);
27c868c2 10973
51219358
MW
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;
10977
10978 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
27c868c2 10979 /*
51219358
MW
10980 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
10981 * order during initialization.
27c868c2 10982 */
51219358 10983 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
1da177e4 10984
27c868c2 10985 /*
51219358
MW
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.
27c868c2 10989 */
51219358 10990 asc_dvc->icq_sp->areq_vpa = req_paddr;
1da177e4 10991
27c868c2 10992 /*
51219358
MW
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.
27c868c2 10996 */
51219358 10997 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
27c868c2
MW
10998
10999 /*
51219358 11000 * Set the host adapter stopper pointer to point to the new carrier.
27c868c2 11001 */
51219358
MW
11002 asc_dvc->icq_sp = new_carrp;
11003
11004 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
11005 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
11006 /*
11007 * Tickle the RISC to tell it to read its Command Queue Head pointer.
11008 */
11009 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
11010 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
11011 /*
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.
11015 */
11016 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
11017 ADV_TICKLE_NOP);
11018 }
11019 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
11020 /*
11021 * Notify the RISC a carrier is ready by writing the physical
11022 * address of the new carrier stopper to the COMMA register.
11023 */
11024 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
11025 le32_to_cpu(new_carrp->carr_pa));
27c868c2 11026 }
1da177e4 11027
51219358
MW
11028 return ADV_SUCCESS;
11029}
11030
11031/*
11032 * Execute a single 'Scsi_Cmnd'.
11033 *
11034 * The function 'done' is called when the request has been completed.
11035 *
11036 * Scsi_Cmnd:
11037 *
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
11045 *
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
11051 * }
11052 *
11053 * sense_buffer - sense command buffer
11054 *
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
11061 *
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
11066 *
11067 * If this function returns ASC_NOERROR the request will be completed
11068 * from the interrupt handler.
11069 *
11070 * If this function returns ASC_ERROR the host error code has been set,
11071 * and the called must call asc_scsi_done.
11072 *
11073 * If ASC_BUSY is returned the request will be returned to the midlayer
11074 * and re-tried later.
11075 */
11076static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
11077{
41d2493d 11078 int ret, err_code;
d2411495 11079 struct asc_board *boardp = shost_priv(scp->device->host);
51219358 11080
b352f923 11081 ASC_DBG(1, "scp 0x%p\n", scp);
27c868c2 11082
51219358 11083 if (ASC_NARROW_BOARD(boardp)) {
41d2493d 11084 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
05848b6e 11085 struct asc_scsi_q asc_scsi_q;
27c868c2 11086
41d2493d 11087 /* asc_build_req() can not return ASC_BUSY. */
05848b6e
MW
11088 ret = asc_build_req(boardp, scp, &asc_scsi_q);
11089 if (ret == ASC_ERROR) {
51219358
MW
11090 ASC_STATS(scp->device->host, build_error);
11091 return ASC_ERROR;
11092 }
1da177e4 11093
41d2493d 11094 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
05848b6e 11095 kfree(asc_scsi_q.sg_head);
41d2493d 11096 err_code = asc_dvc->err_code;
51219358 11097 } else {
41d2493d
MW
11098 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
11099 ADV_SCSI_REQ_Q *adv_scsiqp;
27c868c2 11100
51219358
MW
11101 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
11102 case ASC_NOERROR:
b352f923 11103 ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
51219358
MW
11104 break;
11105 case ASC_BUSY:
b352f923 11106 ASC_DBG(1, "adv_build_req ASC_BUSY\n");
51219358
MW
11107 /*
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.
11112 */
11113 return ASC_BUSY;
11114 case ASC_ERROR:
11115 default:
b352f923 11116 ASC_DBG(1, "adv_build_req ASC_ERROR\n");
51219358
MW
11117 ASC_STATS(scp->device->host, build_error);
11118 return ASC_ERROR;
11119 }
11120
41d2493d
MW
11121 ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
11122 err_code = adv_dvc->err_code;
11123 }
11124
11125 switch (ret) {
11126 case ASC_NOERROR:
11127 ASC_STATS(scp->device->host, exe_noerror);
11128 /*
11129 * Increment monotonically increasing per device
11130 * successful request counter. Wrapping doesn't matter.
11131 */
11132 boardp->reqcnt[scp->device->id]++;
b352f923 11133 ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
41d2493d
MW
11134 break;
11135 case ASC_BUSY:
11136 ASC_STATS(scp->device->host, exe_busy);
11137 break;
11138 case ASC_ERROR:
9d0e96eb
MW
11139 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
11140 "err_code 0x%x\n", err_code);
41d2493d
MW
11141 ASC_STATS(scp->device->host, exe_error);
11142 scp->result = HOST_BYTE(DID_ERROR);
11143 break;
11144 default:
9d0e96eb
MW
11145 scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
11146 "err_code 0x%x\n", err_code);
41d2493d
MW
11147 ASC_STATS(scp->device->host, exe_unknown);
11148 scp->result = HOST_BYTE(DID_ERROR);
11149 break;
27c868c2 11150 }
1da177e4 11151
b352f923 11152 ASC_DBG(1, "end\n");
51219358
MW
11153 return ret;
11154}
27c868c2 11155
51219358
MW
11156/*
11157 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11158 *
11159 * This function always returns 0. Command return status is saved
11160 * in the 'scp' result field.
11161 */
11162static int
11163advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11164{
11165 struct Scsi_Host *shost = scp->device->host;
51219358 11166 int asc_res, result = 0;
27c868c2 11167
51219358
MW
11168 ASC_STATS(shost, queuecommand);
11169 scp->scsi_done = done;
27c868c2 11170
51219358 11171 asc_res = asc_execute_scsi_cmnd(scp);
51219358
MW
11172
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;
11183 }
11184
11185 return result;
11186}
11187
11188static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11189{
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);
11193}
11194
11195/*
11196 * Return the BIOS address of the adapter at the specified
11197 * I/O port and with the specified bus type.
11198 */
11199static unsigned short __devinit
11200AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11201{
11202 unsigned short cfg_lsw;
11203 unsigned short bios_addr;
27c868c2
MW
11204
11205 /*
51219358
MW
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.
27c868c2 11209 */
51219358
MW
11210 if (bus_type & ASC_IS_PCI)
11211 return 0;
27c868c2 11212
51219358
MW
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;
11218 }
27c868c2 11219
51219358 11220 cfg_lsw = AscGetChipCfgLsw(iop_base);
27c868c2
MW
11221
11222 /*
51219358 11223 * ISA PnP uses the top bit as the 32K BIOS flag
27c868c2 11224 */
51219358
MW
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;
11229}
11230
11231static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11232{
11233 ushort cfg_lsw;
11234
11235 if (AscGetChipScsiID(iop_base) == new_host_id) {
11236 return (new_host_id);
27c868c2 11237 }
51219358
MW
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));
11243}
27c868c2 11244
51219358
MW
11245static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11246{
11247 unsigned char sc;
27c868c2 11248
51219358
MW
11249 AscSetBank(iop_base, 1);
11250 sc = inp(iop_base + IOP_REG_SC);
11251 AscSetBank(iop_base, 0);
11252 return sc;
11253}
27c868c2 11254
51219358
MW
11255static unsigned char __devinit
11256AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11257{
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;
27c868c2 11265 }
51219358
MW
11266 return AscGetChipVerNo(iop_base);
11267}
27c868c2 11268
51219358
MW
11269#ifdef CONFIG_ISA
11270static void __devinit AscEnableIsaDma(uchar dma_channel)
11271{
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));
11278 }
51219358
MW
11279}
11280#endif /* CONFIG_ISA */
11281
11282static int AscStopQueueExe(PortAddr iop_base)
11283{
11284 int count = 0;
11285
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);
11293 }
11294 mdelay(100);
11295 } while (count++ < 20);
11296 }
11297 return (0);
11298}
11299
11300static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11301{
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;
27c868c2 11307}
1da177e4 11308
51219358
MW
11309#ifdef CONFIG_ISA
11310static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
27c868c2 11311{
51219358 11312 ushort channel;
1da177e4 11313
51219358
MW
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);
11320}
1da177e4 11321
51219358
MW
11322static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11323{
11324 ushort cfg_lsw;
11325 uchar value;
1da177e4 11326
51219358
MW
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));
11336 }
11337 return 0;
11338}
1da177e4 11339
51219358
MW
11340static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11341{
11342 uchar speed_value;
1da177e4 11343
51219358
MW
11344 AscSetBank(iop_base, 1);
11345 speed_value = AscReadChipDmaSpeed(iop_base);
11346 speed_value &= 0x07;
11347 AscSetBank(iop_base, 0);
11348 return speed_value;
11349}
1da177e4 11350
51219358
MW
11351static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11352{
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);
11358}
11359#endif /* CONFIG_ISA */
1da177e4 11360
51219358
MW
11361static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11362{
11363 int i;
11364 PortAddr iop_base;
11365 ushort warn_code;
11366 uchar chip_version;
1da177e4 11367
51219358
MW
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;
27c868c2 11374 }
51219358
MW
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;
afbb68c3 11392 asc_dvc->min_sdtr_index = 0;
51219358
MW
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;
51219358
MW
11404 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11405 asc_dvc->cfg->chip_version = chip_version;
afbb68c3 11406 asc_dvc->sdtr_period_tbl = asc_syn_xfer_period;
51219358
MW
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;
afbb68c3 11411 asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period;
51219358
MW
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));
27c868c2
MW
11420 }
11421 }
51219358
MW
11422 if (asc_dvc->bus_type == ASC_IS_PCI) {
11423 AscSetExtraControl(iop_base,
11424 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11425 }
1da177e4 11426
51219358
MW
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;
27c868c2 11433 }
51219358
MW
11434 asc_dvc->cfg->isa_dma_channel =
11435 (uchar)AscGetIsaDmaChannel(iop_base);
27c868c2 11436 }
51219358
MW
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;
27c868c2 11444 }
51219358
MW
11445 return warn_code;
11446}
1da177e4 11447
51219358
MW
11448static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11449{
11450 int retry;
27c868c2 11451
51219358
MW
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;
27c868c2 11459 }
51219358
MW
11460 return 0;
11461}
1da177e4 11462
51219358
MW
11463static void __devinit AscWaitEEPRead(void)
11464{
11465 mdelay(1);
27c868c2 11466}
1da177e4 11467
51219358 11468static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
27c868c2 11469{
51219358
MW
11470 ushort read_wval;
11471 uchar cmd_reg;
27c868c2 11472
51219358
MW
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;
11481}
27c868c2 11482
51219358
MW
11483static ushort __devinit
11484AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11485{
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;
27c868c2 11493
51219358
MW
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;
11500 }
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;
11507 }
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) {
11511 /*
11512 * Swap all char fields - must unswap bytes already swapped
11513 * by AscReadEEPWord().
11514 */
11515 *wbuf = le16_to_cpu(wval);
11516 } else {
11517 /* Don't swap word field at the end - cntl field. */
11518 *wbuf = wval;
11519 }
11520 sum += wval; /* Checksum treats all EEPROM data as words. */
11521 }
27c868c2 11522 /*
51219358
MW
11523 * Read the checksum word which will be compared against 'sum'
11524 * by the caller. Word field already swapped.
27c868c2 11525 */
51219358
MW
11526 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11527 return sum;
11528}
1da177e4 11529
51219358
MW
11530static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11531{
11532 PortAddr iop_base;
11533 ushort q_addr;
11534 ushort saved_word;
11535 int sta;
1da177e4 11536
51219358
MW
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);
11548 }
11549 return (sta);
11550}
1da177e4 11551
51219358
MW
11552static void __devinit AscWaitEEPWrite(void)
11553{
11554 mdelay(20);
51219358 11555}
1da177e4 11556
51219358
MW
11557static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11558{
11559 ushort read_back;
11560 int retry;
1da177e4 11561
51219358
MW
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);
11569 }
11570 if (retry++ > ASC_EEP_MAX_RETRY) {
11571 return (0);
11572 }
27c868c2 11573 }
51219358 11574}
27c868c2 11575
51219358
MW
11576static ushort __devinit
11577AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11578{
11579 ushort read_wval;
11580
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));
11593 }
11594 return (read_wval);
11595}
11596
11597static int __devinit
11598AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11599{
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;
11608
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++;
27c868c2 11617 }
51219358
MW
11618 }
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;
11625 }
11626 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11627 if (s_addr <= uchar_end_in_config) {
11628 /*
11629 * This is a char field. Swap char fields before they are
11630 * swapped again by AscWriteEEPWord().
11631 */
11632 word = cpu_to_le16(*wbuf);
11633 if (word !=
11634 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11635 n_error++;
11636 }
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++;
11642 }
27c868c2 11643 }
51219358
MW
11644 sum += *wbuf; /* Checksum calculated from word values. */
11645 }
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++;
27c868c2 11650 }
1da177e4 11651
51219358
MW
11652 /* Read EEPROM back again. */
11653 wbuf = (ushort *)cfg_buf;
27c868c2 11654 /*
51219358 11655 * Read two config words; Byte-swapping done by AscReadEEPWord().
27c868c2 11656 */
51219358
MW
11657 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11658 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11659 n_error++;
27c868c2
MW
11660 }
11661 }
51219358
MW
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;
11668 }
11669 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11670 if (s_addr <= uchar_end_in_config) {
11671 /*
11672 * Swap all char fields. Must unswap bytes already swapped
11673 * by AscReadEEPWord().
11674 */
11675 word =
11676 le16_to_cpu(AscReadEEPWord
11677 (iop_base, (uchar)s_addr));
27c868c2 11678 } else {
51219358
MW
11679 /* Don't swap word field at the end - cntl field. */
11680 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11681 }
11682 if (*wbuf != word) {
11683 n_error++;
27c868c2
MW
11684 }
11685 }
51219358
MW
11686 /* Read checksum; Byte swapping not needed. */
11687 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11688 n_error++;
27c868c2 11689 }
51219358
MW
11690 return n_error;
11691}
1da177e4 11692
51219358
MW
11693static int __devinit
11694AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11695{
11696 int retry;
11697 int n_error;
27c868c2 11698
51219358
MW
11699 retry = 0;
11700 while (TRUE) {
11701 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11702 bus_type)) == 0) {
11703 break;
11704 }
11705 if (++retry > ASC_EEP_MAX_RETRY) {
11706 break;
11707 }
11708 }
11709 return n_error;
11710}
27c868c2 11711
51219358
MW
11712static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
11713{
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;
27c868c2 11722
51219358
MW
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? */
11732 }
11733 if (AscIsChipHalted(iop_base) == FALSE) {
11734 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11735 return (warn_code);
11736 }
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);
11741 }
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);
11749 }
11750 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
b352f923 11751 ASC_DBG(1, "chksum 0x%x\n", chksum);
51219358
MW
11752 if (chksum == 0) {
11753 chksum = 0xaa55;
11754 }
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);
11762 }
11763 if (eep_config->cfg_msw != cfg_msw) {
11764 warn_code |= ASC_WARN_EEPROM_RECOVER;
11765 eep_config->cfg_msw =
11766 AscGetChipCfgMsw(iop_base);
11767 }
11768 }
11769 }
11770 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11771 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
b352f923 11772 ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
51219358
MW
11773 if (chksum != eep_config->chksum) {
11774 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
11775 ASC_CHIP_VER_PCI_ULTRA_3050) {
b352f923 11776 ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
51219358
MW
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;
27c868c2 11793 } else {
51219358
MW
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;
11798 }
11799 }
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;
27c868c2 11826 }
51219358
MW
11827 } else {
11828 }
11829 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11830 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11831 }
11832 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11833 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11834 }
11835 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11836 eep_config->max_tag_qng = eep_config->max_total_qng;
11837 }
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;
11840 }
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;
11846 }
51219358
MW
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)) {
afbb68c3 11852 asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
27c868c2 11853 }
1da177e4 11854
51219358
MW
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 |
afbb68c3 11860 (asc_dvc->min_sdtr_index << 4));
51219358
MW
11861 }
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",
11868 i);
27c868c2 11869 } else {
51219358
MW
11870 ASC_PRINT
11871 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
27c868c2
MW
11872 }
11873 }
51219358 11874 return (warn_code);
1da177e4
LT
11875}
11876
9d0e96eb 11877static int __devinit AscInitGetConfig(struct Scsi_Host *shost)
1da177e4 11878{
9d0e96eb
MW
11879 struct asc_board *board = shost_priv(shost);
11880 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
51219358 11881 unsigned short warn_code = 0;
27c868c2 11882
51219358
MW
11883 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11884 if (asc_dvc->err_code != 0)
11885 return asc_dvc->err_code;
27c868c2 11886
51219358
MW
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;
11895 }
27c868c2 11896
51219358
MW
11897 switch (warn_code) {
11898 case 0: /* No error */
11899 break;
11900 case ASC_WARN_IO_PORT_ROTATE:
9d0e96eb
MW
11901 shost_printk(KERN_WARNING, shost, "I/O port address "
11902 "modified\n");
51219358
MW
11903 break;
11904 case ASC_WARN_AUTO_CONFIG:
9d0e96eb
MW
11905 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
11906 "enabled\n");
51219358
MW
11907 break;
11908 case ASC_WARN_EEPROM_CHKSUM:
9d0e96eb 11909 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
51219358
MW
11910 break;
11911 case ASC_WARN_IRQ_MODIFIED:
9d0e96eb 11912 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
51219358
MW
11913 break;
11914 case ASC_WARN_CMD_QNG_CONFLICT:
9d0e96eb
MW
11915 shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o "
11916 "disconnects\n");
51219358
MW
11917 break;
11918 default:
9d0e96eb
MW
11919 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
11920 warn_code);
51219358
MW
11921 break;
11922 }
1da177e4 11923
9d0e96eb
MW
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);
27c868c2 11927
51219358
MW
11928 return asc_dvc->err_code;
11929}
1da177e4 11930
9d0e96eb 11931static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
51219358 11932{
9d0e96eb
MW
11933 struct asc_board *board = shost_priv(shost);
11934 ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
51219358
MW
11935 PortAddr iop_base = asc_dvc->iop_base;
11936 unsigned short cfg_msw;
11937 unsigned short warn_code = 0;
1da177e4 11938
51219358
MW
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;
27c868c2 11945 }
1da177e4 11946
51219358
MW
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);
11952 }
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;
11957 }
11958 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11959 warn_code |= ASC_WARN_AUTO_CONFIG;
11960 }
51219358
MW
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) {
27c868c2 11966 } else {
51219358
MW
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;
11972 }
27c868c2 11973 }
51219358
MW
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;
27c868c2
MW
11980 }
11981 }
51219358
MW
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;
11985 }
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);
11990 }
11991#endif /* CONFIG_ISA */
1da177e4 11992
51219358
MW
11993 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11994
11995 switch (warn_code) {
11996 case 0: /* No error. */
11997 break;
11998 case ASC_WARN_IO_PORT_ROTATE:
9d0e96eb
MW
11999 shost_printk(KERN_WARNING, shost, "I/O port address "
12000 "modified\n");
51219358
MW
12001 break;
12002 case ASC_WARN_AUTO_CONFIG:
9d0e96eb
MW
12003 shost_printk(KERN_WARNING, shost, "I/O port increment switch "
12004 "enabled\n");
51219358
MW
12005 break;
12006 case ASC_WARN_EEPROM_CHKSUM:
9d0e96eb 12007 shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
51219358
MW
12008 break;
12009 case ASC_WARN_IRQ_MODIFIED:
9d0e96eb 12010 shost_printk(KERN_WARNING, shost, "IRQ modified\n");
51219358
MW
12011 break;
12012 case ASC_WARN_CMD_QNG_CONFLICT:
9d0e96eb
MW
12013 shost_printk(KERN_WARNING, shost, "tag queuing w/o "
12014 "disconnects\n");
51219358
MW
12015 break;
12016 default:
9d0e96eb
MW
12017 shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
12018 warn_code);
51219358 12019 break;
27c868c2 12020 }
1da177e4 12021
9d0e96eb
MW
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);
27c868c2 12025
51219358
MW
12026 return asc_dvc->err_code;
12027}
27c868c2 12028
51219358
MW
12029/*
12030 * EEPROM Configuration.
12031 *
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.
12036 *
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.
12044 */
12045static 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 */
12081};
27c868c2 12082
51219358
MW
12083static 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 */
12119};
1da177e4 12120
51219358
MW
12121static 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 */
12184};
27c868c2 12185
51219358
MW
12186static 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 */
12249};
27c868c2 12250
51219358
MW
12251static 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 */
12314};
1da177e4 12315
51219358
MW
12316static 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 */
12379};
1da177e4 12380
51219358 12381#ifdef CONFIG_PCI
1da177e4 12382/*
51219358 12383 * Wait for EEPROM command to complete
1da177e4 12384 */
51219358 12385static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 12386{
51219358 12387 int eep_delay_ms;
27c868c2 12388
51219358
MW
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;
27c868c2 12393 }
51219358 12394 mdelay(1);
27c868c2 12395 }
51219358
MW
12396 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12397 0)
12398 BUG();
1da177e4
LT
12399}
12400
12401/*
51219358 12402 * Read the EEPROM from specified location
1da177e4 12403 */
51219358
MW
12404static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12405{
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);
12410}
12411
12412/*
12413 * Write the EEPROM from 'cfg_buf'.
12414 */
12415void __devinit
12416AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
1da177e4 12417{
27c868c2 12418 ushort *wbuf;
51219358 12419 ushort addr, chksum;
27c868c2
MW
12420 ushort *charfields;
12421
27c868c2 12422 wbuf = (ushort *)cfg_buf;
51219358 12423 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
27c868c2
MW
12424 chksum = 0;
12425
51219358
MW
12426 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12427 AdvWaitEEPCmd(iop_base);
12428
12429 /*
12430 * Write EEPROM from word 0 to word 20.
12431 */
12432 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12433 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12434 ushort word;
12435
27c868c2 12436 if (*charfields++) {
51219358 12437 word = cpu_to_le16(*wbuf);
27c868c2 12438 } else {
51219358 12439 word = *wbuf;
27c868c2 12440 }
51219358
MW
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);
27c868c2 12447 }
51219358
MW
12448
12449 /*
12450 * Write EEPROM checksum at word 21.
12451 */
12452 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12453 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12454 AdvWaitEEPCmd(iop_base);
27c868c2
MW
12455 wbuf++;
12456 charfields++;
12457
51219358
MW
12458 /*
12459 * Write EEPROM OEM name at words 22 to 29.
12460 */
12461 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12462 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12463 ushort word;
12464
27c868c2 12465 if (*charfields++) {
51219358
MW
12466 word = cpu_to_le16(*wbuf);
12467 } else {
12468 word = *wbuf;
27c868c2 12469 }
51219358
MW
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);
27c868c2 12474 }
51219358
MW
12475 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12476 AdvWaitEEPCmd(iop_base);
1da177e4
LT
12477}
12478
12479/*
51219358 12480 * Write the EEPROM from 'cfg_buf'.
1da177e4 12481 */
51219358
MW
12482void __devinit
12483AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 12484{
27c868c2 12485 ushort *wbuf;
27c868c2 12486 ushort *charfields;
51219358 12487 ushort addr, chksum;
27c868c2 12488
27c868c2 12489 wbuf = (ushort *)cfg_buf;
51219358 12490 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
27c868c2
MW
12491 chksum = 0;
12492
51219358
MW
12493 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12494 AdvWaitEEPCmd(iop_base);
12495
12496 /*
12497 * Write EEPROM from word 0 to word 20.
12498 */
12499 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12500 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12501 ushort word;
12502
27c868c2 12503 if (*charfields++) {
51219358 12504 word = cpu_to_le16(*wbuf);
27c868c2 12505 } else {
51219358 12506 word = *wbuf;
27c868c2 12507 }
51219358
MW
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);
27c868c2 12514 }
51219358
MW
12515
12516 /*
12517 * Write EEPROM checksum at word 21.
12518 */
12519 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12520 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12521 AdvWaitEEPCmd(iop_base);
27c868c2
MW
12522 wbuf++;
12523 charfields++;
12524
51219358
MW
12525 /*
12526 * Write EEPROM OEM name at words 22 to 29.
12527 */
12528 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12529 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12530 ushort word;
12531
27c868c2 12532 if (*charfields++) {
51219358
MW
12533 word = cpu_to_le16(*wbuf);
12534 } else {
12535 word = *wbuf;
27c868c2 12536 }
51219358
MW
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);
27c868c2 12541 }
51219358 12542 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
27c868c2 12543 AdvWaitEEPCmd(iop_base);
1da177e4
LT
12544}
12545
12546/*
12547 * Write the EEPROM from 'cfg_buf'.
12548 */
78e77d8b 12549void __devinit
51219358 12550AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 12551{
27c868c2 12552 ushort *wbuf;
27c868c2 12553 ushort *charfields;
51219358 12554 ushort addr, chksum;
27c868c2
MW
12555
12556 wbuf = (ushort *)cfg_buf;
51219358 12557 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
27c868c2
MW
12558 chksum = 0;
12559
12560 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12561 AdvWaitEEPCmd(iop_base);
12562
12563 /*
12564 * Write EEPROM from word 0 to word 20.
12565 */
12566 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12567 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12568 ushort word;
12569
12570 if (*charfields++) {
12571 word = cpu_to_le16(*wbuf);
12572 } else {
12573 word = *wbuf;
12574 }
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);
b009bef6 12580 mdelay(ADV_EEP_DELAY_MS);
27c868c2 12581 }
1da177e4 12582
27c868c2
MW
12583 /*
12584 * Write EEPROM checksum at word 21.
12585 */
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++;
12591
12592 /*
12593 * Write EEPROM OEM name at words 22 to 29.
12594 */
12595 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12596 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12597 ushort word;
12598
12599 if (*charfields++) {
12600 word = cpu_to_le16(*wbuf);
12601 } else {
12602 word = *wbuf;
12603 }
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);
12608 }
12609 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12610 AdvWaitEEPCmd(iop_base);
1da177e4
LT
12611}
12612
12613/*
51219358
MW
12614 * Read EEPROM configuration into the specified buffer.
12615 *
12616 * Return a checksum based on the EEPROM configuration read.
1da177e4 12617 */
51219358
MW
12618static ushort __devinit
12619AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
1da177e4 12620{
51219358 12621 ushort wval, chksum;
27c868c2 12622 ushort *wbuf;
51219358 12623 int eep_addr;
27c868c2 12624 ushort *charfields;
27c868c2 12625
51219358 12626 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
27c868c2 12627 wbuf = (ushort *)cfg_buf;
27c868c2
MW
12628 chksum = 0;
12629
51219358
MW
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;
12638 }
12639 }
12640 /* Read checksum word. */
12641 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12642 wbuf++;
12643 charfields++;
27c868c2 12644
51219358
MW
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);
12651 }
12652 }
12653 return chksum;
12654}
12655
12656/*
12657 * Read EEPROM configuration into the specified buffer.
12658 *
12659 * Return a checksum based on the EEPROM configuration read.
12660 */
12661static ushort __devinit
12662AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12663{
12664 ushort wval, chksum;
12665 ushort *wbuf;
12666 int eep_addr;
12667 ushort *charfields;
27c868c2 12668
51219358
MW
12669 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12670 wbuf = (ushort *)cfg_buf;
12671 chksum = 0;
12672
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. */
27c868c2 12677 if (*charfields++) {
51219358 12678 *wbuf = le16_to_cpu(wval);
27c868c2 12679 } else {
51219358 12680 *wbuf = wval;
27c868c2 12681 }
27c868c2 12682 }
51219358
MW
12683 /* Read checksum word. */
12684 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
27c868c2
MW
12685 wbuf++;
12686 charfields++;
12687
51219358
MW
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);
27c868c2 12692 if (*charfields++) {
51219358 12693 *wbuf = le16_to_cpu(*wbuf);
27c868c2 12694 }
27c868c2 12695 }
51219358 12696 return chksum;
1da177e4
LT
12697}
12698
12699/*
51219358
MW
12700 * Read EEPROM configuration into the specified buffer.
12701 *
12702 * Return a checksum based on the EEPROM configuration read.
1da177e4 12703 */
51219358
MW
12704static ushort __devinit
12705AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 12706{
51219358 12707 ushort wval, chksum;
27c868c2 12708 ushort *wbuf;
51219358 12709 int eep_addr;
27c868c2 12710 ushort *charfields;
27c868c2 12711
27c868c2 12712 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
51219358 12713 wbuf = (ushort *)cfg_buf;
27c868c2
MW
12714 chksum = 0;
12715
51219358
MW
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. */
27c868c2 12720 if (*charfields++) {
51219358 12721 *wbuf = le16_to_cpu(wval);
27c868c2 12722 } else {
51219358 12723 *wbuf = wval;
27c868c2 12724 }
27c868c2 12725 }
51219358
MW
12726 /* Read checksum word. */
12727 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
27c868c2
MW
12728 wbuf++;
12729 charfields++;
12730
51219358
MW
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);
27c868c2 12735 if (*charfields++) {
51219358 12736 *wbuf = le16_to_cpu(*wbuf);
27c868c2 12737 }
27c868c2 12738 }
51219358 12739 return chksum;
1da177e4
LT
12740}
12741
1da177e4 12742/*
51219358
MW
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.
1da177e4 12746 *
51219358 12747 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4 12748 *
51219358
MW
12749 * For a non-fatal error return a warning code. If there are no warnings
12750 * then 0 is returned.
1da177e4 12751 *
51219358 12752 * Note: Chip is stopped on entry.
1da177e4 12753 */
51219358 12754static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 12755{
27c868c2 12756 AdvPortAddr iop_base;
51219358
MW
12757 ushort warn_code;
12758 ADVEEP_3550_CONFIG eep_config;
1da177e4 12759
27c868c2 12760 iop_base = asc_dvc->iop_base;
1da177e4 12761
51219358 12762 warn_code = 0;
27c868c2
MW
12763
12764 /*
51219358
MW
12765 * Read the board's EEPROM configuration.
12766 *
12767 * Set default values if a bad checksum is found.
27c868c2 12768 */
51219358
MW
12769 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12770 warn_code |= ASC_WARN_EEPROM_CHKSUM;
27c868c2 12771
51219358
MW
12772 /*
12773 * Set EEPROM default values.
12774 */
12775 memcpy(&eep_config, &Default_3550_EEPROM_Config,
12776 sizeof(ADVEEP_3550_CONFIG));
27c868c2 12777
51219358
MW
12778 /*
12779 * Assume the 6 byte board serial number that was read from
12780 * EEPROM is correct even if the EEPROM checksum failed.
12781 */
12782 eep_config.serial_number_word3 =
12783 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
27c868c2 12784
51219358
MW
12785 eep_config.serial_number_word2 =
12786 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 12787
51219358
MW
12788 eep_config.serial_number_word1 =
12789 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
27c868c2 12790
51219358
MW
12791 AdvSet3550EEPConfig(iop_base, &eep_config);
12792 }
12793 /*
12794 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12795 * EEPROM configuration that was read.
12796 *
12797 * This is the mapping of EEPROM fields to Adv Library fields.
12798 */
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;
27c868c2 12814
27c868c2 12815 /*
51219358
MW
12816 * Set the host maximum queuing (max. 253, min. 16) and the per device
12817 * maximum queuing (max. 63, min. 4).
27c868c2 12818 */
51219358
MW
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;
12827 }
12828 }
12829
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;
12838 }
12839 }
27c868c2
MW
12840
12841 /*
51219358
MW
12842 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12843 * set 'max_dvc_qng' to 'max_host_qng'.
27c868c2 12844 */
51219358
MW
12845 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12846 eep_config.max_dvc_qng = eep_config.max_host_qng;
12847 }
27c868c2
MW
12848
12849 /*
51219358
MW
12850 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12851 * values based on possibly adjusted EEPROM values.
27c868c2 12852 */
51219358
MW
12853 asc_dvc->max_host_qng = eep_config.max_host_qng;
12854 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
27c868c2
MW
12855
12856 /*
51219358
MW
12857 * If the EEPROM 'termination' field is set to automatic (0), then set
12858 * the ADV_DVC_CFG 'termination' field to automatic also.
12859 *
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.
27c868c2 12863 */
51219358
MW
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;
27c868c2 12870
51219358
MW
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;
12874
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 {
27c868c2 12880 /*
51219358
MW
12881 * The EEPROM 'termination' field contains a bad value. Use
12882 * automatic termination instead.
27c868c2 12883 */
51219358
MW
12884 asc_dvc->cfg->termination = 0;
12885 warn_code |= ASC_WARN_EEPROM_TERMINATION;
27c868c2 12886 }
27c868c2 12887 }
1da177e4 12888
51219358 12889 return warn_code;
1da177e4
LT
12890}
12891
12892/*
51219358
MW
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.
1da177e4 12896 *
51219358
MW
12897 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12898 *
12899 * For a non-fatal error return a warning code. If there are no warnings
12900 * then 0 is returned.
12901 *
12902 * Note: Chip is stopped on entry.
1da177e4 12903 */
51219358 12904static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 12905{
51219358
MW
12906 AdvPortAddr iop_base;
12907 ushort warn_code;
12908 ADVEEP_38C0800_CONFIG eep_config;
12909 uchar tid, termination;
12910 ushort sdtr_speed = 0;
27c868c2 12911
51219358 12912 iop_base = asc_dvc->iop_base;
1da177e4 12913
51219358 12914 warn_code = 0;
27c868c2
MW
12915
12916 /*
51219358
MW
12917 * Read the board's EEPROM configuration.
12918 *
12919 * Set default values if a bad checksum is found.
27c868c2 12920 */
51219358
MW
12921 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
12922 eep_config.check_sum) {
12923 warn_code |= ASC_WARN_EEPROM_CHKSUM;
27c868c2 12924
51219358
MW
12925 /*
12926 * Set EEPROM default values.
12927 */
12928 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
12929 sizeof(ADVEEP_38C0800_CONFIG));
1da177e4 12930
51219358
MW
12931 /*
12932 * Assume the 6 byte board serial number that was read from
12933 * EEPROM is correct even if the EEPROM checksum failed.
12934 */
12935 eep_config.serial_number_word3 =
12936 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 12937
51219358
MW
12938 eep_config.serial_number_word2 =
12939 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 12940
51219358
MW
12941 eep_config.serial_number_word1 =
12942 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
27c868c2 12943
51219358 12944 AdvSet38C0800EEPConfig(iop_base, &eep_config);
27c868c2 12945 }
27c868c2 12946 /*
51219358
MW
12947 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
12948 * EEPROM configuration that was read.
12949 *
12950 * This is the mapping of EEPROM fields to Adv Library fields.
27c868c2 12951 */
51219358
MW
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;
27c868c2
MW
12969
12970 /*
51219358
MW
12971 * For every Target ID if any of its 'sdtr_speed[1234]' bits
12972 * are set, then set an 'sdtr_able' bit for it.
27c868c2 12973 */
51219358
MW
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;
12984 }
12985 if (sdtr_speed & ADV_MAX_TID) {
12986 asc_dvc->sdtr_able |= (1 << tid);
12987 }
12988 sdtr_speed >>= 4;
12989 }
27c868c2
MW
12990
12991 /*
51219358
MW
12992 * Set the host maximum queuing (max. 253, min. 16) and the per device
12993 * maximum queuing (max. 63, min. 4).
27c868c2 12994 */
51219358
MW
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;
13003 }
27c868c2 13004 }
1da177e4 13005
51219358
MW
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;
13014 }
13015 }
13016
13017 /*
13018 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13019 * set 'max_dvc_qng' to 'max_host_qng'.
13020 */
13021 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13022 eep_config.max_dvc_qng = eep_config.max_host_qng;
27c868c2 13023 }
1da177e4 13024
27c868c2 13025 /*
51219358
MW
13026 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13027 * values based on possibly adjusted EEPROM values.
27c868c2 13028 */
51219358
MW
13029 asc_dvc->max_host_qng = eep_config.max_host_qng;
13030 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
27c868c2
MW
13031
13032 /*
51219358
MW
13033 * If the EEPROM 'termination' field is set to automatic (0), then set
13034 * the ADV_DVC_CFG 'termination' field to automatic also.
13035 *
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.
27c868c2 13039 */
51219358
MW
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;
13046
13047 /* Enable manual control with low off / high on. */
13048 } else if (eep_config.termination_se == 2) {
13049 termination = TERM_SE_HI;
13050
13051 /* Enable manual control with low on / high on. */
13052 } else if (eep_config.termination_se == 3) {
13053 termination = TERM_SE;
13054 } else {
13055 /*
13056 * The EEPROM 'termination_se' field contains a bad value.
13057 * Use automatic termination instead.
13058 */
13059 termination = 0;
13060 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13061 }
27c868c2 13062 }
51219358
MW
13063
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;
13070
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;
13074
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 {
13079 /*
13080 * The EEPROM 'termination_lvd' field contains a bad value.
13081 * Use automatic termination instead.
13082 */
13083 asc_dvc->cfg->termination = termination;
13084 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13085 }
27c868c2 13086 }
1da177e4 13087
51219358 13088 return warn_code;
1da177e4
LT
13089}
13090
13091/*
51219358
MW
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.
1da177e4 13095 *
51219358 13096 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4 13097 *
51219358
MW
13098 * For a non-fatal error return a warning code. If there are no warnings
13099 * then 0 is returned.
1da177e4 13100 *
51219358 13101 * Note: Chip is stopped on entry.
1da177e4 13102 */
51219358 13103static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13104{
27c868c2 13105 AdvPortAddr iop_base;
51219358
MW
13106 ushort warn_code;
13107 ADVEEP_38C1600_CONFIG eep_config;
13108 uchar tid, termination;
13109 ushort sdtr_speed = 0;
1da177e4 13110
27c868c2
MW
13111 iop_base = asc_dvc->iop_base;
13112
51219358 13113 warn_code = 0;
27c868c2 13114
51219358
MW
13115 /*
13116 * Read the board's EEPROM configuration.
13117 *
13118 * Set default values if a bad checksum is found.
13119 */
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;
13124
13125 /*
13126 * Set EEPROM default values.
13127 */
13128 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13129 sizeof(ADVEEP_38C1600_CONFIG));
13130
13131 if (PCI_FUNC(pdev->devfn) != 0) {
13132 u8 ints;
13133 /*
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
13137 */
13138 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13139 /*
13140 * Clear the INTAB (bit 11) if the GPIO 0 input
13141 * indicates the Function 1 interrupt line is wired
13142 * to INTB.
13143 *
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.
13147 *
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.
13151 */
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;
13156 }
13157
13158 /*
13159 * Assume the 6 byte board serial number that was read from
13160 * EEPROM is correct even if the EEPROM checksum failed.
13161 */
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);
13168
13169 AdvSet38C1600EEPConfig(iop_base, &eep_config);
27c868c2
MW
13170 }
13171
13172 /*
51219358
MW
13173 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13174 * EEPROM configuration that was read.
13175 *
13176 * This is the mapping of EEPROM fields to Adv Library fields.
27c868c2 13177 */
51219358
MW
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;
27c868c2 13193
51219358
MW
13194 /*
13195 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13196 * are set, then set an 'sdtr_able' bit for it.
13197 */
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;
13208 }
13209 if (sdtr_speed & ASC_MAX_TID) {
13210 asc_dvc->sdtr_able |= (1 << tid);
13211 }
13212 sdtr_speed >>= 4;
13213 }
27c868c2 13214
51219358
MW
13215 /*
13216 * Set the host maximum queuing (max. 253, min. 16) and the per device
13217 * maximum queuing (max. 63, min. 4).
13218 */
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;
27c868c2 13227 }
51219358 13228 }
27c868c2 13229
51219358
MW
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;
13238 }
13239 }
13240
13241 /*
13242 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13243 * set 'max_dvc_qng' to 'max_host_qng'.
13244 */
13245 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13246 eep_config.max_dvc_qng = eep_config.max_host_qng;
27c868c2
MW
13247 }
13248
13249 /*
51219358
MW
13250 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13251 * values based on possibly adjusted EEPROM values.
13252 */
13253 asc_dvc->max_host_qng = eep_config.max_host_qng;
13254 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13255
13256 /*
13257 * If the EEPROM 'termination' field is set to automatic (0), then set
13258 * the ASC_DVC_CFG 'termination' field to automatic also.
13259 *
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.
27c868c2 13263 */
51219358
MW
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;
27c868c2 13270
51219358
MW
13271 /* Enable manual control with low off / high on. */
13272 } else if (eep_config.termination_se == 2) {
13273 termination = TERM_SE_HI;
27c868c2 13274
51219358
MW
13275 /* Enable manual control with low on / high on. */
13276 } else if (eep_config.termination_se == 3) {
13277 termination = TERM_SE;
13278 } else {
13279 /*
13280 * The EEPROM 'termination_se' field contains a bad value.
13281 * Use automatic termination instead.
13282 */
13283 termination = 0;
13284 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13285 }
13286 }
27c868c2 13287
51219358
MW
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;
27c868c2 13294
51219358
MW
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;
27c868c2 13298
51219358
MW
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 {
13303 /*
13304 * The EEPROM 'termination_lvd' field contains a bad value.
13305 * Use automatic termination instead.
13306 */
13307 asc_dvc->cfg->termination = termination;
13308 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13309 }
27c868c2 13310 }
51219358
MW
13311
13312 return warn_code;
1da177e4
LT
13313}
13314
13315/*
51219358 13316 * Initialize the ADV_DVC_VAR structure.
1da177e4 13317 *
51219358 13318 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4 13319 *
51219358
MW
13320 * For a non-fatal error return a warning code. If there are no warnings
13321 * then 0 is returned.
1da177e4 13322 */
51219358 13323static int __devinit
9d0e96eb 13324AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
1da177e4 13325{
9d0e96eb
MW
13326 struct asc_board *board = shost_priv(shost);
13327 ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
51219358
MW
13328 unsigned short warn_code = 0;
13329 AdvPortAddr iop_base = asc_dvc->iop_base;
13330 u16 cmd;
13331 int status;
27c868c2 13332
51219358 13333 asc_dvc->err_code = 0;
27c868c2
MW
13334
13335 /*
51219358
MW
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.
27c868c2 13340 */
51219358
MW
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;
27c868c2 13345
51219358
MW
13346 asc_dvc->cfg->chip_version =
13347 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13348
b352f923 13349 ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
51219358
MW
13350 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13351 (ushort)ADV_CHIP_ID_BYTE);
13352
b352f923 13353 ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
51219358
MW
13354 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13355 (ushort)ADV_CHIP_ID_WORD);
27c868c2
MW
13356
13357 /*
51219358 13358 * Reset the chip to start and allow register writes.
27c868c2 13359 */
51219358
MW
13360 if (AdvFindSignature(iop_base) == 0) {
13361 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13362 return ADV_ERROR;
13363 } else {
27c868c2 13364 /*
51219358 13365 * The caller must set 'chip_type' to a valid setting.
27c868c2 13366 */
51219358
MW
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;
13372 }
1da177e4 13373
51219358
MW
13374 /*
13375 * Reset Chip.
13376 */
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);
13382
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);
27c868c2 13389 }
51219358 13390 warn_code |= status;
27c868c2 13391 }
1da177e4 13392
9d0e96eb
MW
13393 if (warn_code != 0)
13394 shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code);
51219358 13395
9d0e96eb
MW
13396 if (asc_dvc->err_code)
13397 shost_printk(KERN_ERR, shost, "error code 0x%x\n",
13398 asc_dvc->err_code);
51219358
MW
13399
13400 return asc_dvc->err_code;
1da177e4 13401}
51219358
MW
13402#endif
13403
13404static 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,
13415 /*
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.
13419 */
13420 .unchecked_isa_dma = 1,
13421 /*
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.
13427 */
13428 .use_clustering = ENABLE_CLUSTERING,
13429};
1da177e4 13430
9d0e96eb 13431static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
b2c16f58 13432{
9d0e96eb
MW
13433 struct asc_board *board = shost_priv(shost);
13434 struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
b2c16f58
MW
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;
13440
13441 /*
13442 * Allocate buffer carrier structures. The total size
13443 * is about 4 KB, so allocate all at once.
13444 */
9d0e96eb
MW
13445 board->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13446 ASC_DBG(1, "carrp 0x%p\n", board->carrp);
b2c16f58 13447
9d0e96eb 13448 if (!board->carrp)
b2c16f58
MW
13449 goto kmalloc_failed;
13450
13451 /*
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.
13455 */
9d0e96eb 13456 for (req_cnt = adv_dvc->max_host_qng; req_cnt > 0; req_cnt--) {
b2c16f58
MW
13457 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13458
b352f923 13459 ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt,
b2c16f58
MW
13460 (ulong)sizeof(adv_req_t) * req_cnt);
13461
13462 if (reqp)
13463 break;
13464 }
13465
13466 if (!reqp)
13467 goto kmalloc_failed;
13468
9d0e96eb 13469 board->orig_reqp = reqp;
b2c16f58
MW
13470
13471 /*
13472 * Allocate up to ADV_TOT_SG_BLOCK request structures for
13473 * the Wide board. Each structure is about 136 bytes.
13474 */
9d0e96eb 13475 board->adv_sgblkp = NULL;
b2c16f58
MW
13476 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13477 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13478
13479 if (!sgp)
13480 break;
13481
9d0e96eb
MW
13482 sgp->next_sgblkp = board->adv_sgblkp;
13483 board->adv_sgblkp = sgp;
b2c16f58
MW
13484
13485 }
13486
b352f923 13487 ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t),
b2c16f58
MW
13488 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
13489
9d0e96eb 13490 if (!board->adv_sgblkp)
b2c16f58
MW
13491 goto kmalloc_failed;
13492
9d0e96eb 13493 adv_dvc->carrier_buf = board->carrp;
b2c16f58
MW
13494
13495 /*
13496 * Point 'adv_reqp' to the request structures and
13497 * link them together.
13498 */
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];
13503 }
9d0e96eb 13504 board->adv_reqp = &reqp[0];
b2c16f58 13505
9d0e96eb 13506 if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
b352f923 13507 ASC_DBG(2, "AdvInitAsc3550Driver()\n");
9d0e96eb
MW
13508 warn_code = AdvInitAsc3550Driver(adv_dvc);
13509 } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) {
b352f923 13510 ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
9d0e96eb 13511 warn_code = AdvInitAsc38C0800Driver(adv_dvc);
b2c16f58 13512 } else {
b352f923 13513 ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
9d0e96eb 13514 warn_code = AdvInitAsc38C1600Driver(adv_dvc);
b2c16f58 13515 }
9d0e96eb 13516 err_code = adv_dvc->err_code;
b2c16f58
MW
13517
13518 if (warn_code || err_code) {
9d0e96eb
MW
13519 shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error "
13520 "0x%x\n", warn_code, err_code);
b2c16f58
MW
13521 }
13522
13523 goto exit;
13524
13525 kmalloc_failed:
9d0e96eb 13526 shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n");
b2c16f58
MW
13527 err_code = ADV_ERROR;
13528 exit:
13529 return err_code;
13530}
13531
d2411495 13532static void advansys_wide_free_mem(struct asc_board *boardp)
b2c16f58
MW
13533{
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);
13542 }
13543}
13544
d361db48
MW
13545static int __devinit advansys_board_found(struct Scsi_Host *shost,
13546 unsigned int iop, int bus_type)
27c868c2 13547{
d361db48 13548 struct pci_dev *pdev;
d2411495 13549 struct asc_board *boardp = shost_priv(shost);
27c868c2
MW
13550 ASC_DVC_VAR *asc_dvc_varp = NULL;
13551 ADV_DVC_VAR *adv_dvc_varp = NULL;
d361db48 13552 int share_irq, warn_code, ret;
27c868c2 13553
d361db48 13554 pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
27c868c2
MW
13555
13556 if (ASC_NARROW_BOARD(boardp)) {
b352f923 13557 ASC_DBG(1, "narrow board\n");
27c868c2
MW
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;
27c868c2 13564 } else {
57ba5fe9 13565#ifdef CONFIG_PCI
27c868c2
MW
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;
27c868c2 13569 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
b352f923 13570 ASC_DBG(1, "wide board ASC-3550\n");
27c868c2
MW
13571 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13572 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
b352f923 13573 ASC_DBG(1, "wide board ASC-38C0800\n");
27c868c2
MW
13574 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13575 } else {
b352f923 13576 ASC_DBG(1, "wide board ASC-38C1600\n");
27c868c2
MW
13577 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13578 }
27c868c2 13579
57ba5fe9
MW
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) {
9d0e96eb
MW
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);
d361db48 13588 ret = -ENODEV;
b2c16f58 13589 goto err_shost;
27c868c2 13590 }
b352f923
MW
13591 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
13592 ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
27c868c2
MW
13593
13594 /*
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.
13598 */
13599 boardp->ioport = iop;
13600
b352f923
MW
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));
57ba5fe9 13603#endif /* CONFIG_PCI */
27c868c2
MW
13604 }
13605
13606#ifdef CONFIG_PROC_FS
13607 /*
13608 * Allocate buffer for printing information from
13609 * /proc/scsi/advansys/[0...].
13610 */
b2c16f58
MW
13611 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13612 if (!boardp->prtbuf) {
9d0e96eb
MW
13613 shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n",
13614 ASC_PRTBUF_SIZE);
d361db48 13615 ret = -ENOMEM;
b2c16f58 13616 goto err_unmap;
27c868c2
MW
13617 }
13618#endif /* CONFIG_PROC_FS */
13619
13620 if (ASC_NARROW_BOARD(boardp)) {
27c868c2
MW
13621 /*
13622 * Set the board bus type and PCI IRQ before
13623 * calling AscInitGetConfig().
13624 */
13625 switch (asc_dvc_varp->bus_type) {
13626#ifdef CONFIG_ISA
13627 case ASC_IS_ISA:
13628 shost->unchecked_isa_dma = TRUE;
074c8fe4 13629 share_irq = 0;
27c868c2
MW
13630 break;
13631 case ASC_IS_VL:
13632 shost->unchecked_isa_dma = FALSE;
074c8fe4 13633 share_irq = 0;
27c868c2
MW
13634 break;
13635 case ASC_IS_EISA:
13636 shost->unchecked_isa_dma = FALSE;
074c8fe4 13637 share_irq = IRQF_SHARED;
27c868c2
MW
13638 break;
13639#endif /* CONFIG_ISA */
13640#ifdef CONFIG_PCI
13641 case ASC_IS_PCI:
27c868c2 13642 shost->unchecked_isa_dma = FALSE;
074c8fe4 13643 share_irq = IRQF_SHARED;
27c868c2
MW
13644 break;
13645#endif /* CONFIG_PCI */
13646 default:
9d0e96eb
MW
13647 shost_printk(KERN_ERR, shost, "unknown adapter type: "
13648 "%d\n", asc_dvc_varp->bus_type);
27c868c2 13649 shost->unchecked_isa_dma = TRUE;
074c8fe4 13650 share_irq = 0;
27c868c2
MW
13651 break;
13652 }
27c868c2 13653
27c868c2
MW
13654 /*
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 "&".
13659 */
b352f923 13660 ASC_DBG(2, "AscInitGetConfig()\n");
9d0e96eb 13661 ret = AscInitGetConfig(shost) ? -ENODEV : 0;
27c868c2 13662 } else {
c2dce2fa
MW
13663#ifdef CONFIG_PCI
13664 /*
13665 * For Wide boards set PCI information before calling
13666 * AdvInitGetConfig().
13667 */
c2dce2fa
MW
13668 shost->unchecked_isa_dma = FALSE;
13669 share_irq = IRQF_SHARED;
b352f923 13670 ASC_DBG(2, "AdvInitGetConfig()\n");
394dbf3f 13671
9d0e96eb 13672 ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0;
c2dce2fa 13673#endif /* CONFIG_PCI */
27c868c2
MW
13674 }
13675
d361db48 13676 if (ret)
b2c16f58 13677 goto err_free_proc;
27c868c2
MW
13678
13679 /*
13680 * Save the EEPROM configuration so that it can be displayed
13681 * from /proc/scsi/advansys/[0...].
13682 */
13683 if (ASC_NARROW_BOARD(boardp)) {
13684
13685 ASCEEP_CONFIG *ep;
13686
13687 /*
13688 * Set the adapter's target id bit in the 'init_tidmask' field.
13689 */
13690 boardp->init_tidmask |=
13691 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
13692
13693 /*
13694 * Save EEPROM settings for the board.
13695 */
13696 ep = &boardp->eep_config.asc_eep;
13697
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];
13715
13716 /*
13717 * Modify board configuration.
13718 */
b352f923 13719 ASC_DBG(2, "AscInitSetConfig()\n");
9d0e96eb 13720 ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
d361db48 13721 if (ret)
b2c16f58 13722 goto err_free_proc;
27c868c2
MW
13723 } else {
13724 ADVEEP_3550_CONFIG *ep_3550;
13725 ADVEEP_38C0800_CONFIG *ep_38C0800;
13726 ADVEEP_38C1600_CONFIG *ep_38C1600;
13727
13728 /*
13729 * Save Wide EEP Configuration Information.
13730 */
13731 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13732 ep_3550 = &boardp->eep_config.adv_3550_eep;
13733
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;
13755
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;
13783
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;
13809 }
13810
13811 /*
13812 * Set the adapter's target id bit in the 'init_tidmask' field.
13813 */
13814 boardp->init_tidmask |=
13815 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
27c868c2
MW
13816 }
13817
13818 /*
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.
13822 */
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;
f05ec594 13827 shost->max_cmd_len = ASC_MAX_CDB_LEN;
27c868c2
MW
13828
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;
13832
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;
f05ec594 13838 shost->max_cmd_len = ADV_MAX_CDB_LEN;
27c868c2
MW
13839
13840 /*
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.
13845 */
13846 shost->io_port = iop;
27c868c2
MW
13847
13848 shost->this_id = adv_dvc_varp->chip_scsi_id;
13849
13850 /* Set maximum number of queues the adapter can handle. */
13851 shost->can_queue = adv_dvc_varp->max_host_qng;
13852 }
13853
27c868c2
MW
13854 /*
13855 * Following v1.3.89, 'cmd_per_lun' is no longer needed
13856 * and should be set to zero.
13857 *
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.
13862 *
13863 * Note: This is wrong. cmd_per_lun should be set to the depth
13864 * you want on untagged devices always.
13865 #ifdef MODULE
13866 */
13867 shost->cmd_per_lun = 1;
13868/* #else
13869 shost->cmd_per_lun = 0;
13870#endif */
13871
13872 /*
13873 * Set the maximum number of scatter-gather elements the
13874 * adapter can handle.
13875 */
13876 if (ASC_NARROW_BOARD(boardp)) {
13877 /*
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.
13882 */
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;
13888 }
13889
13890 /*
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'.
13895 */
13896 if (shost->sg_tablesize > SG_ALL) {
13897 shost->sg_tablesize = SG_ALL;
13898 }
13899
b352f923 13900 ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
27c868c2
MW
13901
13902 /* BIOS start address. */
13903 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
13904 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
13905 asc_dvc_varp->bus_type);
27c868c2
MW
13906 } else {
13907 /*
13908 * Fill-in BIOS board variables. The Wide BIOS saves
13909 * information in LRAM that is used by the driver.
13910 */
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);
13919
b352f923 13920 ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
27c868c2
MW
13921 boardp->bios_signature, boardp->bios_version);
13922
b352f923 13923 ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
27c868c2
MW
13924 boardp->bios_codeseg, boardp->bios_codelen);
13925
13926 /*
13927 * If the BIOS saved a valid signature, then fill in
13928 * the BIOS code segment base address.
13929 */
13930 if (boardp->bios_signature == 0x55AA) {
13931 /*
13932 * Convert x86 realmode code segment to a linear
13933 * address by shifting left 4.
13934 */
13935 shost->base = ((ulong)boardp->bios_codeseg << 4);
13936 } else {
13937 shost->base = 0;
13938 }
13939 }
13940
13941 /*
13942 * Register Board Resources - I/O Port, DMA, IRQ
13943 */
13944
27c868c2
MW
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;
01fbfe0b 13952 ret = request_dma(shost->dma_channel, DRV_NAME);
b2c16f58 13953 if (ret) {
9d0e96eb
MW
13954 shost_printk(KERN_ERR, shost, "request_dma() "
13955 "%d failed %d\n",
13956 shost->dma_channel, ret);
71f36115 13957 goto err_free_proc;
27c868c2
MW
13958 }
13959 AscEnableIsaDma(shost->dma_channel);
13960 }
13961 }
13962#endif /* CONFIG_ISA */
13963
13964 /* Register IRQ Number. */
b352f923 13965 ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
074c8fe4 13966
d361db48 13967 ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
01fbfe0b 13968 DRV_NAME, shost);
074c8fe4
MW
13969
13970 if (ret) {
27c868c2 13971 if (ret == -EBUSY) {
9d0e96eb
MW
13972 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13973 "already in use\n", boardp->irq);
27c868c2 13974 } else if (ret == -EINVAL) {
9d0e96eb
MW
13975 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13976 "not valid\n", boardp->irq);
27c868c2 13977 } else {
9d0e96eb
MW
13978 shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13979 "failed with %d\n", boardp->irq, ret);
27c868c2 13980 }
b2c16f58 13981 goto err_free_dma;
27c868c2
MW
13982 }
13983
13984 /*
13985 * Initialize board RISC chip and enable interrupts.
13986 */
13987 if (ASC_NARROW_BOARD(boardp)) {
b352f923 13988 ASC_DBG(2, "AscInitAsc1000Driver()\n");
27c868c2 13989 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
27c868c2 13990
d361db48 13991 if (warn_code || asc_dvc_varp->err_code) {
9d0e96eb
MW
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);
d361db48
MW
13996 if (asc_dvc_varp->err_code)
13997 ret = -ENODEV;
27c868c2
MW
13998 }
13999 } else {
9d0e96eb 14000 if (advansys_wide_init_chip(shost))
d361db48 14001 ret = -ENODEV;
27c868c2
MW
14002 }
14003
d361db48 14004 if (ret)
b2c16f58
MW
14005 goto err_free_wide_mem;
14006
27c868c2
MW
14007 ASC_DBG_PRT_SCSI_HOST(2, shost);
14008
d361db48 14009 ret = scsi_add_host(shost, boardp->dev);
8dfb5379
MW
14010 if (ret)
14011 goto err_free_wide_mem;
14012
14013 scsi_scan_host(shost);
d361db48 14014 return 0;
b2c16f58
MW
14015
14016 err_free_wide_mem:
14017 advansys_wide_free_mem(boardp);
d361db48 14018 free_irq(boardp->irq, shost);
b2c16f58
MW
14019 err_free_dma:
14020 if (shost->dma_channel != NO_ISA_DMA)
14021 free_dma(shost->dma_channel);
b2c16f58
MW
14022 err_free_proc:
14023 kfree(boardp->prtbuf);
14024 err_unmap:
14025 if (boardp->ioremap_addr)
14026 iounmap(boardp->ioremap_addr);
14027 err_shost:
d361db48 14028 return ret;
27c868c2
MW
14029}
14030
27c868c2
MW
14031/*
14032 * advansys_release()
14033 *
14034 * Release resources allocated for a single AdvanSys adapter.
14035 */
14036static int advansys_release(struct Scsi_Host *shost)
14037{
d2411495 14038 struct asc_board *boardp = shost_priv(shost);
b352f923 14039 ASC_DBG(1, "begin\n");
8dfb5379 14040 scsi_remove_host(shost);
d361db48 14041 free_irq(boardp->irq, shost);
27c868c2 14042 if (shost->dma_channel != NO_ISA_DMA) {
b352f923 14043 ASC_DBG(1, "free_dma()\n");
27c868c2
MW
14044 free_dma(shost->dma_channel);
14045 }
9a256fa5 14046 if (!ASC_NARROW_BOARD(boardp)) {
27c868c2 14047 iounmap(boardp->ioremap_addr);
b2c16f58 14048 advansys_wide_free_mem(boardp);
27c868c2 14049 }
27c868c2 14050 kfree(boardp->prtbuf);
8dfb5379 14051 scsi_host_put(shost);
b352f923 14052 ASC_DBG(1, "end\n");
27c868c2
MW
14053 return 0;
14054}
14055
95c9f162
MW
14056#define ASC_IOADR_TABLE_MAX_IX 11
14057
c304ec94
MW
14058static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14059 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14060 0x0210, 0x0230, 0x0250, 0x0330
14061};
14062
d361db48
MW
14063/*
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
14069 */
14070static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
14071{
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;
14077}
14078
c304ec94
MW
14079static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14080{
d361db48 14081 int err = -ENODEV;
c304ec94
MW
14082 PortAddr iop_base = _asc_def_iop_base[id];
14083 struct Scsi_Host *shost;
d361db48 14084 struct asc_board *board;
c304ec94 14085
01fbfe0b 14086 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
b352f923 14087 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
c304ec94
MW
14088 return -ENODEV;
14089 }
b352f923 14090 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
c304ec94 14091 if (!AscFindSignature(iop_base))
d361db48 14092 goto release_region;
c304ec94 14093 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
d361db48 14094 goto release_region;
c304ec94 14095
d361db48
MW
14096 err = -ENOMEM;
14097 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
c304ec94 14098 if (!shost)
d361db48
MW
14099 goto release_region;
14100
d2411495 14101 board = shost_priv(shost);
d361db48
MW
14102 board->irq = advansys_isa_irq_no(iop_base);
14103 board->dev = dev;
14104
14105 err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
14106 if (err)
14107 goto free_host;
c304ec94
MW
14108
14109 dev_set_drvdata(dev, shost);
14110 return 0;
14111
d361db48
MW
14112 free_host:
14113 scsi_host_put(shost);
14114 release_region:
71f36115 14115 release_region(iop_base, ASC_IOADR_GAP);
d361db48 14116 return err;
c304ec94
MW
14117}
14118
14119static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14120{
71f36115 14121 int ioport = _asc_def_iop_base[id];
c304ec94 14122 advansys_release(dev_get_drvdata(dev));
71f36115 14123 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
14124 return 0;
14125}
14126
14127static struct isa_driver advansys_isa_driver = {
14128 .probe = advansys_isa_probe,
14129 .remove = __devexit_p(advansys_isa_remove),
14130 .driver = {
14131 .owner = THIS_MODULE,
01fbfe0b 14132 .name = DRV_NAME,
c304ec94
MW
14133 },
14134};
14135
d361db48
MW
14136/*
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
14146 */
14147static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
14148{
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;
14154}
14155
c304ec94
MW
14156static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14157{
d361db48 14158 int err = -ENODEV;
c304ec94
MW
14159 PortAddr iop_base = _asc_def_iop_base[id];
14160 struct Scsi_Host *shost;
d361db48 14161 struct asc_board *board;
c304ec94 14162
01fbfe0b 14163 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
b352f923 14164 ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
c304ec94
MW
14165 return -ENODEV;
14166 }
b352f923 14167 ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
c304ec94 14168 if (!AscFindSignature(iop_base))
d361db48 14169 goto release_region;
c304ec94
MW
14170 /*
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.
14174 */
14175 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
d361db48 14176 goto release_region;
c304ec94 14177
d361db48
MW
14178 err = -ENOMEM;
14179 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
c304ec94 14180 if (!shost)
d361db48
MW
14181 goto release_region;
14182
d2411495 14183 board = shost_priv(shost);
d361db48
MW
14184 board->irq = advansys_vlb_irq_no(iop_base);
14185 board->dev = dev;
14186
14187 err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14188 if (err)
14189 goto free_host;
c304ec94
MW
14190
14191 dev_set_drvdata(dev, shost);
14192 return 0;
14193
d361db48
MW
14194 free_host:
14195 scsi_host_put(shost);
14196 release_region:
71f36115 14197 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
14198 return -ENODEV;
14199}
14200
14201static struct isa_driver advansys_vlb_driver = {
14202 .probe = advansys_vlb_probe,
14203 .remove = __devexit_p(advansys_isa_remove),
14204 .driver = {
14205 .owner = THIS_MODULE,
b8e5152b 14206 .name = "advansys_vlb",
c304ec94
MW
14207 },
14208};
14209
b09e05a7
MW
14210static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14211 { "ABP7401" },
14212 { "ABP7501" },
14213 { "" }
14214};
14215
14216MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14217
14218/*
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
14221 */
14222struct eisa_scsi_data {
14223 struct Scsi_Host *host[2];
14224};
14225
d361db48
MW
14226/*
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
14236 */
14237static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14238{
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;
14244}
14245
b09e05a7
MW
14246static int __devinit advansys_eisa_probe(struct device *dev)
14247{
d361db48 14248 int i, ioport, irq = 0;
b09e05a7
MW
14249 int err;
14250 struct eisa_device *edev = to_eisa_device(dev);
14251 struct eisa_scsi_data *data;
14252
14253 err = -ENOMEM;
14254 data = kzalloc(sizeof(*data), GFP_KERNEL);
14255 if (!data)
14256 goto fail;
14257 ioport = edev->base_addr + 0xc30;
14258
14259 err = -ENODEV;
14260 for (i = 0; i < 2; i++, ioport += 0x20) {
d361db48
MW
14261 struct asc_board *board;
14262 struct Scsi_Host *shost;
01fbfe0b 14263 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
71f36115
MW
14264 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14265 ioport + ASC_IOADR_GAP - 1);
14266 continue;
14267 }
14268 if (!AscFindSignature(ioport)) {
14269 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 14270 continue;
71f36115
MW
14271 }
14272
b09e05a7
MW
14273 /*
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.
14279 */
14280 inw(ioport + 4);
d361db48
MW
14281
14282 if (!irq)
14283 irq = advansys_eisa_irq_no(edev);
14284
14285 err = -ENOMEM;
14286 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14287 if (!shost)
14288 goto release_region;
14289
d2411495 14290 board = shost_priv(shost);
d361db48
MW
14291 board->irq = irq;
14292 board->dev = dev;
14293
14294 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14295 if (!err) {
14296 data->host[i] = shost;
14297 continue;
71f36115 14298 }
b09e05a7 14299
d361db48
MW
14300 scsi_host_put(shost);
14301 release_region:
14302 release_region(ioport, ASC_IOADR_GAP);
14303 break;
b09e05a7
MW
14304 }
14305
d361db48
MW
14306 if (err)
14307 goto free_data;
14308 dev_set_drvdata(dev, data);
14309 return 0;
14310
14311 free_data:
14312 kfree(data->host[0]);
14313 kfree(data->host[1]);
14314 kfree(data);
b09e05a7
MW
14315 fail:
14316 return err;
14317}
14318
14319static __devexit int advansys_eisa_remove(struct device *dev)
14320{
14321 int i;
14322 struct eisa_scsi_data *data = dev_get_drvdata(dev);
14323
14324 for (i = 0; i < 2; i++) {
71f36115 14325 int ioport;
b09e05a7
MW
14326 struct Scsi_Host *shost = data->host[i];
14327 if (!shost)
14328 continue;
71f36115 14329 ioport = shost->io_port;
b09e05a7 14330 advansys_release(shost);
71f36115 14331 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
14332 }
14333
14334 kfree(data);
14335 return 0;
14336}
14337
14338static struct eisa_driver advansys_eisa_driver = {
14339 .id_table = advansys_eisa_table,
14340 .driver = {
01fbfe0b 14341 .name = DRV_NAME,
b09e05a7
MW
14342 .probe = advansys_eisa_probe,
14343 .remove = __devexit_p(advansys_eisa_remove),
14344 }
14345};
14346
2672ea86
DJ
14347/* PCI Devices supported by this driver */
14348static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
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},
14361 {}
2672ea86 14362};
27c868c2 14363
2672ea86 14364MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b 14365
9649af39
MW
14366static void __devinit advansys_set_latency(struct pci_dev *pdev)
14367{
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);
14376 }
14377}
14378
78e77d8b
MW
14379static int __devinit
14380advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14381{
14382 int err, ioport;
14383 struct Scsi_Host *shost;
d361db48 14384 struct asc_board *board;
78e77d8b
MW
14385
14386 err = pci_enable_device(pdev);
14387 if (err)
14388 goto fail;
01fbfe0b 14389 err = pci_request_regions(pdev, DRV_NAME);
71f36115
MW
14390 if (err)
14391 goto disable_device;
9649af39
MW
14392 pci_set_master(pdev);
14393 advansys_set_latency(pdev);
78e77d8b 14394
d361db48 14395 err = -ENODEV;
78e77d8b 14396 if (pci_resource_len(pdev, 0) == 0)
d361db48 14397 goto release_region;
78e77d8b
MW
14398
14399 ioport = pci_resource_start(pdev, 0);
78e77d8b 14400
d361db48
MW
14401 err = -ENOMEM;
14402 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
78e77d8b 14403 if (!shost)
d361db48
MW
14404 goto release_region;
14405
d2411495 14406 board = shost_priv(shost);
d361db48
MW
14407 board->irq = pdev->irq;
14408 board->dev = &pdev->dev;
14409
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;
14414 }
14415
14416 err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14417 if (err)
14418 goto free_host;
78e77d8b
MW
14419
14420 pci_set_drvdata(pdev, shost);
14421 return 0;
14422
d361db48
MW
14423 free_host:
14424 scsi_host_put(shost);
14425 release_region:
71f36115
MW
14426 pci_release_regions(pdev);
14427 disable_device:
78e77d8b
MW
14428 pci_disable_device(pdev);
14429 fail:
14430 return err;
14431}
14432
14433static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14434{
14435 advansys_release(pci_get_drvdata(pdev));
71f36115 14436 pci_release_regions(pdev);
78e77d8b
MW
14437 pci_disable_device(pdev);
14438}
14439
14440static struct pci_driver advansys_pci_driver = {
01fbfe0b 14441 .name = DRV_NAME,
78e77d8b
MW
14442 .id_table = advansys_pci_tbl,
14443 .probe = advansys_pci_probe,
14444 .remove = __devexit_p(advansys_pci_remove),
14445};
8c6af9e1 14446
8dfb5379
MW
14447static int __init advansys_init(void)
14448{
c304ec94 14449 int error;
b09e05a7 14450
c304ec94
MW
14451 error = isa_register_driver(&advansys_isa_driver,
14452 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
14453 if (error)
14454 goto fail;
8dfb5379 14455
c304ec94
MW
14456 error = isa_register_driver(&advansys_vlb_driver,
14457 ASC_IOADR_TABLE_MAX_IX);
14458 if (error)
14459 goto unregister_isa;
14460
14461 error = eisa_driver_register(&advansys_eisa_driver);
14462 if (error)
14463 goto unregister_vlb;
14464
b09e05a7
MW
14465 error = pci_register_driver(&advansys_pci_driver);
14466 if (error)
14467 goto unregister_eisa;
14468
8dfb5379 14469 return 0;
78e77d8b 14470
b09e05a7
MW
14471 unregister_eisa:
14472 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
14473 unregister_vlb:
14474 isa_unregister_driver(&advansys_vlb_driver);
14475 unregister_isa:
14476 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 14477 fail:
78e77d8b 14478 return error;
8dfb5379
MW
14479}
14480
14481static void __exit advansys_exit(void)
14482{
78e77d8b 14483 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 14484 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
14485 isa_unregister_driver(&advansys_vlb_driver);
14486 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
14487}
14488
14489module_init(advansys_init);
14490module_exit(advansys_exit);
14491
8c6af9e1 14492MODULE_LICENSE("GPL");