]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/scsi/advansys.c
[SCSI] advansys: Remove some custom wrappers
[mirror_ubuntu-focal-kernel.git] / drivers / scsi / advansys.c
CommitLineData
8c6af9e1 1#define ASC_VERSION "3.4" /* AdvanSys Driver Version */
1da177e4
LT
2
3/*
4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5 *
6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
7 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8c6af9e1 8 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
1da177e4
LT
9 * All Rights Reserved.
10 *
8c6af9e1
MW
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17/*
1da177e4
LT
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
8c6af9e1 20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
1da177e4
LT
21 */
22
1da177e4 23#include <linux/module.h>
1da177e4
LT
24#include <linux/string.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/ioport.h>
28#include <linux/interrupt.h>
29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <linux/mm.h>
32#include <linux/proc_fs.h>
33#include <linux/init.h>
34#include <linux/blkdev.h>
c304ec94 35#include <linux/isa.h>
b09e05a7 36#include <linux/eisa.h>
8c6af9e1 37#include <linux/pci.h>
1da177e4
LT
38#include <linux/spinlock.h>
39#include <linux/dma-mapping.h>
40
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/dma.h>
44
8c6af9e1
MW
45#include <scsi/scsi_cmnd.h>
46#include <scsi/scsi_device.h>
47#include <scsi/scsi_tcq.h>
48#include <scsi/scsi.h>
49#include <scsi/scsi_host.h>
50
4bd6d7f3 51/* FIXME:
1da177e4 52 *
4bd6d7f3
MW
53 * 1. Although all of the necessary command mapping places have the
54 * appropriate dma_map.. APIs, the driver still processes its internal
55 * queue using bus_to_virt() and virt_to_bus() which are illegal under
56 * the API. The entire queue processing structure will need to be
57 * altered to fix this.
58 * 2. Need to add memory mapping workaround. Test the memory mapping.
59 * If it doesn't work revert to I/O port access. Can a test be done
60 * safely?
61 * 3. Handle an interrupt not working. Keep an interrupt counter in
62 * the interrupt handler. In the timeout function if the interrupt
63 * has not occurred then print a message and run in polled mode.
64 * 4. Need to add support for target mode commands, cf. CAM XPT.
65 * 5. check DMA mapping functions for failure
349d2c44
MW
66 * 6. Use scsi_transport_spi
67 * 7. advansys_info is not safe against multiple simultaneous callers
68 * 8. Kill boardp->id
69 * 9. 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. */
77/* #define ADVANSYS_DEBUG */
78
1da177e4
LT
79/*
80 * --- Asc Library Constants and Macros
81 */
82
83#define ASC_LIB_VERSION_MAJOR 1
84#define ASC_LIB_VERSION_MINOR 24
85#define ASC_LIB_SERIAL_NUMBER 123
86
87/*
88 * Portable Data Types
89 *
90 * Any instance where a 32-bit long or pointer type is assumed
91 * for precision or HW defined structures, the following define
92 * types must be used. In Linux the char, short, and int types
93 * are all consistent at 8, 16, and 32 bits respectively. Pointers
94 * and long types are 64 bits on Alpha and UltraSPARC.
95 */
27c868c2
MW
96#define ASC_PADDR __u32 /* Physical/Bus address data type. */
97#define ASC_VADDR __u32 /* Virtual address data type. */
98#define ASC_DCNT __u32 /* Unsigned Data count type. */
99#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
100
101/*
102 * These macros are used to convert a virtual address to a
103 * 32-bit value. This currently can be used on Linux Alpha
104 * which uses 64-bit virtual address but a 32-bit bus address.
105 * This is likely to break in the future, but doing this now
106 * will give us time to change the HW and FW to handle 64-bit
107 * addresses.
108 */
109#define ASC_VADDR_TO_U32 virt_to_bus
110#define ASC_U32_TO_VADDR bus_to_virt
111
112typedef unsigned char uchar;
113
114#ifndef TRUE
115#define TRUE (1)
116#endif
117#ifndef FALSE
118#define FALSE (0)
119#endif
120
121#define EOF (-1)
122#define ERR (-1)
123#define UW_ERR (uint)(0xFFFF)
124#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
1da177e4
LT
125
126#define ASC_DVCLIB_CALL_DONE (1)
127#define ASC_DVCLIB_CALL_FAILED (0)
128#define ASC_DVCLIB_CALL_ERROR (-1)
129
2672ea86
DJ
130#define PCI_VENDOR_ID_ASP 0x10cd
131#define PCI_DEVICE_ID_ASP_1200A 0x1100
132#define PCI_DEVICE_ID_ASP_ABP940 0x1200
133#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
134#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
135#define PCI_DEVICE_ID_38C0800_REV1 0x2500
136#define PCI_DEVICE_ID_38C1600_REV1 0x2700
137
1da177e4
LT
138/*
139 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
140 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
141 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
142 * SRB structure.
143 */
144#define CC_VERY_LONG_SG_LIST 0
145#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
146
27c868c2 147#define PortAddr unsigned short /* port address size */
1da177e4
LT
148#define inp(port) inb(port)
149#define outp(port, byte) outb((byte), (port))
150
151#define inpw(port) inw(port)
152#define outpw(port, word) outw((word), (port))
153
154#define ASC_MAX_SG_QUEUE 7
155#define ASC_MAX_SG_LIST 255
156
157#define ASC_CS_TYPE unsigned short
158
159#define ASC_IS_ISA (0x0001)
160#define ASC_IS_ISAPNP (0x0081)
161#define ASC_IS_EISA (0x0002)
162#define ASC_IS_PCI (0x0004)
163#define ASC_IS_PCI_ULTRA (0x0104)
164#define ASC_IS_PCMCIA (0x0008)
165#define ASC_IS_MCA (0x0020)
166#define ASC_IS_VL (0x0040)
167#define ASC_ISA_PNP_PORT_ADDR (0x279)
168#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
169#define ASC_IS_WIDESCSI_16 (0x0100)
170#define ASC_IS_WIDESCSI_32 (0x0200)
171#define ASC_IS_BIG_ENDIAN (0x8000)
172#define ASC_CHIP_MIN_VER_VL (0x01)
173#define ASC_CHIP_MAX_VER_VL (0x07)
174#define ASC_CHIP_MIN_VER_PCI (0x09)
175#define ASC_CHIP_MAX_VER_PCI (0x0F)
176#define ASC_CHIP_VER_PCI_BIT (0x08)
177#define ASC_CHIP_MIN_VER_ISA (0x11)
178#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
179#define ASC_CHIP_MAX_VER_ISA (0x27)
180#define ASC_CHIP_VER_ISA_BIT (0x30)
181#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
182#define ASC_CHIP_VER_ASYN_BUG (0x21)
183#define ASC_CHIP_VER_PCI 0x08
184#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
185#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
186#define ASC_CHIP_MIN_VER_EISA (0x41)
187#define ASC_CHIP_MAX_VER_EISA (0x47)
188#define ASC_CHIP_VER_EISA_BIT (0x40)
189#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
190#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
191#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
192#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
193#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
194#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
195#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
196#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
197#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
198#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
199#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
200
201#define ASC_SCSI_ID_BITS 3
202#define ASC_SCSI_TIX_TYPE uchar
203#define ASC_ALL_DEVICE_BIT_SET 0xFF
204#define ASC_SCSI_BIT_ID_TYPE uchar
205#define ASC_MAX_TID 7
206#define ASC_MAX_LUN 7
207#define ASC_SCSI_WIDTH_BIT_SET 0xFF
208#define ASC_MAX_SENSE_LEN 32
209#define ASC_MIN_SENSE_LEN 14
1da177e4
LT
210#define ASC_SCSI_RESET_HOLD_TIME_US 60
211
f05ec594
MW
212/*
213 * Narrow boards only support 12-byte commands, while wide boards
214 * extend to 16-byte commands.
215 */
216#define ASC_MAX_CDB_LEN 12
217#define ADV_MAX_CDB_LEN 16
218
1da177e4
LT
219/*
220 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
221 * and CmdDt (Command Support Data) field bit definitions.
222 */
223#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
224#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
225#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
226#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
227
228#define ASC_SCSIDIR_NOCHK 0x00
229#define ASC_SCSIDIR_T2H 0x08
230#define ASC_SCSIDIR_H2T 0x10
231#define ASC_SCSIDIR_NODATA 0x18
232#define SCSI_ASC_NOMEDIA 0x3A
233#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
234#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
235#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
236#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1da177e4 237#define MS_SDTR_LEN 0x03
1da177e4 238#define MS_WDTR_LEN 0x02
1da177e4
LT
239
240#define ASC_SG_LIST_PER_Q 7
241#define QS_FREE 0x00
242#define QS_READY 0x01
243#define QS_DISC1 0x02
244#define QS_DISC2 0x04
245#define QS_BUSY 0x08
246#define QS_ABORTED 0x40
247#define QS_DONE 0x80
248#define QC_NO_CALLBACK 0x01
249#define QC_SG_SWAP_QUEUE 0x02
250#define QC_SG_HEAD 0x04
251#define QC_DATA_IN 0x08
252#define QC_DATA_OUT 0x10
253#define QC_URGENT 0x20
254#define QC_MSG_OUT 0x40
255#define QC_REQ_SENSE 0x80
256#define QCSG_SG_XFER_LIST 0x02
257#define QCSG_SG_XFER_MORE 0x04
258#define QCSG_SG_XFER_END 0x08
259#define QD_IN_PROGRESS 0x00
260#define QD_NO_ERROR 0x01
261#define QD_ABORTED_BY_HOST 0x02
262#define QD_WITH_ERROR 0x04
263#define QD_INVALID_REQUEST 0x80
264#define QD_INVALID_HOST_NUM 0x81
265#define QD_INVALID_DEVICE 0x82
266#define QD_ERR_INTERNAL 0xFF
267#define QHSTA_NO_ERROR 0x00
268#define QHSTA_M_SEL_TIMEOUT 0x11
269#define QHSTA_M_DATA_OVER_RUN 0x12
270#define QHSTA_M_DATA_UNDER_RUN 0x12
271#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
272#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
273#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
274#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
275#define QHSTA_D_HOST_ABORT_FAILED 0x23
276#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
277#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
278#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
279#define QHSTA_M_WTM_TIMEOUT 0x41
280#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
281#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
282#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
283#define QHSTA_M_TARGET_STATUS_BUSY 0x45
284#define QHSTA_M_BAD_TAG_CODE 0x46
285#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
286#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
287#define QHSTA_D_LRAM_CMP_ERROR 0x81
288#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
289#define ASC_FLAG_SCSIQ_REQ 0x01
290#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
291#define ASC_FLAG_BIOS_ASYNC_IO 0x04
292#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
293#define ASC_FLAG_WIN16 0x10
294#define ASC_FLAG_WIN32 0x20
295#define ASC_FLAG_ISA_OVER_16MB 0x40
296#define ASC_FLAG_DOS_VM_CALLBACK 0x80
297#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
298#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
299#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
300#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
301#define ASC_SCSIQ_CPY_BEG 4
302#define ASC_SCSIQ_SGHD_CPY_BEG 2
303#define ASC_SCSIQ_B_FWD 0
304#define ASC_SCSIQ_B_BWD 1
305#define ASC_SCSIQ_B_STATUS 2
306#define ASC_SCSIQ_B_QNO 3
307#define ASC_SCSIQ_B_CNTL 4
308#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
309#define ASC_SCSIQ_D_DATA_ADDR 8
310#define ASC_SCSIQ_D_DATA_CNT 12
311#define ASC_SCSIQ_B_SENSE_LEN 20
312#define ASC_SCSIQ_DONE_INFO_BEG 22
313#define ASC_SCSIQ_D_SRBPTR 22
314#define ASC_SCSIQ_B_TARGET_IX 26
315#define ASC_SCSIQ_B_CDB_LEN 28
316#define ASC_SCSIQ_B_TAG_CODE 29
317#define ASC_SCSIQ_W_VM_ID 30
318#define ASC_SCSIQ_DONE_STATUS 32
319#define ASC_SCSIQ_HOST_STATUS 33
320#define ASC_SCSIQ_SCSI_STATUS 34
321#define ASC_SCSIQ_CDB_BEG 36
322#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
323#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
324#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
325#define ASC_SCSIQ_B_SG_WK_QP 49
326#define ASC_SCSIQ_B_SG_WK_IX 50
327#define ASC_SCSIQ_W_ALT_DC1 52
328#define ASC_SCSIQ_B_LIST_CNT 6
329#define ASC_SCSIQ_B_CUR_LIST_CNT 7
330#define ASC_SGQ_B_SG_CNTL 4
331#define ASC_SGQ_B_SG_HEAD_QP 5
332#define ASC_SGQ_B_SG_LIST_CNT 6
333#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
334#define ASC_SGQ_LIST_BEG 8
335#define ASC_DEF_SCSI1_QNG 4
336#define ASC_MAX_SCSI1_QNG 4
337#define ASC_DEF_SCSI2_QNG 16
338#define ASC_MAX_SCSI2_QNG 32
339#define ASC_TAG_CODE_MASK 0x23
340#define ASC_STOP_REQ_RISC_STOP 0x01
341#define ASC_STOP_ACK_RISC_STOP 0x03
342#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
343#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
344#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
345#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
346#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
347#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
348#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
349#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
350#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
351#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
352
353typedef struct asc_scsiq_1 {
27c868c2
MW
354 uchar status;
355 uchar q_no;
356 uchar cntl;
357 uchar sg_queue_cnt;
358 uchar target_id;
359 uchar target_lun;
360 ASC_PADDR data_addr;
361 ASC_DCNT data_cnt;
362 ASC_PADDR sense_addr;
363 uchar sense_len;
364 uchar extra_bytes;
1da177e4
LT
365} ASC_SCSIQ_1;
366
367typedef struct asc_scsiq_2 {
27c868c2
MW
368 ASC_VADDR srb_ptr;
369 uchar target_ix;
370 uchar flag;
371 uchar cdb_len;
372 uchar tag_code;
373 ushort vm_id;
1da177e4
LT
374} ASC_SCSIQ_2;
375
376typedef struct asc_scsiq_3 {
27c868c2
MW
377 uchar done_stat;
378 uchar host_stat;
379 uchar scsi_stat;
380 uchar scsi_msg;
1da177e4
LT
381} ASC_SCSIQ_3;
382
383typedef struct asc_scsiq_4 {
27c868c2
MW
384 uchar cdb[ASC_MAX_CDB_LEN];
385 uchar y_first_sg_list_qp;
386 uchar y_working_sg_qp;
387 uchar y_working_sg_ix;
388 uchar y_res;
389 ushort x_req_count;
390 ushort x_reconnect_rtn;
391 ASC_PADDR x_saved_data_addr;
392 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
393} ASC_SCSIQ_4;
394
395typedef struct asc_q_done_info {
27c868c2
MW
396 ASC_SCSIQ_2 d2;
397 ASC_SCSIQ_3 d3;
398 uchar q_status;
399 uchar q_no;
400 uchar cntl;
401 uchar sense_len;
402 uchar extra_bytes;
403 uchar res;
404 ASC_DCNT remain_bytes;
1da177e4
LT
405} ASC_QDONE_INFO;
406
407typedef struct asc_sg_list {
27c868c2
MW
408 ASC_PADDR addr;
409 ASC_DCNT bytes;
1da177e4
LT
410} ASC_SG_LIST;
411
412typedef struct asc_sg_head {
27c868c2
MW
413 ushort entry_cnt;
414 ushort queue_cnt;
415 ushort entry_to_copy;
416 ushort res;
417 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
418} ASC_SG_HEAD;
419
420#define ASC_MIN_SG_LIST 2
421
422typedef struct asc_min_sg_head {
27c868c2
MW
423 ushort entry_cnt;
424 ushort queue_cnt;
425 ushort entry_to_copy;
426 ushort res;
427 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1da177e4
LT
428} ASC_MIN_SG_HEAD;
429
430#define QCX_SORT (0x0001)
431#define QCX_COALEASE (0x0002)
432
433typedef struct asc_scsi_q {
27c868c2
MW
434 ASC_SCSIQ_1 q1;
435 ASC_SCSIQ_2 q2;
436 uchar *cdbptr;
437 ASC_SG_HEAD *sg_head;
438 ushort remain_sg_entry_cnt;
439 ushort next_sg_index;
1da177e4
LT
440} ASC_SCSI_Q;
441
442typedef struct asc_scsi_req_q {
27c868c2
MW
443 ASC_SCSIQ_1 r1;
444 ASC_SCSIQ_2 r2;
445 uchar *cdbptr;
446 ASC_SG_HEAD *sg_head;
447 uchar *sense_ptr;
448 ASC_SCSIQ_3 r3;
449 uchar cdb[ASC_MAX_CDB_LEN];
450 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
451} ASC_SCSI_REQ_Q;
452
453typedef struct asc_scsi_bios_req_q {
27c868c2
MW
454 ASC_SCSIQ_1 r1;
455 ASC_SCSIQ_2 r2;
456 uchar *cdbptr;
457 ASC_SG_HEAD *sg_head;
458 uchar *sense_ptr;
459 ASC_SCSIQ_3 r3;
460 uchar cdb[ASC_MAX_CDB_LEN];
461 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
462} ASC_SCSI_BIOS_REQ_Q;
463
464typedef struct asc_risc_q {
27c868c2
MW
465 uchar fwd;
466 uchar bwd;
467 ASC_SCSIQ_1 i1;
468 ASC_SCSIQ_2 i2;
469 ASC_SCSIQ_3 i3;
470 ASC_SCSIQ_4 i4;
1da177e4
LT
471} ASC_RISC_Q;
472
473typedef struct asc_sg_list_q {
27c868c2
MW
474 uchar seq_no;
475 uchar q_no;
476 uchar cntl;
477 uchar sg_head_qp;
478 uchar sg_list_cnt;
479 uchar sg_cur_list_cnt;
1da177e4
LT
480} ASC_SG_LIST_Q;
481
482typedef struct asc_risc_sg_list_q {
27c868c2
MW
483 uchar fwd;
484 uchar bwd;
485 ASC_SG_LIST_Q sg;
486 ASC_SG_LIST sg_list[7];
1da177e4
LT
487} ASC_RISC_SG_LIST_Q;
488
489#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
490#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
491#define ASCQ_ERR_NO_ERROR 0
492#define ASCQ_ERR_IO_NOT_FOUND 1
493#define ASCQ_ERR_LOCAL_MEM 2
494#define ASCQ_ERR_CHKSUM 3
495#define ASCQ_ERR_START_CHIP 4
496#define ASCQ_ERR_INT_TARGET_ID 5
497#define ASCQ_ERR_INT_LOCAL_MEM 6
498#define ASCQ_ERR_HALT_RISC 7
499#define ASCQ_ERR_GET_ASPI_ENTRY 8
500#define ASCQ_ERR_CLOSE_ASPI 9
501#define ASCQ_ERR_HOST_INQUIRY 0x0A
502#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
503#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
504#define ASCQ_ERR_Q_STATUS 0x0D
505#define ASCQ_ERR_WR_SCSIQ 0x0E
506#define ASCQ_ERR_PC_ADDR 0x0F
507#define ASCQ_ERR_SYN_OFFSET 0x10
508#define ASCQ_ERR_SYN_XFER_TIME 0x11
509#define ASCQ_ERR_LOCK_DMA 0x12
510#define ASCQ_ERR_UNLOCK_DMA 0x13
511#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
512#define ASCQ_ERR_MICRO_CODE_HALT 0x15
513#define ASCQ_ERR_SET_LRAM_ADDR 0x16
514#define ASCQ_ERR_CUR_QNG 0x17
515#define ASCQ_ERR_SG_Q_LINKS 0x18
516#define ASCQ_ERR_SCSIQ_PTR 0x19
517#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
518#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
519#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1da177e4
LT
520
521/*
522 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
523 */
524#define ASC_WARN_NO_ERROR 0x0000
525#define ASC_WARN_IO_PORT_ROTATE 0x0001
526#define ASC_WARN_EEPROM_CHKSUM 0x0002
527#define ASC_WARN_IRQ_MODIFIED 0x0004
528#define ASC_WARN_AUTO_CONFIG 0x0008
529#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
530#define ASC_WARN_EEPROM_RECOVER 0x0020
531#define ASC_WARN_CFG_MSW_RECOVER 0x0040
532#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
533
534/*
535 * Error code values are set in ASC_DVC_VAR 'err_code'.
536 */
537#define ASC_IERR_WRITE_EEPROM 0x0001
538#define ASC_IERR_MCODE_CHKSUM 0x0002
539#define ASC_IERR_SET_PC_ADDR 0x0004
540#define ASC_IERR_START_STOP_CHIP 0x0008
541#define ASC_IERR_IRQ_NO 0x0010
542#define ASC_IERR_SET_IRQ_NO 0x0020
543#define ASC_IERR_CHIP_VERSION 0x0040
544#define ASC_IERR_SET_SCSI_ID 0x0080
545#define ASC_IERR_GET_PHY_ADDR 0x0100
546#define ASC_IERR_BAD_SIGNATURE 0x0200
547#define ASC_IERR_NO_BUS_TYPE 0x0400
548#define ASC_IERR_SCAM 0x0800
549#define ASC_IERR_SET_SDTR 0x1000
550#define ASC_IERR_RW_LRAM 0x8000
551
552#define ASC_DEF_IRQ_NO 10
553#define ASC_MAX_IRQ_NO 15
554#define ASC_MIN_IRQ_NO 10
555#define ASC_MIN_REMAIN_Q (0x02)
556#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
557#define ASC_MIN_TAG_Q_PER_DVC (0x04)
558#define ASC_DEF_TAG_Q_PER_DVC (0x04)
559#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
560#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
561#define ASC_MAX_TOTAL_QNG 240
562#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
563#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
564#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
565#define ASC_MAX_INRAM_TAG_QNG 16
566#define ASC_IOADR_TABLE_MAX_IX 11
567#define ASC_IOADR_GAP 0x10
1da177e4
LT
568#define ASC_LIB_SCSIQ_WK_SP 256
569#define ASC_MAX_SYN_XFER_NO 16
570#define ASC_SYN_MAX_OFFSET 0x0F
571#define ASC_DEF_SDTR_OFFSET 0x0F
572#define ASC_DEF_SDTR_INDEX 0x00
573#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
574#define SYN_XFER_NS_0 25
575#define SYN_XFER_NS_1 30
576#define SYN_XFER_NS_2 35
577#define SYN_XFER_NS_3 40
578#define SYN_XFER_NS_4 50
579#define SYN_XFER_NS_5 60
580#define SYN_XFER_NS_6 70
581#define SYN_XFER_NS_7 85
582#define SYN_ULTRA_XFER_NS_0 12
583#define SYN_ULTRA_XFER_NS_1 19
584#define SYN_ULTRA_XFER_NS_2 25
585#define SYN_ULTRA_XFER_NS_3 32
586#define SYN_ULTRA_XFER_NS_4 38
587#define SYN_ULTRA_XFER_NS_5 44
588#define SYN_ULTRA_XFER_NS_6 50
589#define SYN_ULTRA_XFER_NS_7 57
590#define SYN_ULTRA_XFER_NS_8 63
591#define SYN_ULTRA_XFER_NS_9 69
592#define SYN_ULTRA_XFER_NS_10 75
593#define SYN_ULTRA_XFER_NS_11 82
594#define SYN_ULTRA_XFER_NS_12 88
595#define SYN_ULTRA_XFER_NS_13 94
596#define SYN_ULTRA_XFER_NS_14 100
597#define SYN_ULTRA_XFER_NS_15 107
598
599typedef struct ext_msg {
27c868c2
MW
600 uchar msg_type;
601 uchar msg_len;
602 uchar msg_req;
603 union {
604 struct {
605 uchar sdtr_xfer_period;
606 uchar sdtr_req_ack_offset;
607 } sdtr;
608 struct {
609 uchar wdtr_width;
610 } wdtr;
611 struct {
612 uchar mdp_b3;
613 uchar mdp_b2;
614 uchar mdp_b1;
615 uchar mdp_b0;
616 } mdp;
617 } u_ext_msg;
618 uchar res;
1da177e4
LT
619} EXT_MSG;
620
621#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
622#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
623#define wdtr_width u_ext_msg.wdtr.wdtr_width
624#define mdp_b3 u_ext_msg.mdp_b3
625#define mdp_b2 u_ext_msg.mdp_b2
626#define mdp_b1 u_ext_msg.mdp_b1
627#define mdp_b0 u_ext_msg.mdp_b0
628
629typedef struct asc_dvc_cfg {
27c868c2
MW
630 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
631 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
632 ASC_SCSI_BIT_ID_TYPE disc_enable;
633 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
634 uchar chip_scsi_id;
635 uchar isa_dma_speed;
636 uchar isa_dma_channel;
637 uchar chip_version;
638 ushort lib_serial_no;
639 ushort lib_version;
640 ushort mcode_date;
641 ushort mcode_version;
642 uchar max_tag_qng[ASC_MAX_TID + 1];
643 uchar *overrun_buf;
644 uchar sdtr_period_offset[ASC_MAX_TID + 1];
27c868c2 645 uchar adapter_info[6];
1da177e4
LT
646} ASC_DVC_CFG;
647
648#define ASC_DEF_DVC_CNTL 0xFFFF
649#define ASC_DEF_CHIP_SCSI_ID 7
650#define ASC_DEF_ISA_DMA_SPEED 4
651#define ASC_INIT_STATE_NULL 0x0000
652#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
653#define ASC_INIT_STATE_END_GET_CFG 0x0002
654#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
655#define ASC_INIT_STATE_END_SET_CFG 0x0008
656#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
657#define ASC_INIT_STATE_END_LOAD_MC 0x0020
658#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
659#define ASC_INIT_STATE_END_INQUIRY 0x0080
660#define ASC_INIT_RESET_SCSI_DONE 0x0100
661#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
662#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
663#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
664#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
665#define ASC_MIN_TAGGED_CMD 7
666#define ASC_MAX_SCSI_RESET_WAIT 30
667
27c868c2 668struct asc_dvc_var; /* Forward Declaration. */
1da177e4 669
1da177e4 670typedef struct asc_dvc_var {
27c868c2
MW
671 PortAddr iop_base;
672 ushort err_code;
673 ushort dvc_cntl;
674 ushort bug_fix_cntl;
675 ushort bus_type;
27c868c2
MW
676 ASC_SCSI_BIT_ID_TYPE init_sdtr;
677 ASC_SCSI_BIT_ID_TYPE sdtr_done;
678 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
679 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
680 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
681 ASC_SCSI_BIT_ID_TYPE start_motor;
682 uchar scsi_reset_wait;
683 uchar chip_no;
684 char is_in_int;
685 uchar max_total_qng;
686 uchar cur_total_qng;
687 uchar in_critical_cnt;
688 uchar irq_no;
689 uchar last_q_shortage;
690 ushort init_state;
691 uchar cur_dvc_qng[ASC_MAX_TID + 1];
692 uchar max_dvc_qng[ASC_MAX_TID + 1];
693 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
694 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
695 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
696 ASC_DVC_CFG *cfg;
697 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
698 char redo_scam;
699 ushort res2;
700 uchar dos_int13_table[ASC_MAX_TID + 1];
701 ASC_DCNT max_dma_count;
702 ASC_SCSI_BIT_ID_TYPE no_scam;
703 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
704 uchar max_sdtr_index;
705 uchar host_init_sdtr_index;
706 struct asc_board *drv_ptr;
707 ASC_DCNT uc_break;
1da177e4
LT
708} ASC_DVC_VAR;
709
710typedef struct asc_dvc_inq_info {
27c868c2 711 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
712} ASC_DVC_INQ_INFO;
713
714typedef struct asc_cap_info {
27c868c2
MW
715 ASC_DCNT lba;
716 ASC_DCNT blk_size;
1da177e4
LT
717} ASC_CAP_INFO;
718
719typedef struct asc_cap_info_array {
27c868c2 720 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
721} ASC_CAP_INFO_ARRAY;
722
723#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
724#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
725#define ASC_CNTL_INITIATOR (ushort)0x0001
726#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
727#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
728#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
729#define ASC_CNTL_NO_SCAM (ushort)0x0010
730#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
731#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
732#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
733#define ASC_CNTL_RESET_SCSI (ushort)0x0200
734#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
735#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
736#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
737#define ASC_CNTL_BURST_MODE (ushort)0x2000
738#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
739#define ASC_EEP_DVC_CFG_BEG_VL 2
740#define ASC_EEP_MAX_DVC_ADDR_VL 15
741#define ASC_EEP_DVC_CFG_BEG 32
742#define ASC_EEP_MAX_DVC_ADDR 45
743#define ASC_EEP_DEFINED_WORDS 10
744#define ASC_EEP_MAX_ADDR 63
745#define ASC_EEP_RES_WORDS 0
746#define ASC_EEP_MAX_RETRY 20
747#define ASC_MAX_INIT_BUSY_RETRY 8
748#define ASC_EEP_ISA_PNP_WSIZE 16
749
750/*
751 * These macros keep the chip SCSI id and ISA DMA speed
752 * bitfields in board order. C bitfields aren't portable
753 * between big and little-endian platforms so they are
754 * not used.
755 */
756
757#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
758#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
759#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
760 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
761#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
762 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
763
764typedef struct asceep_config {
27c868c2
MW
765 ushort cfg_lsw;
766 ushort cfg_msw;
767 uchar init_sdtr;
768 uchar disc_enable;
769 uchar use_cmd_qng;
770 uchar start_motor;
771 uchar max_total_qng;
772 uchar max_tag_qng;
773 uchar bios_scan;
774 uchar power_up_wait;
775 uchar no_scam;
776 uchar id_speed; /* low order 4 bits is chip scsi id */
777 /* high order 4 bits is isa dma speed */
778 uchar dos_int13_table[ASC_MAX_TID + 1];
779 uchar adapter_info[6];
780 ushort cntl;
781 ushort chksum;
1da177e4
LT
782} ASCEEP_CONFIG;
783
784#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
785#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
786#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
787
788#define ASC_EEP_CMD_READ 0x80
789#define ASC_EEP_CMD_WRITE 0x40
790#define ASC_EEP_CMD_WRITE_ABLE 0x30
791#define ASC_EEP_CMD_WRITE_DISABLE 0x00
792#define ASC_OVERRUN_BSIZE 0x00000048UL
793#define ASC_CTRL_BREAK_ONCE 0x0001
794#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
795#define ASCV_MSGOUT_BEG 0x0000
796#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
797#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
798#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
799#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
800#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
801#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
802#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
803#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
804#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
805#define ASCV_BREAK_ADDR (ushort)0x0028
806#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
807#define ASCV_BREAK_CONTROL (ushort)0x002C
808#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
809
810#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
811#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
812#define ASCV_MCODE_SIZE_W (ushort)0x0034
813#define ASCV_STOP_CODE_B (ushort)0x0036
814#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
815#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
816#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
817#define ASCV_HALTCODE_W (ushort)0x0040
818#define ASCV_CHKSUM_W (ushort)0x0042
819#define ASCV_MC_DATE_W (ushort)0x0044
820#define ASCV_MC_VER_W (ushort)0x0046
821#define ASCV_NEXTRDY_B (ushort)0x0048
822#define ASCV_DONENEXT_B (ushort)0x0049
823#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
824#define ASCV_SCSIBUSY_B (ushort)0x004B
825#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
826#define ASCV_CURCDB_B (ushort)0x004D
827#define ASCV_RCLUN_B (ushort)0x004E
828#define ASCV_BUSY_QHEAD_B (ushort)0x004F
829#define ASCV_DISC1_QHEAD_B (ushort)0x0050
830#define ASCV_DISC_ENABLE_B (ushort)0x0052
831#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
832#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
833#define ASCV_MCODE_CNTL_B (ushort)0x0056
834#define ASCV_NULL_TARGET_B (ushort)0x0057
835#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
836#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
837#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
838#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
839#define ASCV_HOST_FLAG_B (ushort)0x005D
840#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
841#define ASCV_VER_SERIAL_B (ushort)0x0065
842#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
843#define ASCV_WTM_FLAG_B (ushort)0x0068
844#define ASCV_RISC_FLAG_B (ushort)0x006A
845#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
846#define ASC_HOST_FLAG_IN_ISR 0x01
847#define ASC_HOST_FLAG_ACK_INT 0x02
848#define ASC_RISC_FLAG_GEN_INT 0x01
849#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
850#define IOP_CTRL (0x0F)
851#define IOP_STATUS (0x0E)
852#define IOP_INT_ACK IOP_STATUS
853#define IOP_REG_IFC (0x0D)
854#define IOP_SYN_OFFSET (0x0B)
855#define IOP_EXTRA_CONTROL (0x0D)
856#define IOP_REG_PC (0x0C)
857#define IOP_RAM_ADDR (0x0A)
858#define IOP_RAM_DATA (0x08)
859#define IOP_EEP_DATA (0x06)
860#define IOP_EEP_CMD (0x07)
861#define IOP_VERSION (0x03)
862#define IOP_CONFIG_HIGH (0x04)
863#define IOP_CONFIG_LOW (0x02)
864#define IOP_SIG_BYTE (0x01)
865#define IOP_SIG_WORD (0x00)
866#define IOP_REG_DC1 (0x0E)
867#define IOP_REG_DC0 (0x0C)
868#define IOP_REG_SB (0x0B)
869#define IOP_REG_DA1 (0x0A)
870#define IOP_REG_DA0 (0x08)
871#define IOP_REG_SC (0x09)
872#define IOP_DMA_SPEED (0x07)
873#define IOP_REG_FLAG (0x07)
874#define IOP_FIFO_H (0x06)
875#define IOP_FIFO_L (0x04)
876#define IOP_REG_ID (0x05)
877#define IOP_REG_QP (0x03)
878#define IOP_REG_IH (0x02)
879#define IOP_REG_IX (0x01)
880#define IOP_REG_AX (0x00)
881#define IFC_REG_LOCK (0x00)
882#define IFC_REG_UNLOCK (0x09)
883#define IFC_WR_EN_FILTER (0x10)
884#define IFC_RD_NO_EEPROM (0x10)
885#define IFC_SLEW_RATE (0x20)
886#define IFC_ACT_NEG (0x40)
887#define IFC_INP_FILTER (0x80)
888#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
889#define SC_SEL (uchar)(0x80)
890#define SC_BSY (uchar)(0x40)
891#define SC_ACK (uchar)(0x20)
892#define SC_REQ (uchar)(0x10)
893#define SC_ATN (uchar)(0x08)
894#define SC_IO (uchar)(0x04)
895#define SC_CD (uchar)(0x02)
896#define SC_MSG (uchar)(0x01)
897#define SEC_SCSI_CTL (uchar)(0x80)
898#define SEC_ACTIVE_NEGATE (uchar)(0x40)
899#define SEC_SLEW_RATE (uchar)(0x20)
900#define SEC_ENABLE_FILTER (uchar)(0x10)
901#define ASC_HALT_EXTMSG_IN (ushort)0x8000
902#define ASC_HALT_CHK_CONDITION (ushort)0x8100
903#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
904#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
905#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
906#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
907#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
908#define ASC_MAX_QNO 0xF8
909#define ASC_DATA_SEC_BEG (ushort)0x0080
910#define ASC_DATA_SEC_END (ushort)0x0080
911#define ASC_CODE_SEC_BEG (ushort)0x0080
912#define ASC_CODE_SEC_END (ushort)0x0080
913#define ASC_QADR_BEG (0x4000)
914#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
915#define ASC_QADR_END (ushort)0x7FFF
916#define ASC_QLAST_ADR (ushort)0x7FC0
917#define ASC_QBLK_SIZE 0x40
918#define ASC_BIOS_DATA_QBEG 0xF8
919#define ASC_MIN_ACTIVE_QNO 0x01
920#define ASC_QLINK_END 0xFF
921#define ASC_EEPROM_WORDS 0x10
922#define ASC_MAX_MGS_LEN 0x10
923#define ASC_BIOS_ADDR_DEF 0xDC00
924#define ASC_BIOS_SIZE 0x3800
925#define ASC_BIOS_RAM_OFF 0x3800
926#define ASC_BIOS_RAM_SIZE 0x800
927#define ASC_BIOS_MIN_ADDR 0xC000
928#define ASC_BIOS_MAX_ADDR 0xEC00
929#define ASC_BIOS_BANK_SIZE 0x0400
930#define ASC_MCODE_START_ADDR 0x0080
931#define ASC_CFG0_HOST_INT_ON 0x0020
932#define ASC_CFG0_BIOS_ON 0x0040
933#define ASC_CFG0_VERA_BURST_ON 0x0080
934#define ASC_CFG0_SCSI_PARITY_ON 0x0800
935#define ASC_CFG1_SCSI_TARGET_ON 0x0080
936#define ASC_CFG1_LRAM_8BITS_ON 0x0800
937#define ASC_CFG_MSW_CLR_MASK 0x3080
938#define CSW_TEST1 (ASC_CS_TYPE)0x8000
939#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
940#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
941#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
942#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
943#define CSW_TEST2 (ASC_CS_TYPE)0x0400
944#define CSW_TEST3 (ASC_CS_TYPE)0x0200
945#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
946#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
947#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
948#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
949#define CSW_HALTED (ASC_CS_TYPE)0x0010
950#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
951#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
952#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
953#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
954#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
955#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
956#define CIW_TEST1 (ASC_CS_TYPE)0x0200
957#define CIW_TEST2 (ASC_CS_TYPE)0x0400
958#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
959#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
960#define CC_CHIP_RESET (uchar)0x80
961#define CC_SCSI_RESET (uchar)0x40
962#define CC_HALT (uchar)0x20
963#define CC_SINGLE_STEP (uchar)0x10
964#define CC_DMA_ABLE (uchar)0x08
965#define CC_TEST (uchar)0x04
966#define CC_BANK_ONE (uchar)0x02
967#define CC_DIAG (uchar)0x01
968#define ASC_1000_ID0W 0x04C1
969#define ASC_1000_ID0W_FIX 0x00C1
970#define ASC_1000_ID1B 0x25
1da177e4
LT
971#define ASC_EISA_REV_IOP_MASK (0x0C83)
972#define ASC_EISA_PID_IOP_MASK (0x0C80)
973#define ASC_EISA_CFG_IOP_MASK (0x0C86)
974#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1da177e4
LT
975#define INS_HALTINT (ushort)0x6281
976#define INS_HALT (ushort)0x6280
977#define INS_SINT (ushort)0x6200
978#define INS_RFLAG_WTM (ushort)0x7380
979#define ASC_MC_SAVE_CODE_WSIZE 0x500
980#define ASC_MC_SAVE_DATA_WSIZE 0x40
981
982typedef struct asc_mc_saved {
27c868c2
MW
983 ushort data[ASC_MC_SAVE_DATA_WSIZE];
984 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
985} ASC_MC_SAVED;
986
987#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
988#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
989#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
990#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
991#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
992#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
993#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
994#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
995#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
996#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
997#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
998#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
999#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1000#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1001#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1002#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1003#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1004#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1005#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1006#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1007#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1008#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1009#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1010#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1011#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1012#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1013#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1014#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1015#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1016#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1017#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1018#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1019#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1020#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1021#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1022#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1023#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1024#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1025#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1026#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1027#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1028#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1029#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1030#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1031#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1032#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1033#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1034#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1035#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1036#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1037#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1038#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1039#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1040#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1041#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1042#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1043#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1044#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1045#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1046#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1047#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1048#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1049#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1050#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1051#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1052#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1053#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1054#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1055
27c868c2
MW
1056static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1057static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1058static void AscWaitEEPRead(void);
1059static void AscWaitEEPWrite(void);
1060static ushort AscReadEEPWord(PortAddr, uchar);
1061static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1062static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1063static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1064static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1065static int AscStartChip(PortAddr);
1066static int AscStopChip(PortAddr);
1067static void AscSetChipIH(PortAddr, ushort);
1068static int AscIsChipHalted(PortAddr);
1069static void AscAckInterrupt(PortAddr);
1070static void AscDisableInterrupt(PortAddr);
1071static void AscEnableInterrupt(PortAddr);
1072static void AscSetBank(PortAddr, uchar);
1073static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 1074#ifdef CONFIG_ISA
27c868c2 1075static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 1076#endif /* CONFIG_ISA */
27c868c2
MW
1077static uchar AscReadLramByte(PortAddr, ushort);
1078static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 1079#if CC_VERY_LONG_SG_LIST
27c868c2 1080static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 1081#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
1082static void AscWriteLramWord(PortAddr, ushort, ushort);
1083static void AscWriteLramByte(PortAddr, ushort, uchar);
1084static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1085static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1086static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1087static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1088static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1089static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1090static ushort AscInitFromEEP(ASC_DVC_VAR *);
27c868c2
MW
1091static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1092static int AscTestExternalLram(ASC_DVC_VAR *);
1093static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1094static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1095static void AscSetChipSDTR(PortAddr, uchar, uchar);
1096static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1097static uchar AscAllocFreeQueue(PortAddr, uchar);
1098static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1099static int AscHostReqRiscHalt(PortAddr);
1100static int AscStopQueueExe(PortAddr);
1101static int AscSendScsiQueue(ASC_DVC_VAR *,
1102 ASC_SCSI_Q *scsiq, uchar n_q_required);
1103static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1104static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1105static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1106static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1107static ushort AscInitLram(ASC_DVC_VAR *);
1108static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1109static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1110static int AscIsrChipHalted(ASC_DVC_VAR *);
1111static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1112 ASC_QDONE_INFO *, ASC_DCNT);
1113static int AscIsrQDone(ASC_DVC_VAR *);
1da177e4 1114#ifdef CONFIG_ISA
27c868c2 1115static ushort AscGetEisaChipCfg(PortAddr);
1da177e4 1116#endif /* CONFIG_ISA */
27c868c2 1117static uchar AscGetChipScsiCtrl(PortAddr);
27c868c2 1118static uchar AscGetChipVersion(PortAddr, ushort);
27c868c2 1119static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
27c868c2 1120static void AscToggleIRQAct(PortAddr);
27c868c2
MW
1121static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1122static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
27c868c2 1123static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
47d853cc 1124static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
27c868c2
MW
1125static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1126static int AscISR(ASC_DVC_VAR *);
1127static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1128static int AscSgListToQueue(int);
1da177e4 1129#ifdef CONFIG_ISA
27c868c2 1130static void AscEnableIsaDma(uchar);
1da177e4 1131#endif /* CONFIG_ISA */
27c868c2 1132static const char *advansys_info(struct Scsi_Host *shost);
1da177e4
LT
1133
1134/*
1135 * --- Adv Library Constants and Macros
1136 */
1137
1138#define ADV_LIB_VERSION_MAJOR 5
1139#define ADV_LIB_VERSION_MINOR 14
1140
1141/*
1142 * Define Adv Library required special types.
1143 */
1144
1145/*
1146 * Portable Data Types
1147 *
1148 * Any instance where a 32-bit long or pointer type is assumed
1149 * for precision or HW defined structures, the following define
1150 * types must be used. In Linux the char, short, and int types
1151 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1152 * and long types are 64 bits on Alpha and UltraSPARC.
1153 */
27c868c2
MW
1154#define ADV_PADDR __u32 /* Physical address data type. */
1155#define ADV_VADDR __u32 /* Virtual address data type. */
1156#define ADV_DCNT __u32 /* Unsigned Data count type. */
1157#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
1158
1159/*
1160 * These macros are used to convert a virtual address to a
1161 * 32-bit value. This currently can be used on Linux Alpha
1162 * which uses 64-bit virtual address but a 32-bit bus address.
1163 * This is likely to break in the future, but doing this now
1164 * will give us time to change the HW and FW to handle 64-bit
1165 * addresses.
1166 */
1167#define ADV_VADDR_TO_U32 virt_to_bus
1168#define ADV_U32_TO_VADDR bus_to_virt
1169
27c868c2 1170#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
1171
1172/*
1173 * Define Adv Library required memory access macros.
1174 */
1175#define ADV_MEM_READB(addr) readb(addr)
1176#define ADV_MEM_READW(addr) readw(addr)
1177#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1178#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1179#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1180
1181#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1182
1da177e4
LT
1183/*
1184 * Define total number of simultaneous maximum element scatter-gather
1185 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1186 * maximum number of outstanding commands per wide host adapter. Each
1187 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1188 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1189 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1190 * structures or 255 scatter-gather elements.
1191 *
1192 */
1193#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1194
1195/*
1196 * Define Adv Library required maximum number of scatter-gather
1197 * elements per request.
1198 */
1199#define ADV_MAX_SG_LIST 255
1200
1201/* Number of SG blocks needed. */
1202#define ADV_NUM_SG_BLOCK \
1203 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1204
1205/* Total contiguous memory needed for SG blocks. */
1206#define ADV_SG_TOTAL_MEM_SIZE \
1207 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1208
1209#define ADV_PAGE_SIZE PAGE_SIZE
1210
1211#define ADV_NUM_PAGE_CROSSING \
1212 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1213
1da177e4
LT
1214#define ADV_EEP_DVC_CFG_BEGIN (0x00)
1215#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 1216#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
1217#define ADV_EEP_MAX_WORD_ADDR (0x1E)
1218
1219#define ADV_EEP_DELAY_MS 100
1220
27c868c2
MW
1221#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1222#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
1223/*
1224 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1225 * For later ICs Bit 13 controls whether the CIS (Card Information
1226 * Service Section) is loaded from EEPROM.
1227 */
27c868c2
MW
1228#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1229#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
1230/*
1231 * ASC38C1600 Bit 11
1232 *
1233 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1234 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1235 * Function 0 will specify INT B.
1236 *
1237 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1238 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1239 * Function 1 will specify INT A.
1240 */
27c868c2
MW
1241#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1242
1243typedef struct adveep_3550_config {
1244 /* Word Offset, Description */
1245
1246 ushort cfg_lsw; /* 00 power up initialization */
1247 /* bit 13 set - Term Polarity Control */
1248 /* bit 14 set - BIOS Enable */
1249 /* bit 15 set - Big Endian Mode */
1250 ushort cfg_msw; /* 01 unused */
1251 ushort disc_enable; /* 02 disconnect enable */
1252 ushort wdtr_able; /* 03 Wide DTR able */
1253 ushort sdtr_able; /* 04 Synchronous DTR able */
1254 ushort start_motor; /* 05 send start up motor */
1255 ushort tagqng_able; /* 06 tag queuing able */
1256 ushort bios_scan; /* 07 BIOS device control */
1257 ushort scam_tolerant; /* 08 no scam */
1258
1259 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1260 uchar bios_boot_delay; /* power up wait */
1261
1262 uchar scsi_reset_delay; /* 10 reset delay */
1263 uchar bios_id_lun; /* first boot device scsi id & lun */
1264 /* high nibble is lun */
1265 /* low nibble is scsi id */
1266
1267 uchar termination; /* 11 0 - automatic */
1268 /* 1 - low off / high off */
1269 /* 2 - low off / high on */
1270 /* 3 - low on / high on */
1271 /* There is no low on / high off */
1272
1273 uchar reserved1; /* reserved byte (not used) */
1274
1275 ushort bios_ctrl; /* 12 BIOS control bits */
1276 /* bit 0 BIOS don't act as initiator. */
1277 /* bit 1 BIOS > 1 GB support */
1278 /* bit 2 BIOS > 2 Disk Support */
1279 /* bit 3 BIOS don't support removables */
1280 /* bit 4 BIOS support bootable CD */
1281 /* bit 5 BIOS scan enabled */
1282 /* bit 6 BIOS support multiple LUNs */
1283 /* bit 7 BIOS display of message */
1284 /* bit 8 SCAM disabled */
1285 /* bit 9 Reset SCSI bus during init. */
1286 /* bit 10 */
1287 /* bit 11 No verbose initialization. */
1288 /* bit 12 SCSI parity enabled */
1289 /* bit 13 */
1290 /* bit 14 */
1291 /* bit 15 */
1292 ushort ultra_able; /* 13 ULTRA speed able */
1293 ushort reserved2; /* 14 reserved */
1294 uchar max_host_qng; /* 15 maximum host queuing */
1295 uchar max_dvc_qng; /* maximum per device queuing */
1296 ushort dvc_cntl; /* 16 control bit for driver */
1297 ushort bug_fix; /* 17 control bit for bug fix */
1298 ushort serial_number_word1; /* 18 Board serial number word 1 */
1299 ushort serial_number_word2; /* 19 Board serial number word 2 */
1300 ushort serial_number_word3; /* 20 Board serial number word 3 */
1301 ushort check_sum; /* 21 EEP check sum */
1302 uchar oem_name[16]; /* 22 OEM name */
1303 ushort dvc_err_code; /* 30 last device driver error code */
1304 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1305 ushort adv_err_addr; /* 32 last uc error address */
1306 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1307 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1308 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1309 ushort num_of_err; /* 36 number of error */
1da177e4
LT
1310} ADVEEP_3550_CONFIG;
1311
27c868c2
MW
1312typedef struct adveep_38C0800_config {
1313 /* Word Offset, Description */
1314
1315 ushort cfg_lsw; /* 00 power up initialization */
1316 /* bit 13 set - Load CIS */
1317 /* bit 14 set - BIOS Enable */
1318 /* bit 15 set - Big Endian Mode */
1319 ushort cfg_msw; /* 01 unused */
1320 ushort disc_enable; /* 02 disconnect enable */
1321 ushort wdtr_able; /* 03 Wide DTR able */
1322 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1323 ushort start_motor; /* 05 send start up motor */
1324 ushort tagqng_able; /* 06 tag queuing able */
1325 ushort bios_scan; /* 07 BIOS device control */
1326 ushort scam_tolerant; /* 08 no scam */
1327
1328 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1329 uchar bios_boot_delay; /* power up wait */
1330
1331 uchar scsi_reset_delay; /* 10 reset delay */
1332 uchar bios_id_lun; /* first boot device scsi id & lun */
1333 /* high nibble is lun */
1334 /* low nibble is scsi id */
1335
1336 uchar termination_se; /* 11 0 - automatic */
1337 /* 1 - low off / high off */
1338 /* 2 - low off / high on */
1339 /* 3 - low on / high on */
1340 /* There is no low on / high off */
1341
1342 uchar termination_lvd; /* 11 0 - automatic */
1343 /* 1 - low off / high off */
1344 /* 2 - low off / high on */
1345 /* 3 - low on / high on */
1346 /* There is no low on / high off */
1347
1348 ushort bios_ctrl; /* 12 BIOS control bits */
1349 /* bit 0 BIOS don't act as initiator. */
1350 /* bit 1 BIOS > 1 GB support */
1351 /* bit 2 BIOS > 2 Disk Support */
1352 /* bit 3 BIOS don't support removables */
1353 /* bit 4 BIOS support bootable CD */
1354 /* bit 5 BIOS scan enabled */
1355 /* bit 6 BIOS support multiple LUNs */
1356 /* bit 7 BIOS display of message */
1357 /* bit 8 SCAM disabled */
1358 /* bit 9 Reset SCSI bus during init. */
1359 /* bit 10 */
1360 /* bit 11 No verbose initialization. */
1361 /* bit 12 SCSI parity enabled */
1362 /* bit 13 */
1363 /* bit 14 */
1364 /* bit 15 */
1365 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1366 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1367 uchar max_host_qng; /* 15 maximum host queueing */
1368 uchar max_dvc_qng; /* maximum per device queuing */
1369 ushort dvc_cntl; /* 16 control bit for driver */
1370 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1371 ushort serial_number_word1; /* 18 Board serial number word 1 */
1372 ushort serial_number_word2; /* 19 Board serial number word 2 */
1373 ushort serial_number_word3; /* 20 Board serial number word 3 */
1374 ushort check_sum; /* 21 EEP check sum */
1375 uchar oem_name[16]; /* 22 OEM name */
1376 ushort dvc_err_code; /* 30 last device driver error code */
1377 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1378 ushort adv_err_addr; /* 32 last uc error address */
1379 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1380 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1381 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1382 ushort reserved36; /* 36 reserved */
1383 ushort reserved37; /* 37 reserved */
1384 ushort reserved38; /* 38 reserved */
1385 ushort reserved39; /* 39 reserved */
1386 ushort reserved40; /* 40 reserved */
1387 ushort reserved41; /* 41 reserved */
1388 ushort reserved42; /* 42 reserved */
1389 ushort reserved43; /* 43 reserved */
1390 ushort reserved44; /* 44 reserved */
1391 ushort reserved45; /* 45 reserved */
1392 ushort reserved46; /* 46 reserved */
1393 ushort reserved47; /* 47 reserved */
1394 ushort reserved48; /* 48 reserved */
1395 ushort reserved49; /* 49 reserved */
1396 ushort reserved50; /* 50 reserved */
1397 ushort reserved51; /* 51 reserved */
1398 ushort reserved52; /* 52 reserved */
1399 ushort reserved53; /* 53 reserved */
1400 ushort reserved54; /* 54 reserved */
1401 ushort reserved55; /* 55 reserved */
1402 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1403 ushort cisprt_msw; /* 57 CIS PTR MSW */
1404 ushort subsysvid; /* 58 SubSystem Vendor ID */
1405 ushort subsysid; /* 59 SubSystem ID */
1406 ushort reserved60; /* 60 reserved */
1407 ushort reserved61; /* 61 reserved */
1408 ushort reserved62; /* 62 reserved */
1409 ushort reserved63; /* 63 reserved */
1da177e4
LT
1410} ADVEEP_38C0800_CONFIG;
1411
27c868c2
MW
1412typedef struct adveep_38C1600_config {
1413 /* Word Offset, Description */
1414
1415 ushort cfg_lsw; /* 00 power up initialization */
1416 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1417 /* clear - Func. 0 INTA, Func. 1 INTB */
1418 /* bit 13 set - Load CIS */
1419 /* bit 14 set - BIOS Enable */
1420 /* bit 15 set - Big Endian Mode */
1421 ushort cfg_msw; /* 01 unused */
1422 ushort disc_enable; /* 02 disconnect enable */
1423 ushort wdtr_able; /* 03 Wide DTR able */
1424 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1425 ushort start_motor; /* 05 send start up motor */
1426 ushort tagqng_able; /* 06 tag queuing able */
1427 ushort bios_scan; /* 07 BIOS device control */
1428 ushort scam_tolerant; /* 08 no scam */
1429
1430 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1431 uchar bios_boot_delay; /* power up wait */
1432
1433 uchar scsi_reset_delay; /* 10 reset delay */
1434 uchar bios_id_lun; /* first boot device scsi id & lun */
1435 /* high nibble is lun */
1436 /* low nibble is scsi id */
1437
1438 uchar termination_se; /* 11 0 - automatic */
1439 /* 1 - low off / high off */
1440 /* 2 - low off / high on */
1441 /* 3 - low on / high on */
1442 /* There is no low on / high off */
1443
1444 uchar termination_lvd; /* 11 0 - automatic */
1445 /* 1 - low off / high off */
1446 /* 2 - low off / high on */
1447 /* 3 - low on / high on */
1448 /* There is no low on / high off */
1449
1450 ushort bios_ctrl; /* 12 BIOS control bits */
1451 /* bit 0 BIOS don't act as initiator. */
1452 /* bit 1 BIOS > 1 GB support */
1453 /* bit 2 BIOS > 2 Disk Support */
1454 /* bit 3 BIOS don't support removables */
1455 /* bit 4 BIOS support bootable CD */
1456 /* bit 5 BIOS scan enabled */
1457 /* bit 6 BIOS support multiple LUNs */
1458 /* bit 7 BIOS display of message */
1459 /* bit 8 SCAM disabled */
1460 /* bit 9 Reset SCSI bus during init. */
1461 /* bit 10 Basic Integrity Checking disabled */
1462 /* bit 11 No verbose initialization. */
1463 /* bit 12 SCSI parity enabled */
1464 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1465 /* bit 14 */
1466 /* bit 15 */
1467 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1468 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1469 uchar max_host_qng; /* 15 maximum host queueing */
1470 uchar max_dvc_qng; /* maximum per device queuing */
1471 ushort dvc_cntl; /* 16 control bit for driver */
1472 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1473 ushort serial_number_word1; /* 18 Board serial number word 1 */
1474 ushort serial_number_word2; /* 19 Board serial number word 2 */
1475 ushort serial_number_word3; /* 20 Board serial number word 3 */
1476 ushort check_sum; /* 21 EEP check sum */
1477 uchar oem_name[16]; /* 22 OEM name */
1478 ushort dvc_err_code; /* 30 last device driver error code */
1479 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1480 ushort adv_err_addr; /* 32 last uc error address */
1481 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1482 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1483 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1484 ushort reserved36; /* 36 reserved */
1485 ushort reserved37; /* 37 reserved */
1486 ushort reserved38; /* 38 reserved */
1487 ushort reserved39; /* 39 reserved */
1488 ushort reserved40; /* 40 reserved */
1489 ushort reserved41; /* 41 reserved */
1490 ushort reserved42; /* 42 reserved */
1491 ushort reserved43; /* 43 reserved */
1492 ushort reserved44; /* 44 reserved */
1493 ushort reserved45; /* 45 reserved */
1494 ushort reserved46; /* 46 reserved */
1495 ushort reserved47; /* 47 reserved */
1496 ushort reserved48; /* 48 reserved */
1497 ushort reserved49; /* 49 reserved */
1498 ushort reserved50; /* 50 reserved */
1499 ushort reserved51; /* 51 reserved */
1500 ushort reserved52; /* 52 reserved */
1501 ushort reserved53; /* 53 reserved */
1502 ushort reserved54; /* 54 reserved */
1503 ushort reserved55; /* 55 reserved */
1504 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1505 ushort cisprt_msw; /* 57 CIS PTR MSW */
1506 ushort subsysvid; /* 58 SubSystem Vendor ID */
1507 ushort subsysid; /* 59 SubSystem ID */
1508 ushort reserved60; /* 60 reserved */
1509 ushort reserved61; /* 61 reserved */
1510 ushort reserved62; /* 62 reserved */
1511 ushort reserved63; /* 63 reserved */
1da177e4
LT
1512} ADVEEP_38C1600_CONFIG;
1513
1514/*
1515 * EEPROM Commands
1516 */
1517#define ASC_EEP_CMD_DONE 0x0200
1518#define ASC_EEP_CMD_DONE_ERR 0x0001
1519
1520/* cfg_word */
1521#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
1522
1523/* bios_ctrl */
1524#define BIOS_CTRL_BIOS 0x0001
1525#define BIOS_CTRL_EXTENDED_XLAT 0x0002
1526#define BIOS_CTRL_GT_2_DISK 0x0004
1527#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1528#define BIOS_CTRL_BOOTABLE_CD 0x0010
1529#define BIOS_CTRL_MULTIPLE_LUN 0x0040
1530#define BIOS_CTRL_DISPLAY_MSG 0x0080
1531#define BIOS_CTRL_NO_SCAM 0x0100
1532#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1533#define BIOS_CTRL_INIT_VERBOSE 0x0800
1534#define BIOS_CTRL_SCSI_PARITY 0x1000
1535#define BIOS_CTRL_AIPP_DIS 0x2000
1536
27c868c2 1537#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1da177e4 1538
27c868c2 1539#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1540
1541/*
1542 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1543 * a special 16K Adv Library and Microcode version. After the issue is
1544 * resolved, should restore 32K support.
1545 *
1546 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1547 */
27c868c2 1548#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1549
1550/*
1551 * Byte I/O register address from base of 'iop_base'.
1552 */
1553#define IOPB_INTR_STATUS_REG 0x00
1554#define IOPB_CHIP_ID_1 0x01
1555#define IOPB_INTR_ENABLES 0x02
1556#define IOPB_CHIP_TYPE_REV 0x03
1557#define IOPB_RES_ADDR_4 0x04
1558#define IOPB_RES_ADDR_5 0x05
1559#define IOPB_RAM_DATA 0x06
1560#define IOPB_RES_ADDR_7 0x07
1561#define IOPB_FLAG_REG 0x08
1562#define IOPB_RES_ADDR_9 0x09
1563#define IOPB_RISC_CSR 0x0A
1564#define IOPB_RES_ADDR_B 0x0B
1565#define IOPB_RES_ADDR_C 0x0C
1566#define IOPB_RES_ADDR_D 0x0D
1567#define IOPB_SOFT_OVER_WR 0x0E
1568#define IOPB_RES_ADDR_F 0x0F
1569#define IOPB_MEM_CFG 0x10
1570#define IOPB_RES_ADDR_11 0x11
1571#define IOPB_GPIO_DATA 0x12
1572#define IOPB_RES_ADDR_13 0x13
1573#define IOPB_FLASH_PAGE 0x14
1574#define IOPB_RES_ADDR_15 0x15
1575#define IOPB_GPIO_CNTL 0x16
1576#define IOPB_RES_ADDR_17 0x17
1577#define IOPB_FLASH_DATA 0x18
1578#define IOPB_RES_ADDR_19 0x19
1579#define IOPB_RES_ADDR_1A 0x1A
1580#define IOPB_RES_ADDR_1B 0x1B
1581#define IOPB_RES_ADDR_1C 0x1C
1582#define IOPB_RES_ADDR_1D 0x1D
1583#define IOPB_RES_ADDR_1E 0x1E
1584#define IOPB_RES_ADDR_1F 0x1F
1585#define IOPB_DMA_CFG0 0x20
1586#define IOPB_DMA_CFG1 0x21
1587#define IOPB_TICKLE 0x22
1588#define IOPB_DMA_REG_WR 0x23
1589#define IOPB_SDMA_STATUS 0x24
1590#define IOPB_SCSI_BYTE_CNT 0x25
1591#define IOPB_HOST_BYTE_CNT 0x26
1592#define IOPB_BYTE_LEFT_TO_XFER 0x27
1593#define IOPB_BYTE_TO_XFER_0 0x28
1594#define IOPB_BYTE_TO_XFER_1 0x29
1595#define IOPB_BYTE_TO_XFER_2 0x2A
1596#define IOPB_BYTE_TO_XFER_3 0x2B
1597#define IOPB_ACC_GRP 0x2C
1598#define IOPB_RES_ADDR_2D 0x2D
1599#define IOPB_DEV_ID 0x2E
1600#define IOPB_RES_ADDR_2F 0x2F
1601#define IOPB_SCSI_DATA 0x30
1602#define IOPB_RES_ADDR_31 0x31
1603#define IOPB_RES_ADDR_32 0x32
1604#define IOPB_SCSI_DATA_HSHK 0x33
1605#define IOPB_SCSI_CTRL 0x34
1606#define IOPB_RES_ADDR_35 0x35
1607#define IOPB_RES_ADDR_36 0x36
1608#define IOPB_RES_ADDR_37 0x37
1609#define IOPB_RAM_BIST 0x38
1610#define IOPB_PLL_TEST 0x39
1611#define IOPB_PCI_INT_CFG 0x3A
1612#define IOPB_RES_ADDR_3B 0x3B
1613#define IOPB_RFIFO_CNT 0x3C
1614#define IOPB_RES_ADDR_3D 0x3D
1615#define IOPB_RES_ADDR_3E 0x3E
1616#define IOPB_RES_ADDR_3F 0x3F
1617
1618/*
1619 * Word I/O register address from base of 'iop_base'.
1620 */
27c868c2
MW
1621#define IOPW_CHIP_ID_0 0x00 /* CID0 */
1622#define IOPW_CTRL_REG 0x02 /* CC */
1623#define IOPW_RAM_ADDR 0x04 /* LA */
1624#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 1625#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
1626#define IOPW_RISC_CSR 0x0A /* CSR */
1627#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1628#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 1629#define IOPW_RES_ADDR_10 0x10
27c868c2 1630#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 1631#define IOPW_RES_ADDR_14 0x14
27c868c2 1632#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 1633#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
1634#define IOPW_EE_CMD 0x1A /* EC */
1635#define IOPW_EE_DATA 0x1C /* ED */
1636#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 1637#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
1638#define IOPW_Q_BASE 0x22 /* QB */
1639#define IOPW_QP 0x24 /* QP */
1640#define IOPW_IX 0x26 /* IX */
1641#define IOPW_SP 0x28 /* SP */
1642#define IOPW_PC 0x2A /* PC */
1da177e4
LT
1643#define IOPW_RES_ADDR_2C 0x2C
1644#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
1645#define IOPW_SCSI_DATA 0x30 /* SD */
1646#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1647#define IOPW_SCSI_CTRL 0x34 /* SC */
1648#define IOPW_HSHK_CFG 0x36 /* HCFG */
1649#define IOPW_SXFR_STATUS 0x36 /* SXS */
1650#define IOPW_SXFR_CNTL 0x38 /* SXL */
1651#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 1652#define IOPW_RES_ADDR_3C 0x3C
27c868c2 1653#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
1654
1655/*
1656 * Doubleword I/O register address from base of 'iop_base'.
1657 */
1658#define IOPDW_RES_ADDR_0 0x00
1659#define IOPDW_RAM_DATA 0x04
1660#define IOPDW_RES_ADDR_8 0x08
1661#define IOPDW_RES_ADDR_C 0x0C
1662#define IOPDW_RES_ADDR_10 0x10
1663#define IOPDW_COMMA 0x14
1664#define IOPDW_COMMB 0x18
1665#define IOPDW_RES_ADDR_1C 0x1C
1666#define IOPDW_SDMA_ADDR0 0x20
1667#define IOPDW_SDMA_ADDR1 0x24
1668#define IOPDW_SDMA_COUNT 0x28
1669#define IOPDW_SDMA_ERROR 0x2C
1670#define IOPDW_RDMA_ADDR0 0x30
1671#define IOPDW_RDMA_ADDR1 0x34
1672#define IOPDW_RDMA_COUNT 0x38
1673#define IOPDW_RDMA_ERROR 0x3C
1674
1675#define ADV_CHIP_ID_BYTE 0x25
1676#define ADV_CHIP_ID_WORD 0x04C1
1677
1678#define ADV_SC_SCSI_BUS_RESET 0x2000
1679
1680#define ADV_INTR_ENABLE_HOST_INTR 0x01
1681#define ADV_INTR_ENABLE_SEL_INTR 0x02
1682#define ADV_INTR_ENABLE_DPR_INTR 0x04
1683#define ADV_INTR_ENABLE_RTA_INTR 0x08
1684#define ADV_INTR_ENABLE_RMA_INTR 0x10
1685#define ADV_INTR_ENABLE_RST_INTR 0x20
1686#define ADV_INTR_ENABLE_DPE_INTR 0x40
1687#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1688
1689#define ADV_INTR_STATUS_INTRA 0x01
1690#define ADV_INTR_STATUS_INTRB 0x02
1691#define ADV_INTR_STATUS_INTRC 0x04
1692
1693#define ADV_RISC_CSR_STOP (0x0000)
1694#define ADV_RISC_TEST_COND (0x2000)
1695#define ADV_RISC_CSR_RUN (0x4000)
1696#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1697
1698#define ADV_CTRL_REG_HOST_INTR 0x0100
1699#define ADV_CTRL_REG_SEL_INTR 0x0200
1700#define ADV_CTRL_REG_DPR_INTR 0x0400
1701#define ADV_CTRL_REG_RTA_INTR 0x0800
1702#define ADV_CTRL_REG_RMA_INTR 0x1000
1703#define ADV_CTRL_REG_RES_BIT14 0x2000
1704#define ADV_CTRL_REG_DPE_INTR 0x4000
1705#define ADV_CTRL_REG_POWER_DONE 0x8000
1706#define ADV_CTRL_REG_ANY_INTR 0xFF00
1707
1708#define ADV_CTRL_REG_CMD_RESET 0x00C6
1709#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1710#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1711#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1712#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1713
1714#define ADV_TICKLE_NOP 0x00
1715#define ADV_TICKLE_A 0x01
1716#define ADV_TICKLE_B 0x02
1717#define ADV_TICKLE_C 0x03
1718
1719#define ADV_SCSI_CTRL_RSTOUT 0x2000
1720
1721#define AdvIsIntPending(port) \
1722 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1723
1724/*
1725 * SCSI_CFG0 Register bit definitions
1726 */
27c868c2
MW
1727#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1728#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1729#define EVEN_PARITY 0x1000 /* Select Even Parity */
1730#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1731#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1732#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1733#define SCAM_EN 0x0080 /* Enable SCAM selection */
1734#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1735#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1736#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1737#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
1738
1739/*
1740 * SCSI_CFG1 Register bit definitions
1741 */
27c868c2
MW
1742#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1743#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1744#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1745#define FILTER_SEL 0x0C00 /* Filter Period Selection */
1746#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1747#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1748#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1749#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1750#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1751#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1752#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1753#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1754#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1755#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1756#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
1757
1758/*
1759 * Addendum for ASC-38C0800 Chip
1760 *
1761 * The ASC-38C1600 Chip uses the same definitions except that the
1762 * bus mode override bits [12:10] have been moved to byte register
1763 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1764 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1765 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1766 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1767 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1768 */
27c868c2
MW
1769#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1770#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1771#define HVD 0x1000 /* HVD Device Detect */
1772#define LVD 0x0800 /* LVD Device Detect */
1773#define SE 0x0400 /* SE Device Detect */
1774#define TERM_LVD 0x00C0 /* LVD Termination Bits */
1775#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1776#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1777#define TERM_SE 0x0030 /* SE Termination Bits */
1778#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1779#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1780#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1781#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1782#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1783#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1784#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1785#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
1786
1787#define CABLE_ILLEGAL_A 0x7
1788 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1789
1790#define CABLE_ILLEGAL_B 0xB
1791 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1792
1793/*
1794 * MEM_CFG Register bit definitions
1795 */
27c868c2
MW
1796#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1797#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1798#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1799#define RAM_SZ_2KB 0x00 /* 2 KB */
1800#define RAM_SZ_4KB 0x04 /* 4 KB */
1801#define RAM_SZ_8KB 0x08 /* 8 KB */
1802#define RAM_SZ_16KB 0x0C /* 16 KB */
1803#define RAM_SZ_32KB 0x10 /* 32 KB */
1804#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
1805
1806/*
1807 * DMA_CFG0 Register bit definitions
1808 *
1809 * This register is only accessible to the host.
1810 */
27c868c2
MW
1811#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1812#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1813#define FIFO_THRESH_16B 0x00 /* 16 bytes */
1814#define FIFO_THRESH_32B 0x20 /* 32 bytes */
1815#define FIFO_THRESH_48B 0x30 /* 48 bytes */
1816#define FIFO_THRESH_64B 0x40 /* 64 bytes */
1817#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1818#define FIFO_THRESH_96B 0x60 /* 96 bytes */
1819#define FIFO_THRESH_112B 0x70 /* 112 bytes */
1820#define START_CTL 0x0C /* DMA start conditions */
1821#define START_CTL_TH 0x00 /* Wait threshold level (default) */
1822#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1823#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1824#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1825#define READ_CMD 0x03 /* Memory Read Method */
1826#define READ_CMD_MR 0x00 /* Memory Read */
1827#define READ_CMD_MRL 0x02 /* Memory Read Long */
1828#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
1829
1830/*
1831 * ASC-38C0800 RAM BIST Register bit definitions
1832 */
1833#define RAM_TEST_MODE 0x80
1834#define PRE_TEST_MODE 0x40
1835#define NORMAL_MODE 0x00
1836#define RAM_TEST_DONE 0x10
1837#define RAM_TEST_STATUS 0x0F
1838#define RAM_TEST_HOST_ERROR 0x08
1839#define RAM_TEST_INTRAM_ERROR 0x04
1840#define RAM_TEST_RISC_ERROR 0x02
1841#define RAM_TEST_SCSI_ERROR 0x01
1842#define RAM_TEST_SUCCESS 0x00
1843#define PRE_TEST_VALUE 0x05
1844#define NORMAL_VALUE 0x00
1845
1846/*
1847 * ASC38C1600 Definitions
1848 *
1849 * IOPB_PCI_INT_CFG Bit Field Definitions
1850 */
1851
27c868c2 1852#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
1853
1854/*
1855 * Bit 1 can be set to change the interrupt for the Function to operate in
1856 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1857 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1858 * mode, otherwise the operating mode is undefined.
1859 */
1860#define TOTEMPOLE 0x02
1861
1862/*
1863 * Bit 0 can be used to change the Int Pin for the Function. The value is
1864 * 0 by default for both Functions with Function 0 using INT A and Function
1865 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1866 * INT A is used.
1867 *
1868 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1869 * value specified in the PCI Configuration Space.
1870 */
1871#define INTAB 0x01
1872
1873/* a_advlib.h */
1874
1875/*
1876 * Adv Library Status Definitions
1877 */
1878#define ADV_TRUE 1
1879#define ADV_FALSE 0
1880#define ADV_NOERROR 1
1881#define ADV_SUCCESS 1
1882#define ADV_BUSY 0
1883#define ADV_ERROR (-1)
1884
1da177e4
LT
1885/*
1886 * ADV_DVC_VAR 'warn_code' values
1887 */
27c868c2
MW
1888#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1889#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1890#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
1891#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
1892#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 1893
27c868c2
MW
1894#define ADV_MAX_TID 15 /* max. target identifier */
1895#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
1896
1897/*
1898 * Error code values are set in ADV_DVC_VAR 'err_code'.
1899 */
27c868c2
MW
1900#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
1901#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
1902#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
1903#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
1904#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
1905#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
1906#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
1907#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
1908#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
1909#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
1910#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
1911#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
1912#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
1913#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
1914
1915/*
1916 * Fixed locations of microcode operating variables.
1917 */
27c868c2
MW
1918#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1919#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1920#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1921#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1922#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1923#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1924#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1925#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1926#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1927#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1928#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1929#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1930#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
1931#define ASC_MC_CHIP_TYPE 0x009A
1932#define ASC_MC_INTRB_CODE 0x009B
1933#define ASC_MC_WDTR_ABLE 0x009C
1934#define ASC_MC_SDTR_ABLE 0x009E
1935#define ASC_MC_TAGQNG_ABLE 0x00A0
1936#define ASC_MC_DISC_ENABLE 0x00A2
1937#define ASC_MC_IDLE_CMD_STATUS 0x00A4
1938#define ASC_MC_IDLE_CMD 0x00A6
1939#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1940#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1941#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1942#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1943#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1944#define ASC_MC_SDTR_DONE 0x00B6
1945#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1946#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1947#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 1948#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 1949#define ASC_MC_WDTR_DONE 0x0124
27c868c2 1950#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
1951#define ASC_MC_ICQ 0x0160
1952#define ASC_MC_IRQ 0x0164
1953#define ASC_MC_PPR_ABLE 0x017A
1954
1955/*
1956 * BIOS LRAM variable absolute offsets.
1957 */
1958#define BIOS_CODESEG 0x54
1959#define BIOS_CODELEN 0x56
1960#define BIOS_SIGNATURE 0x58
1961#define BIOS_VERSION 0x5A
1962
1963/*
1964 * Microcode Control Flags
1965 *
1966 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1967 * and handled by the microcode.
1968 */
27c868c2
MW
1969#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1970#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
1971
1972/*
1973 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1974 */
1975#define HSHK_CFG_WIDE_XFR 0x8000
1976#define HSHK_CFG_RATE 0x0F00
1977#define HSHK_CFG_OFFSET 0x001F
1978
27c868c2
MW
1979#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1980#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1981#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1982#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1983
1984#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1985#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1986#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1987#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1988#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1989
1990#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1991#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1992#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
1993#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
1994#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
1995/*
1996 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1997 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1998 */
27c868c2
MW
1999#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2000#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
2001
2002/*
2003 * All fields here are accessed by the board microcode and need to be
2004 * little-endian.
2005 */
27c868c2
MW
2006typedef struct adv_carr_t {
2007 ADV_VADDR carr_va; /* Carrier Virtual Address */
2008 ADV_PADDR carr_pa; /* Carrier Physical Address */
2009 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2010 /*
2011 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2012 *
2013 * next_vpa [3:1] Reserved Bits
2014 * next_vpa [0] Done Flag set in Response Queue.
2015 */
2016 ADV_VADDR next_vpa;
1da177e4
LT
2017} ADV_CARR_T;
2018
2019/*
2020 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2021 */
2022#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2023
2024#define ASC_RQ_DONE 0x00000001
2025#define ASC_RQ_GOOD 0x00000002
2026#define ASC_CQ_STOPPER 0x00000000
2027
2028#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2029
2030#define ADV_CARRIER_NUM_PAGE_CROSSING \
2031 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2032 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2033
2034#define ADV_CARRIER_BUFSIZE \
2035 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2036
2037/*
2038 * ASC_SCSI_REQ_Q 'a_flag' definitions
2039 *
2040 * The Adv Library should limit use to the lower nibble (4 bits) of
2041 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2042 */
27c868c2
MW
2043#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2044#define ADV_SCSIQ_DONE 0x02 /* request done */
2045#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 2046
27c868c2
MW
2047#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2048#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2049#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
2050
2051/*
2052 * Adapter temporary configuration structure
2053 *
2054 * This structure can be discarded after initialization. Don't add
2055 * fields here needed after initialization.
2056 *
2057 * Field naming convention:
2058 *
2059 * *_enable indicates the field enables or disables a feature. The
2060 * value of the field is never reset.
2061 */
2062typedef struct adv_dvc_cfg {
27c868c2
MW
2063 ushort disc_enable; /* enable disconnection */
2064 uchar chip_version; /* chip version */
2065 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2066 ushort lib_version; /* Adv Library version number */
2067 ushort control_flag; /* Microcode Control Flag */
2068 ushort mcode_date; /* Microcode date */
2069 ushort mcode_version; /* Microcode version */
27c868c2
MW
2070 ushort serial1; /* EEPROM serial number word 1 */
2071 ushort serial2; /* EEPROM serial number word 2 */
2072 ushort serial3; /* EEPROM serial number word 3 */
1da177e4
LT
2073} ADV_DVC_CFG;
2074
2075struct adv_dvc_var;
2076struct adv_scsi_req_q;
2077
1da177e4
LT
2078/*
2079 * Adapter operation variable structure.
2080 *
2081 * One structure is required per host adapter.
2082 *
2083 * Field naming convention:
2084 *
2085 * *_able indicates both whether a feature should be enabled or disabled
2086 * and whether a device isi capable of the feature. At initialization
2087 * this field may be set, but later if a device is found to be incapable
2088 * of the feature, the field is cleared.
2089 */
2090typedef struct adv_dvc_var {
27c868c2
MW
2091 AdvPortAddr iop_base; /* I/O port address */
2092 ushort err_code; /* fatal error code */
2093 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
27c868c2
MW
2094 ushort wdtr_able; /* try WDTR for a device */
2095 ushort sdtr_able; /* try SDTR for a device */
2096 ushort ultra_able; /* try SDTR Ultra speed for a device */
2097 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2098 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2099 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2100 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2101 ushort tagqng_able; /* try tagged queuing with a device */
2102 ushort ppr_able; /* PPR message capable per TID bitmask. */
2103 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2104 ushort start_motor; /* start motor command allowed */
2105 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2106 uchar chip_no; /* should be assigned by caller */
2107 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2108 uchar irq_no; /* IRQ number */
2109 ushort no_scam; /* scam_tolerant of EEPROM */
2110 struct asc_board *drv_ptr; /* driver pointer to private structure */
2111 uchar chip_scsi_id; /* chip SCSI target ID */
2112 uchar chip_type;
2113 uchar bist_err_code;
2114 ADV_CARR_T *carrier_buf;
2115 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2116 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2117 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2118 ushort carr_pending_cnt; /* Count of pending carriers. */
2119 /*
2120 * Note: The following fields will not be used after initialization. The
2121 * driver may discard the buffer after initialization is done.
2122 */
2123 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
2124} ADV_DVC_VAR;
2125
2126#define NO_OF_SG_PER_BLOCK 15
2127
2128typedef struct asc_sg_block {
27c868c2
MW
2129 uchar reserved1;
2130 uchar reserved2;
2131 uchar reserved3;
2132 uchar sg_cnt; /* Valid entries in block. */
2133 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2134 struct {
2135 ADV_PADDR sg_addr; /* SG element address. */
2136 ADV_DCNT sg_count; /* SG element count. */
2137 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
2138} ADV_SG_BLOCK;
2139
2140/*
2141 * ADV_SCSI_REQ_Q - microcode request structure
2142 *
2143 * All fields in this structure up to byte 60 are used by the microcode.
2144 * The microcode makes assumptions about the size and ordering of fields
2145 * in this structure. Do not change the structure definition here without
2146 * coordinating the change with the microcode.
2147 *
2148 * All fields accessed by microcode must be maintained in little_endian
2149 * order.
2150 */
2151typedef struct adv_scsi_req_q {
27c868c2
MW
2152 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2153 uchar target_cmd;
2154 uchar target_id; /* Device target identifier. */
2155 uchar target_lun; /* Device target logical unit number. */
2156 ADV_PADDR data_addr; /* Data buffer physical address. */
2157 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2158 ADV_PADDR sense_addr;
2159 ADV_PADDR carr_pa;
2160 uchar mflag;
2161 uchar sense_len;
2162 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2163 uchar scsi_cntl;
2164 uchar done_status; /* Completion status. */
2165 uchar scsi_status; /* SCSI status byte. */
2166 uchar host_status; /* Ucode host status. */
2167 uchar sg_working_ix;
2168 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2169 ADV_PADDR sg_real_addr; /* SG list physical address. */
2170 ADV_PADDR scsiq_rptr;
2171 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2172 ADV_VADDR scsiq_ptr;
2173 ADV_VADDR carr_va;
2174 /*
2175 * End of microcode structure - 60 bytes. The rest of the structure
2176 * is used by the Adv Library and ignored by the microcode.
2177 */
2178 ADV_VADDR srb_ptr;
2179 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2180 char *vdata_addr; /* Data buffer virtual address. */
2181 uchar a_flag;
2182 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
2183} ADV_SCSI_REQ_Q;
2184
2185/*
2186 * Microcode idle loop commands
2187 */
2188#define IDLE_CMD_COMPLETED 0
2189#define IDLE_CMD_STOP_CHIP 0x0001
2190#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2191#define IDLE_CMD_SEND_INT 0x0004
2192#define IDLE_CMD_ABORT 0x0008
2193#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
2194#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2195#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
2196#define IDLE_CMD_SCSIREQ 0x0080
2197
2198#define IDLE_CMD_STATUS_SUCCESS 0x0001
2199#define IDLE_CMD_STATUS_FAILURE 0x0002
2200
2201/*
2202 * AdvSendIdleCmd() flag definitions.
2203 */
2204#define ADV_NOWAIT 0x01
2205
2206/*
2207 * Wait loop time out values.
2208 */
27c868c2
MW
2209#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
2210#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2211#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2212#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
2213#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 2214
27c868c2
MW
2215#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2216#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2217#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2218#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 2219
27c868c2 2220#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4 2221
27c868c2
MW
2222static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2223 uchar *, ASC_SDCNT *, int);
1da177e4
LT
2224
2225/*
2226 * Adv Library functions available to drivers.
2227 */
27c868c2
MW
2228static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2229static int AdvISR(ADV_DVC_VAR *);
27c868c2
MW
2230static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2231static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
2232static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
2233static int AdvResetChipAndSB(ADV_DVC_VAR *);
2234static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
2235
2236/*
2237 * Internal Adv Library functions.
2238 */
27c868c2 2239static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
27c868c2
MW
2240static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
2241static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
2242static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
2243static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2244static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2245static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2246static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2247static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2248static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2249static void AdvWaitEEPCmd(AdvPortAddr);
2250static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4 2251
1da177e4
LT
2252/* Read byte from a register. */
2253#define AdvReadByteRegister(iop_base, reg_off) \
2254 (ADV_MEM_READB((iop_base) + (reg_off)))
2255
2256/* Write byte to a register. */
2257#define AdvWriteByteRegister(iop_base, reg_off, byte) \
2258 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2259
2260/* Read word (2 bytes) from a register. */
2261#define AdvReadWordRegister(iop_base, reg_off) \
2262 (ADV_MEM_READW((iop_base) + (reg_off)))
2263
2264/* Write word (2 bytes) to a register. */
2265#define AdvWriteWordRegister(iop_base, reg_off, word) \
2266 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2267
2268/* Write dword (4 bytes) to a register. */
2269#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2270 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2271
2272/* Read byte from LRAM. */
2273#define AdvReadByteLram(iop_base, addr, byte) \
2274do { \
2275 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2276 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2277} while (0)
2278
2279/* Write byte to LRAM. */
2280#define AdvWriteByteLram(iop_base, addr, byte) \
2281 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2282 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2283
2284/* Read word (2 bytes) from LRAM. */
2285#define AdvReadWordLram(iop_base, addr, word) \
2286do { \
2287 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2288 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2289} while (0)
2290
2291/* Write word (2 bytes) to LRAM. */
2292#define AdvWriteWordLram(iop_base, addr, word) \
2293 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2294 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2295
2296/* Write little-endian double word (4 bytes) to LRAM */
2297/* Because of unspecified C language ordering don't use auto-increment. */
2298#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2299 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2300 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2301 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2302 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2303 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2304 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2305
2306/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2307#define AdvReadWordAutoIncLram(iop_base) \
2308 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2309
2310/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2311#define AdvWriteWordAutoIncLram(iop_base, word) \
2312 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2313
1da177e4
LT
2314/*
2315 * Define macro to check for Condor signature.
2316 *
2317 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2318 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2319 */
2320#define AdvFindSignature(iop_base) \
2321 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2322 ADV_CHIP_ID_BYTE) && \
2323 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2324 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2325
2326/*
2327 * Define macro to Return the version number of the chip at 'iop_base'.
2328 *
2329 * The second parameter 'bus_type' is currently unused.
2330 */
2331#define AdvGetChipVersion(iop_base, bus_type) \
2332 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2333
2334/*
2335 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2336 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2337 *
2338 * If the request has not yet been sent to the device it will simply be
2339 * aborted from RISC memory. If the request is disconnected it will be
2340 * aborted on reselection by sending an Abort Message to the target ID.
2341 *
2342 * Return value:
2343 * ADV_TRUE(1) - Queue was successfully aborted.
2344 * ADV_FALSE(0) - Queue was not found on the active queue list.
2345 */
2346#define AdvAbortQueue(asc_dvc, scsiq) \
2347 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2348 (ADV_DCNT) (scsiq))
2349
2350/*
2351 * Send a Bus Device Reset Message to the specified target ID.
2352 *
2353 * All outstanding commands will be purged if sending the
2354 * Bus Device Reset Message is successful.
2355 *
2356 * Return Value:
2357 * ADV_TRUE(1) - All requests on the target are purged.
2358 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2359 * are not purged.
2360 */
2361#define AdvResetDevice(asc_dvc, target_id) \
2362 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2363 (ADV_DCNT) (target_id))
2364
2365/*
2366 * SCSI Wide Type definition.
2367 */
2368#define ADV_SCSI_BIT_ID_TYPE ushort
2369
2370/*
2371 * AdvInitScsiTarget() 'cntl_flag' options.
2372 */
2373#define ADV_SCAN_LUN 0x01
2374#define ADV_CAPINFO_NOLUN 0x02
2375
2376/*
2377 * Convert target id to target id bit mask.
2378 */
2379#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2380
2381/*
2382 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2383 */
2384
27c868c2 2385#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
2386#define QD_NO_ERROR 0x01
2387#define QD_ABORTED_BY_HOST 0x02
2388#define QD_WITH_ERROR 0x04
2389
2390#define QHSTA_NO_ERROR 0x00
2391#define QHSTA_M_SEL_TIMEOUT 0x11
2392#define QHSTA_M_DATA_OVER_RUN 0x12
2393#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2394#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
2395#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2396#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2397#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2398#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2399#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2400#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2401#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 2402/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
2403#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2404#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2405#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2406#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2407#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2408#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2409#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2410#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
2411#define QHSTA_M_WTM_TIMEOUT 0x41
2412#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2413#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2414#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
2415#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2416#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2417#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4 2418
1da177e4
LT
2419/*
2420 * DvcGetPhyAddr() flag arguments
2421 */
27c868c2
MW
2422#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2423#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2424#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2425#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2426#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2427#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
2428
2429/* Return the address that is aligned at the next doubleword >= to 'addr'. */
2430#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2431#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2432#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2433
2434/*
2435 * Total contiguous memory needed for driver SG blocks.
2436 *
2437 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2438 * number of scatter-gather elements the driver supports in a
2439 * single request.
2440 */
2441
2442#define ADV_SG_LIST_MAX_BYTE_SIZE \
2443 (sizeof(ADV_SG_BLOCK) * \
2444 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2445
1da177e4
LT
2446/*
2447 * --- Driver Constants and Macros
2448 */
2449
1da177e4
LT
2450/* Reference Scsi_Host hostdata */
2451#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2452
2453/* asc_board_t flags */
2454#define ASC_HOST_IN_RESET 0x01
27c868c2 2455#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
2456#define ASC_SELECT_QUEUE_DEPTHS 0x08
2457
2458#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2459#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
2460
27c868c2 2461#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 2462
27c868c2 2463#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
2464
2465#ifdef CONFIG_PROC_FS
2466/* /proc/scsi/advansys/[0...] related definitions */
2467#define ASC_PRTBUF_SIZE 2048
2468#define ASC_PRTLINE_SIZE 160
2469
2470#define ASC_PRT_NEXT() \
2471 if (cp) { \
2472 totlen += len; \
2473 leftlen -= len; \
2474 if (leftlen == 0) { \
2475 return totlen; \
2476 } \
2477 cp += len; \
2478 }
2479#endif /* CONFIG_PROC_FS */
2480
2481/* Asc Library return codes */
2482#define ASC_TRUE 1
2483#define ASC_FALSE 0
2484#define ASC_NOERROR 1
2485#define ASC_BUSY 0
2486#define ASC_ERROR (-1)
2487
2488/* struct scsi_cmnd function return codes */
2489#define STATUS_BYTE(byte) (byte)
2490#define MSG_BYTE(byte) ((byte) << 8)
2491#define HOST_BYTE(byte) ((byte) << 16)
2492#define DRIVER_BYTE(byte) ((byte) << 24)
2493
1da177e4 2494#ifndef ADVANSYS_STATS
27c868c2
MW
2495#define ASC_STATS(shost, counter)
2496#define ASC_STATS_ADD(shost, counter, count)
1da177e4 2497#else /* ADVANSYS_STATS */
27c868c2
MW
2498#define ASC_STATS(shost, counter) \
2499 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 2500
27c868c2
MW
2501#define ASC_STATS_ADD(shost, counter, count) \
2502 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
2503#endif /* ADVANSYS_STATS */
2504
2505#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2506
2507/* If the result wraps when calculating tenths, return 0. */
2508#define ASC_TENTHS(num, den) \
2509 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2510 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2511
2512/*
2513 * Display a message to the console.
2514 */
2515#define ASC_PRINT(s) \
2516 { \
2517 printk("advansys: "); \
2518 printk(s); \
2519 }
2520
2521#define ASC_PRINT1(s, a1) \
2522 { \
2523 printk("advansys: "); \
2524 printk((s), (a1)); \
2525 }
2526
2527#define ASC_PRINT2(s, a1, a2) \
2528 { \
2529 printk("advansys: "); \
2530 printk((s), (a1), (a2)); \
2531 }
2532
2533#define ASC_PRINT3(s, a1, a2, a3) \
2534 { \
2535 printk("advansys: "); \
2536 printk((s), (a1), (a2), (a3)); \
2537 }
2538
2539#define ASC_PRINT4(s, a1, a2, a3, a4) \
2540 { \
2541 printk("advansys: "); \
2542 printk((s), (a1), (a2), (a3), (a4)); \
2543 }
2544
1da177e4
LT
2545#ifndef ADVANSYS_DEBUG
2546
2547#define ASC_DBG(lvl, s)
2548#define ASC_DBG1(lvl, s, a1)
2549#define ASC_DBG2(lvl, s, a1, a2)
2550#define ASC_DBG3(lvl, s, a1, a2, a3)
2551#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2552#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2553#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2554#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2555#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2556#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2557#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2558#define ASC_DBG_PRT_HEX(lvl, name, start, length)
2559#define ASC_DBG_PRT_CDB(lvl, cdb, len)
2560#define ASC_DBG_PRT_SENSE(lvl, sense, len)
2561#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2562
2563#else /* ADVANSYS_DEBUG */
2564
2565/*
2566 * Debugging Message Levels:
2567 * 0: Errors Only
2568 * 1: High-Level Tracing
2569 * 2-N: Verbose Tracing
2570 */
2571
2572#define ASC_DBG(lvl, s) \
2573 { \
2574 if (asc_dbglvl >= (lvl)) { \
2575 printk(s); \
2576 } \
2577 }
2578
2579#define ASC_DBG1(lvl, s, a1) \
2580 { \
2581 if (asc_dbglvl >= (lvl)) { \
2582 printk((s), (a1)); \
2583 } \
2584 }
2585
2586#define ASC_DBG2(lvl, s, a1, a2) \
2587 { \
2588 if (asc_dbglvl >= (lvl)) { \
2589 printk((s), (a1), (a2)); \
2590 } \
2591 }
2592
2593#define ASC_DBG3(lvl, s, a1, a2, a3) \
2594 { \
2595 if (asc_dbglvl >= (lvl)) { \
2596 printk((s), (a1), (a2), (a3)); \
2597 } \
2598 }
2599
2600#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2601 { \
2602 if (asc_dbglvl >= (lvl)) { \
2603 printk((s), (a1), (a2), (a3), (a4)); \
2604 } \
2605 }
2606
2607#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2608 { \
2609 if (asc_dbglvl >= (lvl)) { \
2610 asc_prt_scsi_host(s); \
2611 } \
2612 }
2613
2614#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2615 { \
2616 if (asc_dbglvl >= (lvl)) { \
2617 asc_prt_scsi_cmnd(s); \
2618 } \
2619 }
2620
2621#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2622 { \
2623 if (asc_dbglvl >= (lvl)) { \
2624 asc_prt_asc_scsi_q(scsiqp); \
2625 } \
2626 }
2627
2628#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2629 { \
2630 if (asc_dbglvl >= (lvl)) { \
2631 asc_prt_asc_qdone_info(qdone); \
2632 } \
2633 }
2634
2635#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2636 { \
2637 if (asc_dbglvl >= (lvl)) { \
2638 asc_prt_adv_scsi_req_q(scsiqp); \
2639 } \
2640 }
2641
2642#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2643 { \
2644 if (asc_dbglvl >= (lvl)) { \
2645 asc_prt_hex((name), (start), (length)); \
2646 } \
2647 }
2648
2649#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2650 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2651
2652#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2653 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2654
2655#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2656 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2657#endif /* ADVANSYS_DEBUG */
2658
1da177e4
LT
2659#ifdef ADVANSYS_STATS
2660
2661/* Per board statistics structure */
2662struct asc_stats {
27c868c2
MW
2663 /* Driver Entrypoint Statistics */
2664 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2665 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2666 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2667 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2668 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2669 ADV_DCNT done; /* # calls to request's scsi_done function */
2670 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2671 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2672 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2673 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2674 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2675 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2676 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2677 ADV_DCNT exe_unknown; /* # unknown returns. */
2678 /* Data Transfer Statistics */
2679 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2680 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2681 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2682 ADV_DCNT sg_elem; /* # scatter-gather elements */
2683 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
2684};
2685#endif /* ADVANSYS_STATS */
2686
1da177e4
LT
2687/*
2688 * Adv Library Request Structures
2689 *
2690 * The following two structures are used to process Wide Board requests.
2691 *
2692 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2693 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2694 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2695 * Mid-Level SCSI request structure.
2696 *
2697 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2698 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2699 * up to 255 scatter-gather elements may be used per request or
2700 * ADV_SCSI_REQ_Q.
2701 *
2702 * Both structures must be 32 byte aligned.
2703 */
2704typedef struct adv_sgblk {
27c868c2
MW
2705 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2706 uchar align[32]; /* Sgblock structure padding. */
2707 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
2708} adv_sgblk_t;
2709
2710typedef struct adv_req {
27c868c2
MW
2711 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2712 uchar align[32]; /* Request structure padding. */
2713 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2714 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2715 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
2716} adv_req_t;
2717
2718/*
2719 * Structure allocated for each board.
2720 *
8dfb5379 2721 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
2722 * of the 'Scsi_Host' structure starting at the 'hostdata'
2723 * field. It is guaranteed to be allocated from DMA-able memory.
2724 */
2725typedef struct asc_board {
394dbf3f 2726 struct device *dev;
27c868c2
MW
2727 int id; /* Board Id */
2728 uint flags; /* Board flags */
2729 union {
2730 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2731 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2732 } dvc_var;
2733 union {
2734 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2735 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2736 } dvc_cfg;
2737 ushort asc_n_io_port; /* Number I/O ports. */
27c868c2
MW
2738 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2739 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
2740 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2741 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2742 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2743 union {
2744 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2745 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2746 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2747 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2748 } eep_config;
2749 ulong last_reset; /* Saved last reset time */
2750 spinlock_t lock; /* Board spinlock */
27c868c2
MW
2751 /* /proc/scsi/advansys/[0...] */
2752 char *prtbuf; /* /proc print buffer */
1da177e4 2753#ifdef ADVANSYS_STATS
27c868c2
MW
2754 struct asc_stats asc_stats; /* Board statistics */
2755#endif /* ADVANSYS_STATS */
2756 /*
2757 * The following fields are used only for Narrow Boards.
2758 */
27c868c2
MW
2759 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2760 /*
2761 * The following fields are used only for Wide Boards.
2762 */
2763 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2764 ushort ioport; /* I/O Port address. */
b2c16f58 2765 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
2766 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2767 adv_req_t *adv_reqp; /* Request structures. */
2768 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2769 ushort bios_signature; /* BIOS Signature. */
2770 ushort bios_version; /* BIOS Version. */
2771 ushort bios_codeseg; /* BIOS Code Segment. */
2772 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
2773} asc_board_t;
2774
13ac2d9c
MW
2775#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2776 dvc_var.adv_dvc_var)
2777#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2778
1da177e4 2779/* Number of boards detected in system. */
78e77d8b
MW
2780static int asc_board_count;
2781
1da177e4 2782/* Overrun buffer used by all narrow boards. */
27c868c2 2783static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
2784
2785/*
2786 * Global structures required to issue a command.
2787 */
27c868c2
MW
2788static ASC_SCSI_Q asc_scsi_q = { {0} };
2789static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4 2790
1da177e4 2791#ifdef ADVANSYS_DEBUG
27c868c2 2792static int asc_dbglvl = 3;
1da177e4
LT
2793#endif /* ADVANSYS_DEBUG */
2794
1da177e4
LT
2795/*
2796 * --- Driver Function Prototypes
1da177e4
LT
2797 */
2798
27c868c2 2799static int advansys_slave_configure(struct scsi_device *);
27c868c2
MW
2800static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
2801static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
2802static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
2803static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
1da177e4 2804#ifdef CONFIG_PROC_FS
27c868c2
MW
2805static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
2806static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
2807static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
2808static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
2809static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
2810static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
2811static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
2812static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
2813static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
2814static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
2815#endif /* CONFIG_PROC_FS */
2816
1da177e4
LT
2817/* Statistics function prototypes. */
2818#ifdef ADVANSYS_STATS
2819#ifdef CONFIG_PROC_FS
27c868c2 2820static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
1da177e4
LT
2821#endif /* CONFIG_PROC_FS */
2822#endif /* ADVANSYS_STATS */
2823
2824/* Debug function prototypes. */
2825#ifdef ADVANSYS_DEBUG
27c868c2
MW
2826static void asc_prt_scsi_host(struct Scsi_Host *);
2827static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
2828static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
2829static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
2830static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
2831static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
2832static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
2833static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
2834static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
2835static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
2836static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
2837#endif /* ADVANSYS_DEBUG */
2838
1da177e4
LT
2839#ifdef CONFIG_PROC_FS
2840/*
c304ec94 2841 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
2842 *
2843 * *buffer: I/O buffer
2844 * **start: if inout == FALSE pointer into buffer where user read should start
2845 * offset: current offset into a /proc/scsi/advansys/[0...] file
2846 * length: length of buffer
2847 * hostno: Scsi_Host host_no
2848 * inout: TRUE - user is writing; FALSE - user is reading
2849 *
2850 * Return the number of bytes read from or written to a
2851 * /proc/scsi/advansys/[0...] file.
2852 *
2853 * Note: This function uses the per board buffer 'prtbuf' which is
2854 * allocated when the board is initialized in advansys_detect(). The
2855 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
2856 * used to write to the buffer. The way asc_proc_copy() is written
2857 * if 'prtbuf' is too small it will not be overwritten. Instead the
2858 * user just won't get all the available statistics.
2859 */
70c8d897 2860static int
1da177e4 2861advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 2862 off_t offset, int length, int inout)
1da177e4 2863{
27c868c2 2864 asc_board_t *boardp;
27c868c2
MW
2865 char *cp;
2866 int cplen;
2867 int cnt;
2868 int totcnt;
2869 int leftlen;
2870 char *curbuf;
2871 off_t advoffset;
1da177e4 2872
27c868c2 2873 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 2874
27c868c2
MW
2875 /*
2876 * User write not supported.
2877 */
2878 if (inout == TRUE) {
2879 return (-ENOSYS);
2880 }
1da177e4 2881
27c868c2
MW
2882 /*
2883 * User read of /proc/scsi/advansys/[0...] file.
2884 */
1da177e4 2885
2a437959 2886 boardp = ASC_BOARDP(shost);
27c868c2
MW
2887
2888 /* Copy read data starting at the beginning of the buffer. */
2889 *start = buffer;
2890 curbuf = buffer;
2891 advoffset = 0;
2892 totcnt = 0;
2893 leftlen = length;
2894
2895 /*
2896 * Get board configuration information.
2897 *
2898 * advansys_info() returns the board string from its own static buffer.
2899 */
2a437959 2900 cp = (char *)advansys_info(shost);
27c868c2
MW
2901 strcat(cp, "\n");
2902 cplen = strlen(cp);
2903 /* Copy board information. */
2904 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2905 totcnt += cnt;
2906 leftlen -= cnt;
2907 if (leftlen == 0) {
2908 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2909 return totcnt;
2910 }
2911 advoffset += cplen;
2912 curbuf += cnt;
2913
2914 /*
2915 * Display Wide Board BIOS Information.
2916 */
2917 if (ASC_WIDE_BOARD(boardp)) {
2918 cp = boardp->prtbuf;
2a437959 2919 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2920 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
ecec1947 2921 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
27c868c2
MW
2922 cplen);
2923 totcnt += cnt;
2924 leftlen -= cnt;
2925 if (leftlen == 0) {
2926 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2927 return totcnt;
2928 }
2929 advoffset += cplen;
2930 curbuf += cnt;
2931 }
1da177e4 2932
27c868c2
MW
2933 /*
2934 * Display driver information for each device attached to the board.
2935 */
2936 cp = boardp->prtbuf;
2a437959 2937 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2938 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2939 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2940 totcnt += cnt;
2941 leftlen -= cnt;
2942 if (leftlen == 0) {
2943 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2944 return totcnt;
2945 }
2946 advoffset += cplen;
2947 curbuf += cnt;
2948
2949 /*
2950 * Display EEPROM configuration for the board.
2951 */
2952 cp = boardp->prtbuf;
2953 if (ASC_NARROW_BOARD(boardp)) {
2a437959 2954 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2955 } else {
2a437959 2956 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2957 }
b009bef6 2958 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2959 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2960 totcnt += cnt;
2961 leftlen -= cnt;
2962 if (leftlen == 0) {
2963 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2964 return totcnt;
2965 }
2966 advoffset += cplen;
2967 curbuf += cnt;
2968
2969 /*
2970 * Display driver configuration and information for the board.
2971 */
2972 cp = boardp->prtbuf;
2a437959 2973 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2974 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2975 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2976 totcnt += cnt;
2977 leftlen -= cnt;
2978 if (leftlen == 0) {
2979 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2980 return totcnt;
2981 }
2982 advoffset += cplen;
2983 curbuf += cnt;
1da177e4
LT
2984
2985#ifdef ADVANSYS_STATS
27c868c2
MW
2986 /*
2987 * Display driver statistics for the board.
2988 */
2989 cp = boardp->prtbuf;
2a437959 2990 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2991 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2992 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2993 totcnt += cnt;
2994 leftlen -= cnt;
2995 if (leftlen == 0) {
2996 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2997 return totcnt;
2998 }
2999 advoffset += cplen;
3000 curbuf += cnt;
1da177e4
LT
3001#endif /* ADVANSYS_STATS */
3002
27c868c2
MW
3003 /*
3004 * Display Asc Library dynamic configuration information
3005 * for the board.
3006 */
3007 cp = boardp->prtbuf;
3008 if (ASC_NARROW_BOARD(boardp)) {
2a437959 3009 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3010 } else {
2a437959 3011 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3012 }
b009bef6 3013 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
3014 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3015 totcnt += cnt;
3016 leftlen -= cnt;
3017 if (leftlen == 0) {
3018 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3019 return totcnt;
3020 }
3021 advoffset += cplen;
3022 curbuf += cnt;
1da177e4 3023
27c868c2 3024 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 3025
27c868c2 3026 return totcnt;
1da177e4 3027}
1da177e4 3028#endif /* CONFIG_PROC_FS */
1da177e4
LT
3029
3030/*
3031 * advansys_info()
3032 *
3033 * Return suitable for printing on the console with the argument
3034 * adapter's configuration information.
3035 *
3036 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3037 * otherwise the static 'info' array will be overrun.
3038 */
27c868c2 3039static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 3040{
27c868c2
MW
3041 static char info[ASC_INFO_SIZE];
3042 asc_board_t *boardp;
3043 ASC_DVC_VAR *asc_dvc_varp;
3044 ADV_DVC_VAR *adv_dvc_varp;
3045 char *busname;
27c868c2
MW
3046 char *widename = NULL;
3047
3048 boardp = ASC_BOARDP(shost);
3049 if (ASC_NARROW_BOARD(boardp)) {
3050 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3051 ASC_DBG(1, "advansys_info: begin\n");
3052 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3053 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3054 ASC_IS_ISAPNP) {
3055 busname = "ISA PnP";
3056 } else {
3057 busname = "ISA";
3058 }
27c868c2
MW
3059 sprintf(info,
3060 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3061 ASC_VERSION, busname,
3062 (ulong)shost->io_port,
4a2d31c8
MW
3063 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3064 shost->irq, shost->dma_channel);
27c868c2
MW
3065 } else {
3066 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3067 busname = "VL";
3068 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3069 busname = "EISA";
3070 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3071 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3072 == ASC_IS_PCI_ULTRA) {
3073 busname = "PCI Ultra";
3074 } else {
3075 busname = "PCI";
3076 }
3077 } else {
3078 busname = "?";
ecec1947
MW
3079 ASC_PRINT2("advansys_info: board %d: unknown "
3080 "bus type %d\n", boardp->id,
3081 asc_dvc_varp->bus_type);
27c868c2 3082 }
27c868c2
MW
3083 sprintf(info,
3084 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
ecec1947 3085 ASC_VERSION, busname, (ulong)shost->io_port,
4a2d31c8
MW
3086 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3087 shost->irq);
27c868c2
MW
3088 }
3089 } else {
3090 /*
3091 * Wide Adapter Information
3092 *
3093 * Memory-mapped I/O is used instead of I/O space to access
3094 * the adapter, but display the I/O Port range. The Memory
3095 * I/O address is displayed through the driver /proc file.
3096 */
3097 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3098 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
27c868c2
MW
3099 widename = "Ultra-Wide";
3100 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
27c868c2
MW
3101 widename = "Ultra2-Wide";
3102 } else {
27c868c2
MW
3103 widename = "Ultra3-Wide";
3104 }
3105 sprintf(info,
3106 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3107 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4a2d31c8 3108 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
27c868c2 3109 }
b009bef6 3110 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
27c868c2
MW
3111 ASC_DBG(1, "advansys_info: end\n");
3112 return info;
1da177e4
LT
3113}
3114
6ed1ef07
MW
3115static void asc_scsi_done(struct scsi_cmnd *scp)
3116{
3117 struct asc_board *boardp = ASC_BOARDP(scp->device->host);
3118
3119 if (scp->use_sg)
3120 dma_unmap_sg(boardp->dev,
3121 (struct scatterlist *)scp->request_buffer,
3122 scp->use_sg, scp->sc_data_direction);
3123 else if (scp->request_bufflen)
3124 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
3125 scp->request_bufflen, scp->sc_data_direction);
3126
3127 ASC_STATS(scp->device->host, done);
3128
3129 scp->scsi_done(scp);
3130}
3131
1da177e4
LT
3132/*
3133 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
3134 *
3135 * This function always returns 0. Command return status is saved
3136 * in the 'scp' result field.
3137 */
70c8d897 3138static int
b2a7a4ba 3139advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
1da177e4 3140{
b2a7a4ba
MW
3141 struct Scsi_Host *shost = scp->device->host;
3142 asc_board_t *boardp = ASC_BOARDP(shost);
3143 unsigned long flags;
b6622925 3144 int asc_res, result = 0;
1da177e4 3145
27c868c2 3146 ASC_STATS(shost, queuecommand);
b2a7a4ba 3147 scp->scsi_done = done;
1da177e4 3148
b2a7a4ba
MW
3149 /*
3150 * host_lock taken by mid-level prior to call, but need
3151 * to protect against own ISR
3152 */
27c868c2 3153 spin_lock_irqsave(&boardp->lock, flags);
b6622925 3154 asc_res = asc_execute_scsi_cmnd(scp);
b2a7a4ba
MW
3155 spin_unlock_irqrestore(&boardp->lock, flags);
3156
b6622925 3157 switch (asc_res) {
27c868c2
MW
3158 case ASC_NOERROR:
3159 break;
3160 case ASC_BUSY:
b6622925 3161 result = SCSI_MLQUEUE_HOST_BUSY;
27c868c2
MW
3162 break;
3163 case ASC_ERROR:
3164 default:
6ed1ef07 3165 asc_scsi_done(scp);
27c868c2
MW
3166 break;
3167 }
1da177e4 3168
b6622925 3169 return result;
1da177e4
LT
3170}
3171
3172/*
3173 * advansys_reset()
3174 *
3175 * Reset the bus associated with the command 'scp'.
3176 *
3177 * This function runs its own thread. Interrupts must be blocked but
3178 * sleeping is allowed and no locking other than for host structures is
3179 * required. Returns SUCCESS or FAILED.
3180 */
27c868c2 3181static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 3182{
27c868c2
MW
3183 struct Scsi_Host *shost;
3184 asc_board_t *boardp;
3185 ASC_DVC_VAR *asc_dvc_varp;
3186 ADV_DVC_VAR *adv_dvc_varp;
3187 ulong flags;
27c868c2
MW
3188 int status;
3189 int ret = SUCCESS;
3190
3191 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
3192
3193#ifdef ADVANSYS_STATS
27c868c2
MW
3194 if (scp->device->host != NULL) {
3195 ASC_STATS(scp->device->host, reset);
3196 }
1da177e4
LT
3197#endif /* ADVANSYS_STATS */
3198
27c868c2
MW
3199 if ((shost = scp->device->host) == NULL) {
3200 scp->result = HOST_BYTE(DID_ERROR);
3201 return FAILED;
3202 }
1da177e4 3203
27c868c2 3204 boardp = ASC_BOARDP(shost);
1da177e4 3205
27c868c2
MW
3206 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
3207 boardp->id);
3208 /*
3209 * Check for re-entrancy.
3210 */
1da177e4 3211 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
3212 if (boardp->flags & ASC_HOST_IN_RESET) {
3213 spin_unlock_irqrestore(&boardp->lock, flags);
3214 return FAILED;
3215 }
3216 boardp->flags |= ASC_HOST_IN_RESET;
3217 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3218
27c868c2
MW
3219 if (ASC_NARROW_BOARD(boardp)) {
3220 /*
3221 * Narrow Board
3222 */
3223 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 3224
27c868c2
MW
3225 /*
3226 * Reset the chip and SCSI bus.
3227 */
3228 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
3229 status = AscInitAsc1000Driver(asc_dvc_varp);
3230
3231 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
3232 if (asc_dvc_varp->err_code) {
ecec1947
MW
3233 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3234 "error: 0x%x\n", boardp->id,
3235 asc_dvc_varp->err_code);
27c868c2
MW
3236 ret = FAILED;
3237 } else if (status) {
ecec1947
MW
3238 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3239 "warning: 0x%x\n", boardp->id, status);
27c868c2 3240 } else {
ecec1947
MW
3241 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3242 "successful.\n", boardp->id);
27c868c2
MW
3243 }
3244
3245 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
3246 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 3247
27c868c2
MW
3248 } else {
3249 /*
3250 * Wide Board
3251 *
3252 * If the suggest reset bus flags are set, then reset the bus.
3253 * Otherwise only reset the device.
3254 */
3255 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 3256
27c868c2
MW
3257 /*
3258 * Reset the target's SCSI bus.
3259 */
3260 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
3261 switch (AdvResetChipAndSB(adv_dvc_varp)) {
3262 case ASC_TRUE:
ecec1947
MW
3263 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3264 "successful.\n", boardp->id);
27c868c2
MW
3265 break;
3266 case ASC_FALSE:
3267 default:
ecec1947
MW
3268 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3269 "error.\n", boardp->id);
27c868c2
MW
3270 ret = FAILED;
3271 break;
3272 }
3273 spin_lock_irqsave(&boardp->lock, flags);
3274 (void)AdvISR(adv_dvc_varp);
3275 }
3276 /* Board lock is held. */
3277
27c868c2
MW
3278 /* Save the time of the most recently completed reset. */
3279 boardp->last_reset = jiffies;
1da177e4 3280
27c868c2
MW
3281 /* Clear reset flag. */
3282 boardp->flags &= ~ASC_HOST_IN_RESET;
3283 spin_unlock_irqrestore(&boardp->lock, flags);
3284
27c868c2 3285 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 3286
27c868c2 3287 return ret;
1da177e4
LT
3288}
3289
3290/*
3291 * advansys_biosparam()
3292 *
3293 * Translate disk drive geometry if the "BIOS greater than 1 GB"
3294 * support is enabled for a drive.
3295 *
3296 * ip (information pointer) is an int array with the following definition:
3297 * ip[0]: heads
3298 * ip[1]: sectors
3299 * ip[2]: cylinders
3300 */
70c8d897 3301static int
1da177e4 3302advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 3303 sector_t capacity, int ip[])
1da177e4 3304{
27c868c2
MW
3305 asc_board_t *boardp;
3306
3307 ASC_DBG(1, "advansys_biosparam: begin\n");
3308 ASC_STATS(sdev->host, biosparam);
3309 boardp = ASC_BOARDP(sdev->host);
3310 if (ASC_NARROW_BOARD(boardp)) {
3311 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
3312 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
3313 ip[0] = 255;
3314 ip[1] = 63;
3315 } else {
3316 ip[0] = 64;
3317 ip[1] = 32;
3318 }
3319 } else {
3320 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
3321 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
3322 ip[0] = 255;
3323 ip[1] = 63;
3324 } else {
3325 ip[0] = 64;
3326 ip[1] = 32;
3327 }
3328 }
3329 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
3330 ASC_DBG(1, "advansys_biosparam: end\n");
3331 return 0;
1da177e4
LT
3332}
3333
8dfb5379 3334static struct scsi_host_template advansys_template = {
27c868c2 3335 .proc_name = "advansys",
1da177e4 3336#ifdef CONFIG_PROC_FS
27c868c2 3337 .proc_info = advansys_proc_info,
1da177e4 3338#endif
27c868c2 3339 .name = "advansys",
27c868c2
MW
3340 .info = advansys_info,
3341 .queuecommand = advansys_queuecommand,
3342 .eh_bus_reset_handler = advansys_reset,
3343 .bios_param = advansys_biosparam,
3344 .slave_configure = advansys_slave_configure,
3345 /*
3346 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
8dfb5379
MW
3347 * must be set. The flag will be cleared in advansys_board_found
3348 * for non-ISA adapters.
27c868c2
MW
3349 */
3350 .unchecked_isa_dma = 1,
3351 /*
3352 * All adapters controlled by this driver are capable of large
3353 * scatter-gather lists. According to the mid-level SCSI documentation
3354 * this obviates any performance gain provided by setting
3355 * 'use_clustering'. But empirically while CPU utilization is increased
3356 * by enabling clustering, I/O throughput increases as well.
3357 */
3358 .use_clustering = ENABLE_CLUSTERING,
1da177e4 3359};
1da177e4 3360
1da177e4
LT
3361/*
3362 * --- Miscellaneous Driver Functions
3363 */
3364
3365/*
3366 * First-level interrupt handler.
3367 *
3368 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
3369 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
3370 * is not referenced. 'dev_id' could be used to identify an interrupt passed
3371 * to the AdvanSys driver which is for a device sharing an interrupt with
3372 * an AdvanSys adapter.
3373 */
27c868c2 3374static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 3375{
074c8fe4 3376 unsigned long flags;
074c8fe4
MW
3377 struct Scsi_Host *shost = dev_id;
3378 asc_board_t *boardp = ASC_BOARDP(shost);
3379 irqreturn_t result = IRQ_NONE;
27c868c2 3380
074c8fe4
MW
3381 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
3382 spin_lock_irqsave(&boardp->lock, flags);
3383 if (ASC_NARROW_BOARD(boardp)) {
3384 /*
3385 * Narrow Board
3386 */
3387 if (AscIsIntPending(shost->io_port)) {
3388 result = IRQ_HANDLED;
3389 ASC_STATS(shost, interrupt);
3390 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
3391 AscISR(&boardp->dvc_var.asc_dvc_var);
3392 }
3393 } else {
3394 /*
3395 * Wide Board
3396 */
3397 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
3398 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
3399 result = IRQ_HANDLED;
3400 ASC_STATS(shost, interrupt);
3401 }
3402 }
27c868c2 3403
074c8fe4 3404 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3405
27c868c2
MW
3406 /*
3407 * If interrupts were enabled on entry, then they
3408 * are now enabled here.
27c868c2 3409 */
1da177e4 3410
27c868c2 3411 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 3412 return result;
1da177e4
LT
3413}
3414
47d853cc
MW
3415static void
3416advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
3417{
3418 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
3419 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
3420
3421 if (sdev->lun == 0) {
3422 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
3423 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
3424 asc_dvc->init_sdtr |= tid_bit;
3425 } else {
3426 asc_dvc->init_sdtr &= ~tid_bit;
3427 }
3428
3429 if (orig_init_sdtr != asc_dvc->init_sdtr)
3430 AscAsyncFix(asc_dvc, sdev);
3431 }
3432
3433 if (sdev->tagged_supported) {
3434 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
3435 if (sdev->lun == 0) {
3436 asc_dvc->cfg->can_tagged_qng |= tid_bit;
3437 asc_dvc->use_tagged_qng |= tid_bit;
3438 }
3439 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3440 asc_dvc->max_dvc_qng[sdev->id]);
3441 }
3442 } else {
3443 if (sdev->lun == 0) {
3444 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
3445 asc_dvc->use_tagged_qng &= ~tid_bit;
3446 }
3447 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
3448 }
3449
3450 if ((sdev->lun == 0) &&
3451 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
3452 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
3453 asc_dvc->cfg->disc_enable);
3454 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
3455 asc_dvc->use_tagged_qng);
3456 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
3457 asc_dvc->cfg->can_tagged_qng);
3458
3459 asc_dvc->max_dvc_qng[sdev->id] =
3460 asc_dvc->cfg->max_tag_qng[sdev->id];
3461 AscWriteLramByte(asc_dvc->iop_base,
3462 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
3463 asc_dvc->max_dvc_qng[sdev->id]);
3464 }
3465}
3466
1da177e4 3467/*
47d853cc
MW
3468 * Wide Transfers
3469 *
3470 * If the EEPROM enabled WDTR for the device and the device supports wide
3471 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
3472 * write the new value to the microcode.
1da177e4 3473 */
47d853cc
MW
3474static void
3475advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
1da177e4 3476{
47d853cc
MW
3477 unsigned short cfg_word;
3478 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
3479 if ((cfg_word & tidmask) != 0)
3480 return;
3481
3482 cfg_word |= tidmask;
3483 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
1da177e4 3484
27c868c2 3485 /*
47d853cc
MW
3486 * Clear the microcode SDTR and WDTR negotiation done indicators for
3487 * the target to cause it to negotiate with the new setting set above.
3488 * WDTR when accepted causes the target to enter asynchronous mode, so
3489 * SDTR must be negotiated.
27c868c2 3490 */
47d853cc
MW
3491 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3492 cfg_word &= ~tidmask;
3493 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3494 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3495 cfg_word &= ~tidmask;
3496 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3497}
3498
3499/*
3500 * Synchronous Transfers
3501 *
3502 * If the EEPROM enabled SDTR for the device and the device
3503 * supports synchronous transfers, then turn on the device's
3504 * 'sdtr_able' bit. Write the new value to the microcode.
3505 */
3506static void
3507advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
3508{
3509 unsigned short cfg_word;
3510 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3511 if ((cfg_word & tidmask) != 0)
3512 return;
3513
3514 cfg_word |= tidmask;
3515 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3516
3517 /*
3518 * Clear the microcode "SDTR negotiation" done indicator for the
3519 * target to cause it to negotiate with the new setting set above.
3520 */
3521 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3522 cfg_word &= ~tidmask;
3523 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3524}
3525
3526/*
3527 * PPR (Parallel Protocol Request) Capable
3528 *
3529 * If the device supports DT mode, then it must be PPR capable.
3530 * The PPR message will be used in place of the SDTR and WDTR
3531 * messages to negotiate synchronous speed and offset, transfer
3532 * width, and protocol options.
3533 */
3534static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
3535 AdvPortAddr iop_base, unsigned short tidmask)
3536{
3537 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3538 adv_dvc->ppr_able |= tidmask;
3539 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3540}
3541
3542static void
3543advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
3544{
3545 AdvPortAddr iop_base = adv_dvc->iop_base;
3546 unsigned short tidmask = 1 << sdev->id;
3547
3548 if (sdev->lun == 0) {
3549 /*
3550 * Handle WDTR, SDTR, and Tag Queuing. If the feature
3551 * is enabled in the EEPROM and the device supports the
3552 * feature, then enable it in the microcode.
3553 */
3554
3555 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
3556 advansys_wide_enable_wdtr(iop_base, tidmask);
3557 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
3558 advansys_wide_enable_sdtr(iop_base, tidmask);
3559 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
3560 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
3561
3562 /*
3563 * Tag Queuing is disabled for the BIOS which runs in polled
3564 * mode and would see no benefit from Tag Queuing. Also by
3565 * disabling Tag Queuing in the BIOS devices with Tag Queuing
3566 * bugs will at least work with the BIOS.
3567 */
3568 if ((adv_dvc->tagqng_able & tidmask) &&
3569 sdev->tagged_supported) {
3570 unsigned short cfg_word;
3571 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
3572 cfg_word |= tidmask;
3573 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
3574 cfg_word);
3575 AdvWriteByteLram(iop_base,
3576 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
3577 adv_dvc->max_dvc_qng);
27c868c2 3578 }
47d853cc
MW
3579 }
3580
3581 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
3582 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3583 adv_dvc->max_dvc_qng);
27c868c2 3584 } else {
47d853cc 3585 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
27c868c2 3586 }
47d853cc
MW
3587}
3588
3589/*
3590 * Set the number of commands to queue per device for the
3591 * specified host adapter.
3592 */
3593static int advansys_slave_configure(struct scsi_device *sdev)
3594{
3595 asc_board_t *boardp = ASC_BOARDP(sdev->host);
3596 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
3597
3598 /*
3599 * Save a pointer to the sdev and set its initial/maximum
3600 * queue depth. Only save the pointer for a lun0 dev though.
3601 */
3602 if (sdev->lun == 0)
3603 boardp->device[sdev->id] = sdev;
3604
3605 if (ASC_NARROW_BOARD(boardp))
3606 advansys_narrow_slave_configure(sdev,
3607 &boardp->dvc_var.asc_dvc_var);
3608 else
3609 advansys_wide_slave_configure(sdev,
3610 &boardp->dvc_var.adv_dvc_var);
3611
27c868c2 3612 return 0;
1da177e4
LT
3613}
3614
1da177e4
LT
3615/*
3616 * Execute a single 'Scsi_Cmnd'.
3617 *
3618 * The function 'done' is called when the request has been completed.
3619 *
3620 * Scsi_Cmnd:
3621 *
3622 * host - board controlling device
3623 * device - device to send command
3624 * target - target of device
3625 * lun - lun of device
3626 * cmd_len - length of SCSI CDB
3627 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
3628 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
3629 *
3630 * if (use_sg == 0) {
3631 * request_buffer - buffer address for request
3632 * request_bufflen - length of request buffer
3633 * } else {
3634 * request_buffer - pointer to scatterlist structure
3635 * }
3636 *
3637 * sense_buffer - sense command buffer
3638 *
3639 * result (4 bytes of an int):
3640 * Byte Meaning
3641 * 0 SCSI Status Byte Code
3642 * 1 SCSI One Byte Message Code
3643 * 2 Host Error Code
3644 * 3 Mid-Level Error Code
3645 *
3646 * host driver fields:
3647 * SCp - Scsi_Pointer used for command processing status
3648 * scsi_done - used to save caller's done function
3649 * host_scribble - used for pointer to another struct scsi_cmnd
3650 *
349d2c44
MW
3651 * If this function returns ASC_NOERROR the request will be completed
3652 * from the interrupt handler.
1da177e4 3653 *
6ed1ef07
MW
3654 * If this function returns ASC_ERROR the host error code has been set,
3655 * and the called must call asc_scsi_done.
1da177e4 3656 *
b6622925
MW
3657 * If ASC_BUSY is returned the request will be returned to the midlayer
3658 * and re-tried later.
1da177e4 3659 */
27c868c2 3660static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 3661{
27c868c2
MW
3662 asc_board_t *boardp;
3663 ASC_DVC_VAR *asc_dvc_varp;
3664 ADV_DVC_VAR *adv_dvc_varp;
3665 ADV_SCSI_REQ_Q *adv_scsiqp;
3666 struct scsi_device *device;
3667 int ret;
3668
3669 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
3670 (ulong)scp, (ulong)scp->scsi_done);
3671
3672 boardp = ASC_BOARDP(scp->device->host);
3673 device = boardp->device[scp->device->id];
3674
3675 if (ASC_NARROW_BOARD(boardp)) {
3676 /*
3677 * Build and execute Narrow Board request.
3678 */
3679
3680 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3681
3682 /*
3683 * Build Asc Library request structure using the
3684 * global structures 'asc_scsi_req' and 'asc_sg_head'.
3685 *
3686 * If an error is returned, then the request has been
3687 * queued on the board done queue. It will be completed
3688 * by the caller.
3689 *
3690 * asc_build_req() can not return ASC_BUSY.
3691 */
3692 if (asc_build_req(boardp, scp) == ASC_ERROR) {
3693 ASC_STATS(scp->device->host, build_error);
3694 return ASC_ERROR;
3695 }
3696
27c868c2
MW
3697 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
3698 case ASC_NOERROR:
3699 ASC_STATS(scp->device->host, exe_noerror);
3700 /*
ecec1947
MW
3701 * Increment monotonically increasing per device
3702 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
3703 */
3704 boardp->reqcnt[scp->device->id]++;
ecec1947
MW
3705 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
3706 "ASC_NOERROR\n");
27c868c2
MW
3707 break;
3708 case ASC_BUSY:
27c868c2
MW
3709 ASC_STATS(scp->device->host, exe_busy);
3710 break;
3711 case ASC_ERROR:
ecec1947
MW
3712 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3713 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
3714 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3715 ASC_STATS(scp->device->host, exe_error);
3716 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3717 break;
3718 default:
ecec1947
MW
3719 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3720 "AscExeScsiQueue() unknown, err_code 0x%x\n",
3721 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3722 ASC_STATS(scp->device->host, exe_unknown);
3723 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3724 break;
3725 }
3726 } else {
3727 /*
3728 * Build and execute Wide Board request.
3729 */
3730 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3731
3732 /*
3733 * Build and get a pointer to an Adv Library request structure.
3734 *
3735 * If the request is successfully built then send it below,
3736 * otherwise return with an error.
3737 */
3738 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
3739 case ASC_NOERROR:
ecec1947
MW
3740 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
3741 "ASC_NOERROR\n");
27c868c2
MW
3742 break;
3743 case ASC_BUSY:
ecec1947
MW
3744 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
3745 "ASC_BUSY\n");
27c868c2 3746 /*
ecec1947
MW
3747 * The asc_stats fields 'adv_build_noreq' and
3748 * 'adv_build_nosg' count wide board busy conditions.
3749 * They are updated in adv_build_req and
3750 * adv_get_sglist, respectively.
27c868c2
MW
3751 */
3752 return ASC_BUSY;
3753 case ASC_ERROR:
27c868c2 3754 default:
ecec1947
MW
3755 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
3756 "ASC_ERROR\n");
27c868c2
MW
3757 ASC_STATS(scp->device->host, build_error);
3758 return ASC_ERROR;
3759 }
1da177e4 3760
27c868c2
MW
3761 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
3762 case ASC_NOERROR:
3763 ASC_STATS(scp->device->host, exe_noerror);
3764 /*
ecec1947
MW
3765 * Increment monotonically increasing per device
3766 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
3767 */
3768 boardp->reqcnt[scp->device->id]++;
ecec1947
MW
3769 ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
3770 "ASC_NOERROR\n");
27c868c2
MW
3771 break;
3772 case ASC_BUSY:
27c868c2
MW
3773 ASC_STATS(scp->device->host, exe_busy);
3774 break;
3775 case ASC_ERROR:
ecec1947
MW
3776 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3777 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
3778 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
3779 ASC_STATS(scp->device->host, exe_error);
3780 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3781 break;
3782 default:
ecec1947
MW
3783 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3784 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
3785 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
3786 ASC_STATS(scp->device->host, exe_unknown);
3787 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3788 break;
3789 }
3790 }
3791
3792 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
3793 return ret;
1da177e4
LT
3794}
3795
3796/*
3797 * Build a request structure for the Asc Library (Narrow Board).
3798 *
3799 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
3800 * used to build the request.
3801 *
6ed1ef07 3802 * If an error occurs, then return ASC_ERROR.
1da177e4 3803 */
27c868c2 3804static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 3805{
27c868c2
MW
3806 /*
3807 * Mutually exclusive access is required to 'asc_scsi_q' and
3808 * 'asc_sg_head' until after the request is started.
3809 */
3810 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
3811
3812 /*
3813 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
3814 */
3815 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
3816
3817 /*
3818 * Build the ASC_SCSI_Q request.
27c868c2 3819 */
27c868c2
MW
3820 asc_scsi_q.cdbptr = &scp->cmnd[0];
3821 asc_scsi_q.q2.cdb_len = scp->cmd_len;
3822 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
3823 asc_scsi_q.q1.target_lun = scp->device->lun;
3824 asc_scsi_q.q2.target_ix =
3825 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
3826 asc_scsi_q.q1.sense_addr =
3827 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
3828 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
3829
3830 /*
3831 * If there are any outstanding requests for the current target,
3832 * then every 255th request send an ORDERED request. This heuristic
3833 * tries to retain the benefit of request sorting while preventing
3834 * request starvation. 255 is the max number of tags or pending commands
3835 * a device may have outstanding.
3836 *
3837 * The request count is incremented below for every successfully
3838 * started request.
3839 *
3840 */
3841 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
3842 (boardp->reqcnt[scp->device->id] % 255) == 0) {
3843 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
3844 } else {
3845 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
3846 }
1da177e4 3847
27c868c2
MW
3848 /*
3849 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
3850 * buffer command.
3851 */
3852 if (scp->use_sg == 0) {
3853 /*
3854 * CDB request of single contiguous buffer.
3855 */
3856 ASC_STATS(scp->device->host, cont_cnt);
3857 scp->SCp.dma_handle = scp->request_bufflen ?
394dbf3f 3858 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
3859 scp->request_bufflen,
3860 scp->sc_data_direction) : 0;
3861 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
3862 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
3863 ASC_STATS_ADD(scp->device->host, cont_xfer,
3864 ASC_CEILING(scp->request_bufflen, 512));
3865 asc_scsi_q.q1.sg_queue_cnt = 0;
3866 asc_scsi_q.sg_head = NULL;
3867 } else {
3868 /*
3869 * CDB scatter-gather request list.
3870 */
3871 int sgcnt;
3872 int use_sg;
3873 struct scatterlist *slp;
3874
3875 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
3876 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
3877 scp->sc_data_direction);
27c868c2
MW
3878
3879 if (use_sg > scp->device->host->sg_tablesize) {
394dbf3f
MW
3880 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
3881 "sg_tablesize %d\n", boardp->id, use_sg,
3882 scp->device->host->sg_tablesize);
3883 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
3884 scp->sc_data_direction);
3885 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3886 return ASC_ERROR;
3887 }
3888
3889 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 3890
27c868c2
MW
3891 /*
3892 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
3893 * structure to point to it.
3894 */
3895 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
3896
3897 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
3898 asc_scsi_q.sg_head = &asc_sg_head;
3899 asc_scsi_q.q1.data_cnt = 0;
3900 asc_scsi_q.q1.data_addr = 0;
3901 /* This is a byte value, otherwise it would need to be swapped. */
3902 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
3903 ASC_STATS_ADD(scp->device->host, sg_elem,
3904 asc_sg_head.entry_cnt);
1da177e4 3905
27c868c2
MW
3906 /*
3907 * Convert scatter-gather list into ASC_SG_HEAD list.
3908 */
3909 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
3910 asc_sg_head.sg_list[sgcnt].addr =
3911 cpu_to_le32(sg_dma_address(slp));
3912 asc_sg_head.sg_list[sgcnt].bytes =
3913 cpu_to_le32(sg_dma_len(slp));
3914 ASC_STATS_ADD(scp->device->host, sg_xfer,
3915 ASC_CEILING(sg_dma_len(slp), 512));
3916 }
3917 }
1da177e4 3918
27c868c2
MW
3919 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
3920 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 3921
27c868c2 3922 return ASC_NOERROR;
1da177e4
LT
3923}
3924
3925/*
3926 * Build a request structure for the Adv Library (Wide Board).
3927 *
3928 * If an adv_req_t can not be allocated to issue the request,
3929 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
3930 *
3931 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
3932 * microcode for DMA addresses or math operations are byte swapped
3933 * to little-endian order.
3934 */
27c868c2 3935static int
1da177e4 3936adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 3937 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 3938{
27c868c2
MW
3939 adv_req_t *reqp;
3940 ADV_SCSI_REQ_Q *scsiqp;
3941 int i;
3942 int ret;
27c868c2
MW
3943
3944 /*
3945 * Allocate an adv_req_t structure from the board to execute
3946 * the command.
3947 */
3948 if (boardp->adv_reqp == NULL) {
3949 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
3950 ASC_STATS(scp->device->host, adv_build_noreq);
3951 return ASC_BUSY;
3952 } else {
3953 reqp = boardp->adv_reqp;
3954 boardp->adv_reqp = reqp->next_reqp;
3955 reqp->next_reqp = NULL;
3956 }
1da177e4 3957
27c868c2
MW
3958 /*
3959 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
3960 */
3961 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
3962
3963 /*
3964 * Initialize the structure.
3965 */
3966 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
3967
3968 /*
3969 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
3970 */
3971 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
3972
3973 /*
3974 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
3975 */
3976 reqp->cmndp = scp;
3977
3978 /*
3979 * Build the ADV_SCSI_REQ_Q request.
3980 */
3981
f05ec594 3982 /* Set CDB length and copy it to the request structure. */
27c868c2
MW
3983 scsiqp->cdb_len = scp->cmd_len;
3984 /* Copy first 12 CDB bytes to cdb[]. */
3985 for (i = 0; i < scp->cmd_len && i < 12; i++) {
3986 scsiqp->cdb[i] = scp->cmnd[i];
3987 }
3988 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
3989 for (; i < scp->cmd_len; i++) {
3990 scsiqp->cdb16[i - 12] = scp->cmnd[i];
3991 }
1da177e4 3992
27c868c2
MW
3993 scsiqp->target_id = scp->device->id;
3994 scsiqp->target_lun = scp->device->lun;
1da177e4 3995
27c868c2
MW
3996 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
3997 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 3998
27c868c2
MW
3999 /*
4000 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
4001 * buffer command.
4002 */
1da177e4 4003
1da177e4 4004 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
4005 scsiqp->vdata_addr = scp->request_buffer;
4006 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 4007
27c868c2
MW
4008 if (scp->use_sg == 0) {
4009 /*
4010 * CDB request of single contiguous buffer.
4011 */
4012 reqp->sgblkp = NULL;
4013 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
4014 if (scp->request_bufflen) {
4015 scsiqp->vdata_addr = scp->request_buffer;
4016 scp->SCp.dma_handle =
394dbf3f 4017 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
4018 scp->request_bufflen,
4019 scp->sc_data_direction);
4020 } else {
4021 scsiqp->vdata_addr = NULL;
4022 scp->SCp.dma_handle = 0;
4023 }
4024 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
4025 scsiqp->sg_list_ptr = NULL;
4026 scsiqp->sg_real_addr = 0;
4027 ASC_STATS(scp->device->host, cont_cnt);
4028 ASC_STATS_ADD(scp->device->host, cont_xfer,
4029 ASC_CEILING(scp->request_bufflen, 512));
4030 } else {
4031 /*
4032 * CDB scatter-gather request list.
4033 */
4034 struct scatterlist *slp;
4035 int use_sg;
4036
4037 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
4038 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4039 scp->sc_data_direction);
27c868c2
MW
4040
4041 if (use_sg > ADV_MAX_SG_LIST) {
394dbf3f
MW
4042 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
4043 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
4044 scp->device->host->sg_tablesize);
4045 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
4046 scp->sc_data_direction);
4047 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
4048
4049 /*
394dbf3f
MW
4050 * Free the 'adv_req_t' structure by adding it back
4051 * to the board free list.
27c868c2
MW
4052 */
4053 reqp->next_reqp = boardp->adv_reqp;
4054 boardp->adv_reqp = reqp;
4055
4056 return ASC_ERROR;
4057 }
4058
394dbf3f
MW
4059 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
4060 if (ret != ADV_SUCCESS) {
27c868c2 4061 /*
394dbf3f
MW
4062 * Free the adv_req_t structure by adding it back to
4063 * the board free list.
27c868c2
MW
4064 */
4065 reqp->next_reqp = boardp->adv_reqp;
4066 boardp->adv_reqp = reqp;
4067
4068 return ret;
4069 }
4070
4071 ASC_STATS(scp->device->host, sg_cnt);
4072 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
4073 }
1da177e4 4074
27c868c2
MW
4075 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4076 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 4077
27c868c2 4078 *adv_scsiqpp = scsiqp;
1da177e4 4079
27c868c2 4080 return ASC_NOERROR;
1da177e4
LT
4081}
4082
4083/*
4084 * Build scatter-gather list for Adv Library (Wide Board).
4085 *
4086 * Additional ADV_SG_BLOCK structures will need to be allocated
4087 * if the total number of scatter-gather elements exceeds
4088 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
4089 * assumed to be physically contiguous.
4090 *
4091 * Return:
4092 * ADV_SUCCESS(1) - SG List successfully created
4093 * ADV_ERROR(-1) - SG List creation failed
4094 */
27c868c2
MW
4095static int
4096adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
4097 int use_sg)
1da177e4 4098{
27c868c2
MW
4099 adv_sgblk_t *sgblkp;
4100 ADV_SCSI_REQ_Q *scsiqp;
4101 struct scatterlist *slp;
4102 int sg_elem_cnt;
4103 ADV_SG_BLOCK *sg_block, *prev_sg_block;
4104 ADV_PADDR sg_block_paddr;
4105 int i;
4106
4107 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
4108 slp = (struct scatterlist *)scp->request_buffer;
4109 sg_elem_cnt = use_sg;
4110 prev_sg_block = NULL;
4111 reqp->sgblkp = NULL;
4112
4113 do {
4114 /*
4115 * Allocate a 'adv_sgblk_t' structure from the board free
4116 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
4117 * (15) scatter-gather elements.
4118 */
4119 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
4120 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
4121 ASC_STATS(scp->device->host, adv_build_nosg);
4122
4123 /*
4124 * Allocation failed. Free 'adv_sgblk_t' structures already
4125 * allocated for the request.
4126 */
4127 while ((sgblkp = reqp->sgblkp) != NULL) {
4128 /* Remove 'sgblkp' from the request list. */
4129 reqp->sgblkp = sgblkp->next_sgblkp;
4130
4131 /* Add 'sgblkp' to the board free list. */
4132 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4133 boardp->adv_sgblkp = sgblkp;
4134 }
4135 return ASC_BUSY;
4136 } else {
4137 /* Complete 'adv_sgblk_t' board allocation. */
4138 boardp->adv_sgblkp = sgblkp->next_sgblkp;
4139 sgblkp->next_sgblkp = NULL;
4140
4141 /*
4142 * Get 8 byte aligned virtual and physical addresses for
4143 * the allocated ADV_SG_BLOCK structure.
4144 */
4145 sg_block =
4146 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
4147 sg_block_paddr = virt_to_bus(sg_block);
4148
4149 /*
4150 * Check if this is the first 'adv_sgblk_t' for the request.
4151 */
4152 if (reqp->sgblkp == NULL) {
4153 /* Request's first scatter-gather block. */
4154 reqp->sgblkp = sgblkp;
4155
4156 /*
4157 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
4158 * address pointers.
4159 */
4160 scsiqp->sg_list_ptr = sg_block;
4161 scsiqp->sg_real_addr =
4162 cpu_to_le32(sg_block_paddr);
4163 } else {
4164 /* Request's second or later scatter-gather block. */
4165 sgblkp->next_sgblkp = reqp->sgblkp;
4166 reqp->sgblkp = sgblkp;
4167
4168 /*
4169 * Point the previous ADV_SG_BLOCK structure to
4170 * the newly allocated ADV_SG_BLOCK structure.
4171 */
27c868c2
MW
4172 prev_sg_block->sg_ptr =
4173 cpu_to_le32(sg_block_paddr);
4174 }
4175 }
4176
4177 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
4178 sg_block->sg_list[i].sg_addr =
4179 cpu_to_le32(sg_dma_address(slp));
4180 sg_block->sg_list[i].sg_count =
4181 cpu_to_le32(sg_dma_len(slp));
4182 ASC_STATS_ADD(scp->device->host, sg_xfer,
4183 ASC_CEILING(sg_dma_len(slp), 512));
4184
4185 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
4186 sg_block->sg_cnt = i + 1;
4187 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
4188 return ADV_SUCCESS;
4189 }
4190 slp++;
4191 }
4192 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
4193 prev_sg_block = sg_block;
4194 }
4195 while (1);
4196 /* NOTREACHED */
1da177e4
LT
4197}
4198
4199/*
4200 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
4201 *
4202 * Interrupt callback function for the Narrow SCSI Asc Library.
4203 */
27c868c2 4204static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 4205{
27c868c2
MW
4206 asc_board_t *boardp;
4207 struct scsi_cmnd *scp;
4208 struct Scsi_Host *shost;
27c868c2
MW
4209
4210 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
4211 (ulong)asc_dvc_varp, (ulong)qdonep);
4212 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
4213
4214 /*
4215 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4216 * command that has been completed.
4217 */
4218 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
4219 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
4220
4221 if (scp == NULL) {
4222 ASC_PRINT("asc_isr_callback: scp is NULL\n");
4223 return;
4224 }
4225 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4226
27c868c2 4227 shost = scp->device->host;
27c868c2
MW
4228 ASC_STATS(shost, callback);
4229 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
4230
27c868c2 4231 boardp = ASC_BOARDP(shost);
b009bef6 4232 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
1da177e4 4233
27c868c2
MW
4234 /*
4235 * 'qdonep' contains the command's ending status.
4236 */
4237 switch (qdonep->d3.done_stat) {
4238 case QD_NO_ERROR:
4239 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
4240 scp->result = 0;
1da177e4 4241
27c868c2
MW
4242 /*
4243 * Check for an underrun condition.
4244 *
4245 * If there was no error and an underrun condition, then
47d853cc 4246 * return the number of underrun bytes.
27c868c2
MW
4247 */
4248 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
4249 qdonep->remain_bytes <= scp->request_bufflen) {
4250 ASC_DBG1(1,
4251 "asc_isr_callback: underrun condition %u bytes\n",
4252 (unsigned)qdonep->remain_bytes);
4253 scp->resid = qdonep->remain_bytes;
4254 }
4255 break;
4256
4257 case QD_WITH_ERROR:
4258 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
4259 switch (qdonep->d3.host_stat) {
4260 case QHSTA_NO_ERROR:
4261 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
4262 ASC_DBG(2,
4263 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4264 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4265 sizeof(scp->sense_buffer));
4266 /*
4267 * Note: The 'status_byte()' macro used by target drivers
4268 * defined in scsi.h shifts the status byte returned by
4269 * host drivers right by 1 bit. This is why target drivers
4270 * also use right shifted status byte definitions. For
4271 * instance target drivers use CHECK_CONDITION, defined to
4272 * 0x1, instead of the SCSI defined check condition value
4273 * of 0x2. Host drivers are supposed to return the status
4274 * byte as it is defined by SCSI.
4275 */
4276 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4277 STATUS_BYTE(qdonep->d3.scsi_stat);
4278 } else {
4279 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
4280 }
4281 break;
4282
4283 default:
4284 /* QHSTA error occurred */
4285 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
4286 qdonep->d3.host_stat);
4287 scp->result = HOST_BYTE(DID_BAD_TARGET);
4288 break;
4289 }
4290 break;
4291
4292 case QD_ABORTED_BY_HOST:
4293 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
4294 scp->result =
4295 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
4296 scsi_msg) |
4297 STATUS_BYTE(qdonep->d3.scsi_stat);
4298 break;
4299
4300 default:
4301 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
4302 qdonep->d3.done_stat);
4303 scp->result =
4304 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
4305 scsi_msg) |
4306 STATUS_BYTE(qdonep->d3.scsi_stat);
4307 break;
4308 }
1da177e4 4309
27c868c2
MW
4310 /*
4311 * If the 'init_tidmask' bit isn't already set for the target and the
4312 * current request finished normally, then set the bit for the target
4313 * to indicate that a device is present.
4314 */
4315 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4316 qdonep->d3.done_stat == QD_NO_ERROR &&
4317 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
4318 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4319 }
1da177e4 4320
6ed1ef07 4321 asc_scsi_done(scp);
1da177e4 4322
27c868c2 4323 return;
1da177e4
LT
4324}
4325
4326/*
4327 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
4328 *
4329 * Callback function for the Wide SCSI Adv Library.
4330 */
27c868c2 4331static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 4332{
27c868c2
MW
4333 asc_board_t *boardp;
4334 adv_req_t *reqp;
4335 adv_sgblk_t *sgblkp;
4336 struct scsi_cmnd *scp;
4337 struct Scsi_Host *shost;
27c868c2
MW
4338 ADV_DCNT resid_cnt;
4339
4340 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
4341 (ulong)adv_dvc_varp, (ulong)scsiqp);
4342 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4343
4344 /*
4345 * Get the adv_req_t structure for the command that has been
4346 * completed. The adv_req_t structure actually contains the
4347 * completed ADV_SCSI_REQ_Q structure.
4348 */
4349 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
4350 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
4351 if (reqp == NULL) {
4352 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
4353 return;
4354 }
1da177e4 4355
27c868c2
MW
4356 /*
4357 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4358 * command that has been completed.
4359 *
4360 * Note: The adv_req_t request structure and adv_sgblk_t structure,
4361 * if any, are dropped, because a board structure pointer can not be
4362 * determined.
4363 */
4364 scp = reqp->cmndp;
4365 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
4366 if (scp == NULL) {
4367 ASC_PRINT
4368 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
4369 return;
4370 }
4371 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4372
27c868c2 4373 shost = scp->device->host;
27c868c2
MW
4374 ASC_STATS(shost, callback);
4375 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
4376
27c868c2 4377 boardp = ASC_BOARDP(shost);
b009bef6 4378 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
1da177e4 4379
27c868c2
MW
4380 /*
4381 * 'done_status' contains the command's ending status.
4382 */
4383 switch (scsiqp->done_status) {
4384 case QD_NO_ERROR:
4385 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
4386 scp->result = 0;
1da177e4 4387
27c868c2
MW
4388 /*
4389 * Check for an underrun condition.
4390 *
4391 * If there was no error and an underrun condition, then
4392 * then return the number of underrun bytes.
4393 */
4394 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
4395 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
4396 resid_cnt <= scp->request_bufflen) {
4397 ASC_DBG1(1,
4398 "adv_isr_callback: underrun condition %lu bytes\n",
4399 (ulong)resid_cnt);
4400 scp->resid = resid_cnt;
4401 }
4402 break;
4403
4404 case QD_WITH_ERROR:
4405 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
4406 switch (scsiqp->host_status) {
4407 case QHSTA_NO_ERROR:
4408 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
4409 ASC_DBG(2,
4410 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4411 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4412 sizeof(scp->sense_buffer));
4413 /*
4414 * Note: The 'status_byte()' macro used by target drivers
4415 * defined in scsi.h shifts the status byte returned by
4416 * host drivers right by 1 bit. This is why target drivers
4417 * also use right shifted status byte definitions. For
4418 * instance target drivers use CHECK_CONDITION, defined to
4419 * 0x1, instead of the SCSI defined check condition value
4420 * of 0x2. Host drivers are supposed to return the status
4421 * byte as it is defined by SCSI.
4422 */
4423 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4424 STATUS_BYTE(scsiqp->scsi_status);
4425 } else {
4426 scp->result = STATUS_BYTE(scsiqp->scsi_status);
4427 }
4428 break;
4429
4430 default:
4431 /* Some other QHSTA error occurred. */
4432 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
4433 scsiqp->host_status);
4434 scp->result = HOST_BYTE(DID_BAD_TARGET);
4435 break;
4436 }
4437 break;
4438
4439 case QD_ABORTED_BY_HOST:
4440 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
4441 scp->result =
4442 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
4443 break;
4444
4445 default:
4446 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
4447 scsiqp->done_status);
4448 scp->result =
4449 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
4450 break;
4451 }
1da177e4 4452
27c868c2
MW
4453 /*
4454 * If the 'init_tidmask' bit isn't already set for the target and the
4455 * current request finished normally, then set the bit for the target
4456 * to indicate that a device is present.
4457 */
4458 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4459 scsiqp->done_status == QD_NO_ERROR &&
4460 scsiqp->host_status == QHSTA_NO_ERROR) {
4461 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4462 }
1da177e4 4463
6ed1ef07 4464 asc_scsi_done(scp);
27c868c2
MW
4465
4466 /*
4467 * Free all 'adv_sgblk_t' structures allocated for the request.
4468 */
4469 while ((sgblkp = reqp->sgblkp) != NULL) {
4470 /* Remove 'sgblkp' from the request list. */
4471 reqp->sgblkp = sgblkp->next_sgblkp;
4472
4473 /* Add 'sgblkp' to the board free list. */
4474 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4475 boardp->adv_sgblkp = sgblkp;
4476 }
1da177e4 4477
27c868c2
MW
4478 /*
4479 * Free the adv_req_t structure used with the command by adding
4480 * it back to the board free list.
4481 */
4482 reqp->next_reqp = boardp->adv_reqp;
4483 boardp->adv_reqp = reqp;
1da177e4 4484
27c868c2 4485 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 4486
27c868c2 4487 return;
1da177e4
LT
4488}
4489
4490/*
4491 * adv_async_callback() - Adv Library asynchronous event callback function.
4492 */
27c868c2 4493static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 4494{
27c868c2
MW
4495 switch (code) {
4496 case ADV_ASYNC_SCSI_BUS_RESET_DET:
4497 /*
4498 * The firmware detected a SCSI Bus reset.
4499 */
4500 ASC_DBG(0,
4501 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
4502 break;
4503
4504 case ADV_ASYNC_RDMA_FAILURE:
4505 /*
4506 * Handle RDMA failure by resetting the SCSI Bus and
4507 * possibly the chip if it is unresponsive. Log the error
4508 * with a unique code.
4509 */
4510 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
4511 AdvResetChipAndSB(adv_dvc_varp);
4512 break;
4513
4514 case ADV_HOST_SCSI_BUS_RESET:
4515 /*
4516 * Host generated SCSI bus reset occurred.
4517 */
4518 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
4519 break;
4520
4521 default:
4522 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
4523 break;
4524 }
1da177e4
LT
4525}
4526
1da177e4
LT
4527#ifdef CONFIG_PROC_FS
4528/*
4529 * asc_prt_board_devices()
4530 *
4531 * Print driver information for devices attached to the board.
4532 *
4533 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4534 * cf. asc_prt_line().
4535 *
4536 * Return the number of characters copied into 'cp'. No more than
4537 * 'cplen' characters will be copied to 'cp'.
4538 */
27c868c2 4539static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4540{
27c868c2
MW
4541 asc_board_t *boardp;
4542 int leftlen;
4543 int totlen;
4544 int len;
4545 int chip_scsi_id;
4546 int i;
4547
4548 boardp = ASC_BOARDP(shost);
4549 leftlen = cplen;
4550 totlen = len = 0;
4551
4552 len = asc_prt_line(cp, leftlen,
4553 "\nDevice Information for AdvanSys SCSI Host %d:\n",
4554 shost->host_no);
4555 ASC_PRT_NEXT();
4556
4557 if (ASC_NARROW_BOARD(boardp)) {
4558 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
4559 } else {
4560 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
4561 }
1da177e4 4562
27c868c2
MW
4563 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
4564 ASC_PRT_NEXT();
4565 for (i = 0; i <= ADV_MAX_TID; i++) {
4566 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
4567 len = asc_prt_line(cp, leftlen, " %X,", i);
4568 ASC_PRT_NEXT();
4569 }
4570 }
4571 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
4572 ASC_PRT_NEXT();
1da177e4 4573
27c868c2 4574 return totlen;
1da177e4
LT
4575}
4576
4577/*
4578 * Display Wide Board BIOS Information.
4579 */
27c868c2 4580static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4581{
27c868c2
MW
4582 asc_board_t *boardp;
4583 int leftlen;
4584 int totlen;
4585 int len;
4586 ushort major, minor, letter;
4587
4588 boardp = ASC_BOARDP(shost);
4589 leftlen = cplen;
4590 totlen = len = 0;
4591
4592 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
4593 ASC_PRT_NEXT();
4594
4595 /*
4596 * If the BIOS saved a valid signature, then fill in
4597 * the BIOS code segment base address.
4598 */
4599 if (boardp->bios_signature != 0x55AA) {
4600 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
4601 ASC_PRT_NEXT();
4602 len = asc_prt_line(cp, leftlen,
4603 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
4604 ASC_PRT_NEXT();
4605 len = asc_prt_line(cp, leftlen,
4606 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
4607 ASC_PRT_NEXT();
4608 } else {
4609 major = (boardp->bios_version >> 12) & 0xF;
4610 minor = (boardp->bios_version >> 8) & 0xF;
4611 letter = (boardp->bios_version & 0xFF);
1da177e4 4612
27c868c2
MW
4613 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
4614 major, minor,
4615 letter >= 26 ? '?' : letter + 'A');
4616 ASC_PRT_NEXT();
1da177e4 4617
27c868c2
MW
4618 /*
4619 * Current available ROM BIOS release is 3.1I for UW
4620 * and 3.2I for U2W. This code doesn't differentiate
4621 * UW and U2W boards.
4622 */
4623 if (major < 3 || (major <= 3 && minor < 1) ||
4624 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
4625 len = asc_prt_line(cp, leftlen,
4626 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
4627 ASC_PRT_NEXT();
4628 len = asc_prt_line(cp, leftlen,
4629 "ftp://ftp.connectcom.net/pub\n");
4630 ASC_PRT_NEXT();
4631 }
4632 }
1da177e4 4633
27c868c2 4634 return totlen;
1da177e4
LT
4635}
4636
4637/*
4638 * Add serial number to information bar if signature AAh
4639 * is found in at bit 15-9 (7 bits) of word 1.
4640 *
4641 * Serial Number consists fo 12 alpha-numeric digits.
4642 *
4643 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
4644 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
4645 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
4646 * 5 - Product revision (A-J) Word0: " "
4647 *
4648 * Signature Word1: 15-9 (7 bits)
4649 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
4650 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
4651 *
4652 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
4653 *
4654 * Note 1: Only production cards will have a serial number.
4655 *
4656 * Note 2: Signature is most significant 7 bits (0xFE).
4657 *
4658 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
4659 */
27c868c2 4660static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 4661{
27c868c2
MW
4662 ushort w, num;
4663
4664 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
4665 return ASC_FALSE;
4666 } else {
4667 /*
4668 * First word - 6 digits.
4669 */
4670 w = serialnum[0];
4671
4672 /* Product type - 1st digit. */
4673 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
4674 /* Product type is P=Prototype */
4675 *cp += 0x8;
4676 }
4677 cp++;
4678
4679 /* Manufacturing location - 2nd digit. */
4680 *cp++ = 'A' + ((w & 0x1C00) >> 10);
4681
4682 /* Product ID - 3rd, 4th digits. */
4683 num = w & 0x3FF;
4684 *cp++ = '0' + (num / 100);
4685 num %= 100;
4686 *cp++ = '0' + (num / 10);
4687
4688 /* Product revision - 5th digit. */
4689 *cp++ = 'A' + (num % 10);
4690
4691 /*
4692 * Second word
4693 */
4694 w = serialnum[1];
4695
4696 /*
4697 * Year - 6th digit.
4698 *
4699 * If bit 15 of third word is set, then the
4700 * last digit of the year is greater than 7.
4701 */
4702 if (serialnum[2] & 0x8000) {
4703 *cp++ = '8' + ((w & 0x1C0) >> 6);
4704 } else {
4705 *cp++ = '0' + ((w & 0x1C0) >> 6);
4706 }
4707
4708 /* Week of year - 7th, 8th digits. */
4709 num = w & 0x003F;
4710 *cp++ = '0' + num / 10;
4711 num %= 10;
4712 *cp++ = '0' + num;
4713
4714 /*
4715 * Third word
4716 */
4717 w = serialnum[2] & 0x7FFF;
4718
4719 /* Serial number - 9th digit. */
4720 *cp++ = 'A' + (w / 1000);
4721
4722 /* 10th, 11th, 12th digits. */
4723 num = w % 1000;
4724 *cp++ = '0' + num / 100;
4725 num %= 100;
4726 *cp++ = '0' + num / 10;
4727 num %= 10;
4728 *cp++ = '0' + num;
4729
4730 *cp = '\0'; /* Null Terminate the string. */
4731 return ASC_TRUE;
4732 }
1da177e4
LT
4733}
4734
4735/*
4736 * asc_prt_asc_board_eeprom()
4737 *
4738 * Print board EEPROM configuration.
4739 *
4740 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4741 * cf. asc_prt_line().
4742 *
4743 * Return the number of characters copied into 'cp'. No more than
4744 * 'cplen' characters will be copied to 'cp'.
4745 */
27c868c2 4746static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4747{
27c868c2
MW
4748 asc_board_t *boardp;
4749 ASC_DVC_VAR *asc_dvc_varp;
4750 int leftlen;
4751 int totlen;
4752 int len;
4753 ASCEEP_CONFIG *ep;
4754 int i;
1da177e4 4755#ifdef CONFIG_ISA
27c868c2 4756 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 4757#endif /* CONFIG_ISA */
27c868c2
MW
4758 uchar serialstr[13];
4759
4760 boardp = ASC_BOARDP(shost);
4761 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4762 ep = &boardp->eep_config.asc_eep;
4763
4764 leftlen = cplen;
4765 totlen = len = 0;
4766
4767 len = asc_prt_line(cp, leftlen,
4768 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
4769 shost->host_no);
4770 ASC_PRT_NEXT();
4771
4772 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
4773 == ASC_TRUE) {
4774 len =
4775 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
4776 serialstr);
4777 ASC_PRT_NEXT();
4778 } else {
4779 if (ep->adapter_info[5] == 0xBB) {
4780 len = asc_prt_line(cp, leftlen,
4781 " Default Settings Used for EEPROM-less Adapter.\n");
4782 ASC_PRT_NEXT();
4783 } else {
4784 len = asc_prt_line(cp, leftlen,
4785 " Serial Number Signature Not Present.\n");
4786 ASC_PRT_NEXT();
4787 }
4788 }
1da177e4 4789
27c868c2
MW
4790 len = asc_prt_line(cp, leftlen,
4791 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4792 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
4793 ep->max_tag_qng);
4794 ASC_PRT_NEXT();
4795
4796 len = asc_prt_line(cp, leftlen,
4797 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
4798 ASC_PRT_NEXT();
4799
4800 len = asc_prt_line(cp, leftlen, " Target ID: ");
4801 ASC_PRT_NEXT();
4802 for (i = 0; i <= ASC_MAX_TID; i++) {
4803 len = asc_prt_line(cp, leftlen, " %d", i);
4804 ASC_PRT_NEXT();
4805 }
4806 len = asc_prt_line(cp, leftlen, "\n");
4807 ASC_PRT_NEXT();
4808
4809 len = asc_prt_line(cp, leftlen, " Disconnects: ");
4810 ASC_PRT_NEXT();
4811 for (i = 0; i <= ASC_MAX_TID; i++) {
4812 len = asc_prt_line(cp, leftlen, " %c",
4813 (ep->
4814 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4815 'N');
4816 ASC_PRT_NEXT();
4817 }
4818 len = asc_prt_line(cp, leftlen, "\n");
4819 ASC_PRT_NEXT();
4820
4821 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
4822 ASC_PRT_NEXT();
4823 for (i = 0; i <= ASC_MAX_TID; i++) {
4824 len = asc_prt_line(cp, leftlen, " %c",
4825 (ep->
4826 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4827 'N');
4828 ASC_PRT_NEXT();
4829 }
4830 len = asc_prt_line(cp, leftlen, "\n");
4831 ASC_PRT_NEXT();
4832
4833 len = asc_prt_line(cp, leftlen, " Start Motor: ");
4834 ASC_PRT_NEXT();
4835 for (i = 0; i <= ASC_MAX_TID; i++) {
4836 len = asc_prt_line(cp, leftlen, " %c",
4837 (ep->
4838 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4839 'N');
4840 ASC_PRT_NEXT();
4841 }
4842 len = asc_prt_line(cp, leftlen, "\n");
4843 ASC_PRT_NEXT();
4844
4845 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
4846 ASC_PRT_NEXT();
4847 for (i = 0; i <= ASC_MAX_TID; i++) {
4848 len = asc_prt_line(cp, leftlen, " %c",
4849 (ep->
4850 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4851 'N');
4852 ASC_PRT_NEXT();
4853 }
4854 len = asc_prt_line(cp, leftlen, "\n");
4855 ASC_PRT_NEXT();
1da177e4
LT
4856
4857#ifdef CONFIG_ISA
27c868c2
MW
4858 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4859 len = asc_prt_line(cp, leftlen,
4860 " Host ISA DMA speed: %d MB/S\n",
4861 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
4862 ASC_PRT_NEXT();
4863 }
1da177e4
LT
4864#endif /* CONFIG_ISA */
4865
27c868c2 4866 return totlen;
1da177e4
LT
4867}
4868
4869/*
4870 * asc_prt_adv_board_eeprom()
4871 *
4872 * Print board EEPROM configuration.
4873 *
4874 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4875 * cf. asc_prt_line().
4876 *
4877 * Return the number of characters copied into 'cp'. No more than
4878 * 'cplen' characters will be copied to 'cp'.
4879 */
27c868c2 4880static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4881{
27c868c2
MW
4882 asc_board_t *boardp;
4883 ADV_DVC_VAR *adv_dvc_varp;
4884 int leftlen;
4885 int totlen;
4886 int len;
4887 int i;
4888 char *termstr;
4889 uchar serialstr[13];
4890 ADVEEP_3550_CONFIG *ep_3550 = NULL;
4891 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
4892 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
4893 ushort word;
4894 ushort *wordp;
4895 ushort sdtr_speed = 0;
4896
4897 boardp = ASC_BOARDP(shost);
4898 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4899 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4900 ep_3550 = &boardp->eep_config.adv_3550_eep;
4901 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4902 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4903 } else {
4904 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4905 }
1da177e4 4906
27c868c2
MW
4907 leftlen = cplen;
4908 totlen = len = 0;
1da177e4 4909
27c868c2
MW
4910 len = asc_prt_line(cp, leftlen,
4911 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
4912 shost->host_no);
4913 ASC_PRT_NEXT();
1da177e4 4914
27c868c2
MW
4915 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4916 wordp = &ep_3550->serial_number_word1;
4917 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4918 wordp = &ep_38C0800->serial_number_word1;
4919 } else {
4920 wordp = &ep_38C1600->serial_number_word1;
4921 }
1da177e4 4922
27c868c2
MW
4923 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
4924 len =
4925 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
4926 serialstr);
4927 ASC_PRT_NEXT();
4928 } else {
4929 len = asc_prt_line(cp, leftlen,
4930 " Serial Number Signature Not Present.\n");
4931 ASC_PRT_NEXT();
4932 }
1da177e4 4933
27c868c2
MW
4934 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4935 len = asc_prt_line(cp, leftlen,
4936 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4937 ep_3550->adapter_scsi_id,
4938 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
4939 ASC_PRT_NEXT();
4940 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4941 len = asc_prt_line(cp, leftlen,
4942 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4943 ep_38C0800->adapter_scsi_id,
4944 ep_38C0800->max_host_qng,
4945 ep_38C0800->max_dvc_qng);
4946 ASC_PRT_NEXT();
4947 } else {
4948 len = asc_prt_line(cp, leftlen,
4949 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4950 ep_38C1600->adapter_scsi_id,
4951 ep_38C1600->max_host_qng,
4952 ep_38C1600->max_dvc_qng);
4953 ASC_PRT_NEXT();
4954 }
4955 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4956 word = ep_3550->termination;
4957 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4958 word = ep_38C0800->termination_lvd;
4959 } else {
4960 word = ep_38C1600->termination_lvd;
4961 }
4962 switch (word) {
4963 case 1:
4964 termstr = "Low Off/High Off";
4965 break;
4966 case 2:
4967 termstr = "Low Off/High On";
4968 break;
4969 case 3:
4970 termstr = "Low On/High On";
4971 break;
4972 default:
4973 case 0:
4974 termstr = "Automatic";
4975 break;
4976 }
1da177e4 4977
27c868c2
MW
4978 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4979 len = asc_prt_line(cp, leftlen,
4980 " termination: %u (%s), bios_ctrl: 0x%x\n",
4981 ep_3550->termination, termstr,
4982 ep_3550->bios_ctrl);
4983 ASC_PRT_NEXT();
4984 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4985 len = asc_prt_line(cp, leftlen,
4986 " termination: %u (%s), bios_ctrl: 0x%x\n",
4987 ep_38C0800->termination_lvd, termstr,
4988 ep_38C0800->bios_ctrl);
4989 ASC_PRT_NEXT();
4990 } else {
4991 len = asc_prt_line(cp, leftlen,
4992 " termination: %u (%s), bios_ctrl: 0x%x\n",
4993 ep_38C1600->termination_lvd, termstr,
4994 ep_38C1600->bios_ctrl);
4995 ASC_PRT_NEXT();
4996 }
1da177e4 4997
27c868c2
MW
4998 len = asc_prt_line(cp, leftlen, " Target ID: ");
4999 ASC_PRT_NEXT();
5000 for (i = 0; i <= ADV_MAX_TID; i++) {
5001 len = asc_prt_line(cp, leftlen, " %X", i);
5002 ASC_PRT_NEXT();
5003 }
5004 len = asc_prt_line(cp, leftlen, "\n");
5005 ASC_PRT_NEXT();
1da177e4 5006
27c868c2
MW
5007 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5008 word = ep_3550->disc_enable;
5009 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5010 word = ep_38C0800->disc_enable;
5011 } else {
5012 word = ep_38C1600->disc_enable;
5013 }
5014 len = asc_prt_line(cp, leftlen, " Disconnects: ");
5015 ASC_PRT_NEXT();
5016 for (i = 0; i <= ADV_MAX_TID; i++) {
5017 len = asc_prt_line(cp, leftlen, " %c",
5018 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5019 ASC_PRT_NEXT();
5020 }
5021 len = asc_prt_line(cp, leftlen, "\n");
5022 ASC_PRT_NEXT();
1da177e4 5023
27c868c2
MW
5024 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5025 word = ep_3550->tagqng_able;
5026 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5027 word = ep_38C0800->tagqng_able;
5028 } else {
5029 word = ep_38C1600->tagqng_able;
5030 }
5031 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
5032 ASC_PRT_NEXT();
5033 for (i = 0; i <= ADV_MAX_TID; i++) {
5034 len = asc_prt_line(cp, leftlen, " %c",
5035 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5036 ASC_PRT_NEXT();
5037 }
5038 len = asc_prt_line(cp, leftlen, "\n");
5039 ASC_PRT_NEXT();
5040
5041 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5042 word = ep_3550->start_motor;
5043 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5044 word = ep_38C0800->start_motor;
5045 } else {
5046 word = ep_38C1600->start_motor;
5047 }
5048 len = asc_prt_line(cp, leftlen, " Start Motor: ");
5049 ASC_PRT_NEXT();
5050 for (i = 0; i <= ADV_MAX_TID; i++) {
5051 len = asc_prt_line(cp, leftlen, " %c",
5052 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5053 ASC_PRT_NEXT();
5054 }
5055 len = asc_prt_line(cp, leftlen, "\n");
5056 ASC_PRT_NEXT();
5057
5058 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5059 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5060 ASC_PRT_NEXT();
5061 for (i = 0; i <= ADV_MAX_TID; i++) {
5062 len = asc_prt_line(cp, leftlen, " %c",
5063 (ep_3550->
5064 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
5065 'Y' : 'N');
5066 ASC_PRT_NEXT();
5067 }
5068 len = asc_prt_line(cp, leftlen, "\n");
5069 ASC_PRT_NEXT();
5070 }
5071
5072 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5073 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
5074 ASC_PRT_NEXT();
5075 for (i = 0; i <= ADV_MAX_TID; i++) {
5076 len = asc_prt_line(cp, leftlen, " %c",
5077 (ep_3550->
5078 ultra_able & ADV_TID_TO_TIDMASK(i))
5079 ? 'Y' : 'N');
5080 ASC_PRT_NEXT();
5081 }
5082 len = asc_prt_line(cp, leftlen, "\n");
5083 ASC_PRT_NEXT();
5084 }
5085
5086 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5087 word = ep_3550->wdtr_able;
5088 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5089 word = ep_38C0800->wdtr_able;
5090 } else {
5091 word = ep_38C1600->wdtr_able;
5092 }
5093 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
5094 ASC_PRT_NEXT();
5095 for (i = 0; i <= ADV_MAX_TID; i++) {
5096 len = asc_prt_line(cp, leftlen, " %c",
5097 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5098 ASC_PRT_NEXT();
5099 }
5100 len = asc_prt_line(cp, leftlen, "\n");
5101 ASC_PRT_NEXT();
5102
5103 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
5104 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
5105 len = asc_prt_line(cp, leftlen,
5106 " Synchronous Transfer Speed (Mhz):\n ");
5107 ASC_PRT_NEXT();
5108 for (i = 0; i <= ADV_MAX_TID; i++) {
5109 char *speed_str;
5110
5111 if (i == 0) {
5112 sdtr_speed = adv_dvc_varp->sdtr_speed1;
5113 } else if (i == 4) {
5114 sdtr_speed = adv_dvc_varp->sdtr_speed2;
5115 } else if (i == 8) {
5116 sdtr_speed = adv_dvc_varp->sdtr_speed3;
5117 } else if (i == 12) {
5118 sdtr_speed = adv_dvc_varp->sdtr_speed4;
5119 }
5120 switch (sdtr_speed & ADV_MAX_TID) {
5121 case 0:
5122 speed_str = "Off";
5123 break;
5124 case 1:
5125 speed_str = " 5";
5126 break;
5127 case 2:
5128 speed_str = " 10";
5129 break;
5130 case 3:
5131 speed_str = " 20";
5132 break;
5133 case 4:
5134 speed_str = " 40";
5135 break;
5136 case 5:
5137 speed_str = " 80";
5138 break;
5139 default:
5140 speed_str = "Unk";
5141 break;
5142 }
5143 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
5144 ASC_PRT_NEXT();
5145 if (i == 7) {
5146 len = asc_prt_line(cp, leftlen, "\n ");
5147 ASC_PRT_NEXT();
5148 }
5149 sdtr_speed >>= 4;
5150 }
5151 len = asc_prt_line(cp, leftlen, "\n");
5152 ASC_PRT_NEXT();
5153 }
5154
5155 return totlen;
5156}
5157
5158/*
5159 * asc_prt_driver_conf()
5160 *
5161 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5162 * cf. asc_prt_line().
1da177e4
LT
5163 *
5164 * Return the number of characters copied into 'cp'. No more than
5165 * 'cplen' characters will be copied to 'cp'.
5166 */
27c868c2 5167static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5168{
27c868c2
MW
5169 asc_board_t *boardp;
5170 int leftlen;
5171 int totlen;
5172 int len;
5173 int chip_scsi_id;
5174
5175 boardp = ASC_BOARDP(shost);
5176
5177 leftlen = cplen;
5178 totlen = len = 0;
5179
5180 len = asc_prt_line(cp, leftlen,
5181 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
5182 shost->host_no);
5183 ASC_PRT_NEXT();
5184
5185 len = asc_prt_line(cp, leftlen,
5186 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
5187 shost->host_busy, shost->last_reset, shost->max_id,
5188 shost->max_lun, shost->max_channel);
5189 ASC_PRT_NEXT();
5190
5191 len = asc_prt_line(cp, leftlen,
5192 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
5193 shost->unique_id, shost->can_queue, shost->this_id,
5194 shost->sg_tablesize, shost->cmd_per_lun);
5195 ASC_PRT_NEXT();
5196
5197 len = asc_prt_line(cp, leftlen,
5198 " unchecked_isa_dma %d, use_clustering %d\n",
5199 shost->unchecked_isa_dma, shost->use_clustering);
5200 ASC_PRT_NEXT();
5201
5202 len = asc_prt_line(cp, leftlen,
5203 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
5204 boardp->flags, boardp->last_reset, jiffies,
5205 boardp->asc_n_io_port);
5206 ASC_PRT_NEXT();
5207
4a2d31c8 5208 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
27c868c2
MW
5209 ASC_PRT_NEXT();
5210
5211 if (ASC_NARROW_BOARD(boardp)) {
5212 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
5213 } else {
5214 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
5215 }
1da177e4 5216
27c868c2 5217 return totlen;
1da177e4
LT
5218}
5219
5220/*
5221 * asc_prt_asc_board_info()
5222 *
5223 * Print dynamic board configuration information.
5224 *
5225 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5226 * cf. asc_prt_line().
5227 *
5228 * Return the number of characters copied into 'cp'. No more than
5229 * 'cplen' characters will be copied to 'cp'.
5230 */
27c868c2 5231static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5232{
27c868c2
MW
5233 asc_board_t *boardp;
5234 int chip_scsi_id;
5235 int leftlen;
5236 int totlen;
5237 int len;
5238 ASC_DVC_VAR *v;
5239 ASC_DVC_CFG *c;
5240 int i;
5241 int renegotiate = 0;
5242
5243 boardp = ASC_BOARDP(shost);
5244 v = &boardp->dvc_var.asc_dvc_var;
5245 c = &boardp->dvc_cfg.asc_dvc_cfg;
5246 chip_scsi_id = c->chip_scsi_id;
5247
5248 leftlen = cplen;
5249 totlen = len = 0;
5250
5251 len = asc_prt_line(cp, leftlen,
5252 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5253 shost->host_no);
5254 ASC_PRT_NEXT();
5255
5256 len = asc_prt_line(cp, leftlen,
5257 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
5258 c->chip_version, c->lib_version, c->lib_serial_no,
5259 c->mcode_date);
5260 ASC_PRT_NEXT();
5261
5262 len = asc_prt_line(cp, leftlen,
5263 " mcode_version 0x%x, err_code %u\n",
5264 c->mcode_version, v->err_code);
5265 ASC_PRT_NEXT();
5266
5267 /* Current number of commands waiting for the host. */
5268 len = asc_prt_line(cp, leftlen,
5269 " Total Command Pending: %d\n", v->cur_total_qng);
5270 ASC_PRT_NEXT();
5271
5272 len = asc_prt_line(cp, leftlen, " Command Queuing:");
5273 ASC_PRT_NEXT();
5274 for (i = 0; i <= ASC_MAX_TID; i++) {
5275 if ((chip_scsi_id == i) ||
5276 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5277 continue;
5278 }
5279 len = asc_prt_line(cp, leftlen, " %X:%c",
5280 i,
5281 (v->
5282 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
5283 'Y' : 'N');
5284 ASC_PRT_NEXT();
5285 }
5286 len = asc_prt_line(cp, leftlen, "\n");
5287 ASC_PRT_NEXT();
5288
5289 /* Current number of commands waiting for a device. */
5290 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
5291 ASC_PRT_NEXT();
5292 for (i = 0; i <= ASC_MAX_TID; i++) {
5293 if ((chip_scsi_id == i) ||
5294 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5295 continue;
5296 }
5297 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
5298 ASC_PRT_NEXT();
5299 }
5300 len = asc_prt_line(cp, leftlen, "\n");
5301 ASC_PRT_NEXT();
5302
5303 /* Current limit on number of commands that can be sent to a device. */
5304 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
5305 ASC_PRT_NEXT();
5306 for (i = 0; i <= ASC_MAX_TID; i++) {
5307 if ((chip_scsi_id == i) ||
5308 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5309 continue;
5310 }
5311 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
5312 ASC_PRT_NEXT();
5313 }
5314 len = asc_prt_line(cp, leftlen, "\n");
5315 ASC_PRT_NEXT();
5316
5317 /* Indicate whether the device has returned queue full status. */
5318 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
5319 ASC_PRT_NEXT();
5320 for (i = 0; i <= ASC_MAX_TID; i++) {
5321 if ((chip_scsi_id == i) ||
5322 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5323 continue;
5324 }
5325 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
5326 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
5327 i, boardp->queue_full_cnt[i]);
5328 } else {
5329 len = asc_prt_line(cp, leftlen, " %X:N", i);
5330 }
5331 ASC_PRT_NEXT();
5332 }
5333 len = asc_prt_line(cp, leftlen, "\n");
5334 ASC_PRT_NEXT();
5335
5336 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5337 ASC_PRT_NEXT();
5338 for (i = 0; i <= ASC_MAX_TID; i++) {
5339 if ((chip_scsi_id == i) ||
5340 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5341 continue;
5342 }
5343 len = asc_prt_line(cp, leftlen, " %X:%c",
5344 i,
5345 (v->
5346 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5347 'N');
5348 ASC_PRT_NEXT();
5349 }
5350 len = asc_prt_line(cp, leftlen, "\n");
5351 ASC_PRT_NEXT();
5352
5353 for (i = 0; i <= ASC_MAX_TID; i++) {
5354 uchar syn_period_ix;
5355
5356 if ((chip_scsi_id == i) ||
5357 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
5358 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
5359 continue;
5360 }
5361
5362 len = asc_prt_line(cp, leftlen, " %X:", i);
5363 ASC_PRT_NEXT();
5364
5365 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
5366 len = asc_prt_line(cp, leftlen, " Asynchronous");
5367 ASC_PRT_NEXT();
5368 } else {
5369 syn_period_ix =
5370 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
5371 1);
5372
5373 len = asc_prt_line(cp, leftlen,
5374 " Transfer Period Factor: %d (%d.%d Mhz),",
5375 v->sdtr_period_tbl[syn_period_ix],
5376 250 /
5377 v->sdtr_period_tbl[syn_period_ix],
5378 ASC_TENTHS(250,
5379 v->
5380 sdtr_period_tbl
5381 [syn_period_ix]));
5382 ASC_PRT_NEXT();
5383
5384 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
5385 boardp->
5386 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
5387 ASC_PRT_NEXT();
5388 }
5389
5390 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5391 len = asc_prt_line(cp, leftlen, "*\n");
5392 renegotiate = 1;
5393 } else {
5394 len = asc_prt_line(cp, leftlen, "\n");
5395 }
5396 ASC_PRT_NEXT();
5397 }
1da177e4 5398
27c868c2
MW
5399 if (renegotiate) {
5400 len = asc_prt_line(cp, leftlen,
5401 " * = Re-negotiation pending before next command.\n");
5402 ASC_PRT_NEXT();
5403 }
1da177e4 5404
27c868c2 5405 return totlen;
1da177e4
LT
5406}
5407
5408/*
5409 * asc_prt_adv_board_info()
5410 *
5411 * Print dynamic board configuration information.
5412 *
5413 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5414 * cf. asc_prt_line().
5415 *
5416 * Return the number of characters copied into 'cp'. No more than
5417 * 'cplen' characters will be copied to 'cp'.
5418 */
27c868c2 5419static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5420{
27c868c2
MW
5421 asc_board_t *boardp;
5422 int leftlen;
5423 int totlen;
5424 int len;
5425 int i;
5426 ADV_DVC_VAR *v;
5427 ADV_DVC_CFG *c;
5428 AdvPortAddr iop_base;
5429 ushort chip_scsi_id;
5430 ushort lramword;
5431 uchar lrambyte;
5432 ushort tagqng_able;
5433 ushort sdtr_able, wdtr_able;
5434 ushort wdtr_done, sdtr_done;
5435 ushort period = 0;
5436 int renegotiate = 0;
5437
5438 boardp = ASC_BOARDP(shost);
5439 v = &boardp->dvc_var.adv_dvc_var;
5440 c = &boardp->dvc_cfg.adv_dvc_cfg;
5441 iop_base = v->iop_base;
5442 chip_scsi_id = v->chip_scsi_id;
5443
5444 leftlen = cplen;
5445 totlen = len = 0;
5446
5447 len = asc_prt_line(cp, leftlen,
5448 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5449 shost->host_no);
5450 ASC_PRT_NEXT();
5451
5452 len = asc_prt_line(cp, leftlen,
5453 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
5454 v->iop_base,
5455 AdvReadWordRegister(iop_base,
5456 IOPW_SCSI_CFG1) & CABLE_DETECT,
5457 v->err_code);
5458 ASC_PRT_NEXT();
5459
5460 len = asc_prt_line(cp, leftlen,
5461 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
5462 c->chip_version, c->lib_version, c->mcode_date,
5463 c->mcode_version);
5464 ASC_PRT_NEXT();
5465
5466 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5467 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
5468 ASC_PRT_NEXT();
5469 for (i = 0; i <= ADV_MAX_TID; i++) {
5470 if ((chip_scsi_id == i) ||
5471 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5472 continue;
5473 }
5474
5475 len = asc_prt_line(cp, leftlen, " %X:%c",
5476 i,
5477 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5478 'N');
5479 ASC_PRT_NEXT();
5480 }
5481 len = asc_prt_line(cp, leftlen, "\n");
5482 ASC_PRT_NEXT();
5483
5484 len = asc_prt_line(cp, leftlen, " Queue Limit:");
5485 ASC_PRT_NEXT();
5486 for (i = 0; i <= ADV_MAX_TID; i++) {
5487 if ((chip_scsi_id == i) ||
5488 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5489 continue;
5490 }
5491
5492 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
5493 lrambyte);
5494
5495 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
5496 ASC_PRT_NEXT();
5497 }
5498 len = asc_prt_line(cp, leftlen, "\n");
5499 ASC_PRT_NEXT();
5500
5501 len = asc_prt_line(cp, leftlen, " Command Pending:");
5502 ASC_PRT_NEXT();
5503 for (i = 0; i <= ADV_MAX_TID; i++) {
5504 if ((chip_scsi_id == i) ||
5505 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5506 continue;
5507 }
5508
5509 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
5510 lrambyte);
5511
5512 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
5513 ASC_PRT_NEXT();
5514 }
5515 len = asc_prt_line(cp, leftlen, "\n");
5516 ASC_PRT_NEXT();
5517
5518 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5519 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
5520 ASC_PRT_NEXT();
5521 for (i = 0; i <= ADV_MAX_TID; i++) {
5522 if ((chip_scsi_id == i) ||
5523 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5524 continue;
5525 }
5526
5527 len = asc_prt_line(cp, leftlen, " %X:%c",
5528 i,
5529 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5530 'N');
5531 ASC_PRT_NEXT();
5532 }
5533 len = asc_prt_line(cp, leftlen, "\n");
5534 ASC_PRT_NEXT();
5535
5536 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
5537 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
5538 ASC_PRT_NEXT();
5539 for (i = 0; i <= ADV_MAX_TID; i++) {
5540 if ((chip_scsi_id == i) ||
5541 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5542 continue;
5543 }
5544
5545 AdvReadWordLram(iop_base,
5546 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
5547 lramword);
5548
5549 len = asc_prt_line(cp, leftlen, " %X:%d",
5550 i, (lramword & 0x8000) ? 16 : 8);
5551 ASC_PRT_NEXT();
5552
5553 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
5554 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5555 len = asc_prt_line(cp, leftlen, "*");
5556 ASC_PRT_NEXT();
5557 renegotiate = 1;
5558 }
5559 }
5560 len = asc_prt_line(cp, leftlen, "\n");
5561 ASC_PRT_NEXT();
5562
5563 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5564 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
5565 ASC_PRT_NEXT();
5566 for (i = 0; i <= ADV_MAX_TID; i++) {
5567 if ((chip_scsi_id == i) ||
5568 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5569 continue;
5570 }
5571
5572 len = asc_prt_line(cp, leftlen, " %X:%c",
5573 i,
5574 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5575 'N');
5576 ASC_PRT_NEXT();
5577 }
5578 len = asc_prt_line(cp, leftlen, "\n");
5579 ASC_PRT_NEXT();
5580
5581 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
5582 for (i = 0; i <= ADV_MAX_TID; i++) {
5583
5584 AdvReadWordLram(iop_base,
5585 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
5586 lramword);
5587 lramword &= ~0x8000;
5588
5589 if ((chip_scsi_id == i) ||
5590 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
5591 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
5592 continue;
5593 }
5594
5595 len = asc_prt_line(cp, leftlen, " %X:", i);
5596 ASC_PRT_NEXT();
5597
5598 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
5599 len = asc_prt_line(cp, leftlen, " Asynchronous");
5600 ASC_PRT_NEXT();
5601 } else {
5602 len =
5603 asc_prt_line(cp, leftlen,
5604 " Transfer Period Factor: ");
5605 ASC_PRT_NEXT();
5606
5607 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
5608 len =
5609 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
5610 ASC_PRT_NEXT();
5611 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
5612 len =
5613 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
5614 ASC_PRT_NEXT();
5615 } else { /* 20 Mhz or below. */
5616
5617 period = (((lramword >> 8) * 25) + 50) / 4;
5618
5619 if (period == 0) { /* Should never happen. */
5620 len =
5621 asc_prt_line(cp, leftlen,
5622 "%d (? Mhz), ");
5623 ASC_PRT_NEXT();
5624 } else {
5625 len = asc_prt_line(cp, leftlen,
5626 "%d (%d.%d Mhz),",
5627 period, 250 / period,
5628 ASC_TENTHS(250,
5629 period));
5630 ASC_PRT_NEXT();
5631 }
5632 }
5633
5634 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
5635 lramword & 0x1F);
5636 ASC_PRT_NEXT();
5637 }
5638
5639 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5640 len = asc_prt_line(cp, leftlen, "*\n");
5641 renegotiate = 1;
5642 } else {
5643 len = asc_prt_line(cp, leftlen, "\n");
5644 }
5645 ASC_PRT_NEXT();
5646 }
1da177e4 5647
27c868c2
MW
5648 if (renegotiate) {
5649 len = asc_prt_line(cp, leftlen,
5650 " * = Re-negotiation pending before next command.\n");
5651 ASC_PRT_NEXT();
5652 }
1da177e4 5653
27c868c2 5654 return totlen;
1da177e4
LT
5655}
5656
5657/*
5658 * asc_proc_copy()
5659 *
5660 * Copy proc information to a read buffer taking into account the current
5661 * read offset in the file and the remaining space in the read buffer.
5662 */
27c868c2 5663static int
1da177e4 5664asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 5665 char *cp, int cplen)
1da177e4 5666{
27c868c2
MW
5667 int cnt = 0;
5668
5669 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
5670 (unsigned)offset, (unsigned)advoffset, cplen);
5671 if (offset <= advoffset) {
5672 /* Read offset below current offset, copy everything. */
5673 cnt = min(cplen, leftlen);
5674 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
5675 (ulong)curbuf, (ulong)cp, cnt);
5676 memcpy(curbuf, cp, cnt);
5677 } else if (offset < advoffset + cplen) {
5678 /* Read offset within current range, partial copy. */
5679 cnt = (advoffset + cplen) - offset;
5680 cp = (cp + cplen) - cnt;
5681 cnt = min(cnt, leftlen);
5682 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
5683 (ulong)curbuf, (ulong)cp, cnt);
5684 memcpy(curbuf, cp, cnt);
5685 }
5686 return cnt;
1da177e4
LT
5687}
5688
5689/*
5690 * asc_prt_line()
5691 *
5692 * If 'cp' is NULL print to the console, otherwise print to a buffer.
5693 *
5694 * Return 0 if printing to the console, otherwise return the number of
5695 * bytes written to the buffer.
5696 *
5697 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
5698 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
5699 */
27c868c2 5700static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 5701{
27c868c2
MW
5702 va_list args;
5703 int ret;
5704 char s[ASC_PRTLINE_SIZE];
5705
5706 va_start(args, fmt);
5707 ret = vsprintf(s, fmt, args);
b009bef6 5708 BUG_ON(ret >= ASC_PRTLINE_SIZE);
27c868c2
MW
5709 if (buf == NULL) {
5710 (void)printk(s);
5711 ret = 0;
5712 } else {
5713 ret = min(buflen, ret);
5714 memcpy(buf, s, ret);
5715 }
5716 va_end(args);
5717 return ret;
1da177e4
LT
5718}
5719#endif /* CONFIG_PROC_FS */
5720
1da177e4
LT
5721/*
5722 * --- Functions Required by the Asc Library
5723 */
5724
1da177e4
LT
5725/*
5726 * void
5727 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
5728 *
5729 * Calling/Exit State:
5730 * none
5731 *
5732 * Description:
5733 * Output an ASC_SCSI_Q structure to the chip
5734 */
27c868c2 5735static void
1da177e4
LT
5736DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
5737{
27c868c2
MW
5738 int i;
5739
5740 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
5741 AscSetChipLramAddr(iop_base, s_addr);
5742 for (i = 0; i < 2 * words; i += 2) {
5743 if (i == 4 || i == 20) {
5744 continue;
5745 }
5746 outpw(iop_base + IOP_RAM_DATA,
5747 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
5748 }
1da177e4
LT
5749}
5750
5751/*
5752 * void
5753 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
5754 *
5755 * Calling/Exit State:
5756 * none
5757 *
5758 * Description:
5759 * Input an ASC_QDONE_INFO structure from the chip
5760 */
27c868c2 5761static void
1da177e4
LT
5762DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
5763{
27c868c2
MW
5764 int i;
5765 ushort word;
5766
5767 AscSetChipLramAddr(iop_base, s_addr);
5768 for (i = 0; i < 2 * words; i += 2) {
5769 if (i == 10) {
5770 continue;
5771 }
5772 word = inpw(iop_base + IOP_RAM_DATA);
5773 inbuf[i] = word & 0xff;
5774 inbuf[i + 1] = (word >> 8) & 0xff;
5775 }
5776 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
5777}
5778
1da177e4
LT
5779/*
5780 * Return the BIOS address of the adapter at the specified
5781 * I/O port and with the specified bus type.
5782 */
ecec1947
MW
5783static unsigned short __devinit
5784AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
1da177e4 5785{
ecec1947
MW
5786 unsigned short cfg_lsw;
5787 unsigned short bios_addr;
27c868c2
MW
5788
5789 /*
5790 * The PCI BIOS is re-located by the motherboard BIOS. Because
5791 * of this the driver can not determine where a PCI BIOS is
5792 * loaded and executes.
5793 */
ecec1947
MW
5794 if (bus_type & ASC_IS_PCI)
5795 return 0;
5796
1da177e4 5797#ifdef CONFIG_ISA
27c868c2
MW
5798 if ((bus_type & ASC_IS_EISA) != 0) {
5799 cfg_lsw = AscGetEisaChipCfg(iop_base);
5800 cfg_lsw &= 0x000F;
ecec1947
MW
5801 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
5802 return bios_addr;
5803 }
1da177e4
LT
5804#endif /* CONFIG_ISA */
5805
27c868c2 5806 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 5807
27c868c2
MW
5808 /*
5809 * ISA PnP uses the top bit as the 32K BIOS flag
5810 */
ecec1947 5811 if (bus_type == ASC_IS_ISAPNP)
27c868c2 5812 cfg_lsw &= 0x7FFF;
ecec1947
MW
5813 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
5814 return bios_addr;
1da177e4
LT
5815}
5816
1da177e4
LT
5817/*
5818 * --- Functions Required by the Adv Library
5819 */
5820
5821/*
5822 * DvcGetPhyAddr()
5823 *
5824 * Return the physical address of 'vaddr' and set '*lenp' to the
5825 * number of physically contiguous bytes that follow 'vaddr'.
5826 * 'flag' indicates the type of structure whose physical address
5827 * is being translated.
5828 *
5829 * Note: Because Linux currently doesn't page the kernel and all
5830 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
5831 */
5832ADV_PADDR
5833DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 5834 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 5835{
27c868c2 5836 ADV_PADDR paddr;
1da177e4 5837
27c868c2 5838 paddr = virt_to_bus(vaddr);
1da177e4 5839
27c868c2
MW
5840 ASC_DBG4(4,
5841 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
5842 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
5843 (ulong)paddr);
1da177e4 5844
27c868c2 5845 return paddr;
1da177e4
LT
5846}
5847
1da177e4
LT
5848/*
5849 * --- Tracing and Debugging Functions
5850 */
5851
5852#ifdef ADVANSYS_STATS
5853#ifdef CONFIG_PROC_FS
5854/*
5855 * asc_prt_board_stats()
5856 *
5857 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5858 * cf. asc_prt_line().
5859 *
5860 * Return the number of characters copied into 'cp'. No more than
5861 * 'cplen' characters will be copied to 'cp'.
5862 */
27c868c2 5863static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5864{
27c868c2
MW
5865 int leftlen;
5866 int totlen;
5867 int len;
5868 struct asc_stats *s;
5869 asc_board_t *boardp;
1da177e4 5870
27c868c2
MW
5871 leftlen = cplen;
5872 totlen = len = 0;
5873
5874 boardp = ASC_BOARDP(shost);
5875 s = &boardp->asc_stats;
5876
5877 len = asc_prt_line(cp, leftlen,
5878 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
5879 shost->host_no);
5880 ASC_PRT_NEXT();
5881
5882 len = asc_prt_line(cp, leftlen,
5883 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
5884 s->queuecommand, s->reset, s->biosparam,
5885 s->interrupt);
5886 ASC_PRT_NEXT();
5887
5888 len = asc_prt_line(cp, leftlen,
5889 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
5890 s->callback, s->done, s->build_error,
5891 s->adv_build_noreq, s->adv_build_nosg);
5892 ASC_PRT_NEXT();
5893
5894 len = asc_prt_line(cp, leftlen,
5895 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
5896 s->exe_noerror, s->exe_busy, s->exe_error,
5897 s->exe_unknown);
5898 ASC_PRT_NEXT();
5899
5900 /*
5901 * Display data transfer statistics.
5902 */
5903 if (s->cont_cnt > 0) {
5904 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
5905 ASC_PRT_NEXT();
5906
5907 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
5908 s->cont_xfer / 2,
5909 ASC_TENTHS(s->cont_xfer, 2));
5910 ASC_PRT_NEXT();
5911
5912 /* Contiguous transfer average size */
5913 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
5914 (s->cont_xfer / 2) / s->cont_cnt,
5915 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
5916 ASC_PRT_NEXT();
5917 }
1da177e4 5918
27c868c2 5919 if (s->sg_cnt > 0) {
1da177e4 5920
27c868c2
MW
5921 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
5922 s->sg_cnt, s->sg_elem);
5923 ASC_PRT_NEXT();
1da177e4 5924
27c868c2
MW
5925 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
5926 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
5927 ASC_PRT_NEXT();
1da177e4 5928
27c868c2
MW
5929 /* Scatter gather transfer statistics */
5930 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
5931 s->sg_elem / s->sg_cnt,
5932 ASC_TENTHS(s->sg_elem, s->sg_cnt));
5933 ASC_PRT_NEXT();
1da177e4 5934
27c868c2
MW
5935 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
5936 (s->sg_xfer / 2) / s->sg_elem,
5937 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
5938 ASC_PRT_NEXT();
1da177e4 5939
27c868c2
MW
5940 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
5941 (s->sg_xfer / 2) / s->sg_cnt,
5942 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
5943 ASC_PRT_NEXT();
5944 }
1da177e4 5945
27c868c2
MW
5946 /*
5947 * Display request queuing statistics.
5948 */
5949 len = asc_prt_line(cp, leftlen,
5950 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
5951 HZ);
5952 ASC_PRT_NEXT();
1da177e4 5953
27c868c2 5954 return totlen;
1da177e4 5955}
1da177e4
LT
5956#endif /* CONFIG_PROC_FS */
5957#endif /* ADVANSYS_STATS */
5958
5959#ifdef ADVANSYS_DEBUG
5960/*
5961 * asc_prt_scsi_host()
5962 */
27c868c2 5963static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 5964{
27c868c2
MW
5965 asc_board_t *boardp;
5966
5967 boardp = ASC_BOARDP(s);
5968
5969 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
5970 printk(" host_busy %u, host_no %d, last_reset %d,\n",
5971 s->host_busy, s->host_no, (unsigned)s->last_reset);
5972
4a2d31c8
MW
5973 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
5974 (ulong)s->base, (ulong)s->io_port, s->irq);
27c868c2
MW
5975
5976 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
5977 s->dma_channel, s->this_id, s->can_queue);
5978
5979 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
5980 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
5981
5982 if (ASC_NARROW_BOARD(boardp)) {
5983 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
5984 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
5985 } else {
5986 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
5987 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
5988 }
1da177e4
LT
5989}
5990
5991/*
5992 * asc_prt_scsi_cmnd()
5993 */
27c868c2 5994static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 5995{
27c868c2 5996 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 5997
27c868c2
MW
5998 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
5999 (ulong)s->device->host, (ulong)s->device, s->device->id,
6000 s->device->lun, s->device->channel);
1da177e4 6001
27c868c2 6002 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 6003
27c868c2
MW
6004 printk("sc_data_direction %u, resid %d\n",
6005 s->sc_data_direction, s->resid);
1da177e4 6006
27c868c2 6007 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 6008
27c868c2
MW
6009 printk(" serial_number 0x%x, retries %d, allowed %d\n",
6010 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 6011
27c868c2 6012 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 6013
ecec1947
MW
6014 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
6015 s->scsi_done, s->done, s->host_scribble, s->result);
1da177e4 6016
27c868c2 6017 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
6018}
6019
6020/*
6021 * asc_prt_asc_dvc_var()
6022 */
27c868c2 6023static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 6024{
27c868c2
MW
6025 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
6026
ecec1947
MW
6027 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
6028 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
27c868c2 6029
895d6b4c
MW
6030 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
6031 (unsigned)h->init_sdtr);
27c868c2 6032
ecec1947
MW
6033 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
6034 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
6035 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
6036 (unsigned)h->chip_no);
27c868c2 6037
ecec1947
MW
6038 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
6039 "%u,\n", (unsigned)h->queue_full_or_busy,
6040 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
27c868c2 6041
ecec1947
MW
6042 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
6043 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
6044 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
6045 (unsigned)h->in_critical_cnt);
27c868c2 6046
ecec1947
MW
6047 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
6048 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
6049 (unsigned)h->init_state, (unsigned)h->no_scam,
6050 (unsigned)h->pci_fix_asyn_xfer);
27c868c2
MW
6051
6052 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
6053}
6054
6055/*
6056 * asc_prt_asc_dvc_cfg()
6057 */
27c868c2 6058static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 6059{
27c868c2
MW
6060 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
6061
6062 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
6063 h->can_tagged_qng, h->cmd_qng_enabled);
6064 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
6065 h->disc_enable, h->sdtr_enable);
6066
6067 printk
6068 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
6069 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
6070 h->chip_version);
6071
6072 printk
6073 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
6074 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
6075 h->mcode_date);
6076
6077 printk(" mcode_version %d, overrun_buf 0x%lx\n",
6078 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
6079}
6080
6081/*
6082 * asc_prt_asc_scsi_q()
6083 */
27c868c2 6084static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 6085{
27c868c2
MW
6086 ASC_SG_HEAD *sgp;
6087 int i;
6088
6089 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
6090
6091 printk
6092 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
6093 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
6094 q->q2.tag_code);
6095
6096 printk
6097 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6098 (ulong)le32_to_cpu(q->q1.data_addr),
6099 (ulong)le32_to_cpu(q->q1.data_cnt),
6100 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
6101
6102 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
6103 (ulong)q->cdbptr, q->q2.cdb_len,
6104 (ulong)q->sg_head, q->q1.sg_queue_cnt);
6105
6106 if (q->sg_head) {
6107 sgp = q->sg_head;
6108 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
6109 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
6110 sgp->queue_cnt);
6111 for (i = 0; i < sgp->entry_cnt; i++) {
6112 printk(" [%u]: addr 0x%lx, bytes %lu\n",
6113 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
6114 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
6115 }
1da177e4 6116
27c868c2 6117 }
1da177e4
LT
6118}
6119
6120/*
6121 * asc_prt_asc_qdone_info()
6122 */
27c868c2 6123static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 6124{
27c868c2
MW
6125 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
6126 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
6127 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
6128 q->d2.tag_code);
6129 printk
6130 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
6131 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
6132}
6133
6134/*
6135 * asc_prt_adv_dvc_var()
6136 *
6137 * Display an ADV_DVC_VAR structure.
6138 */
27c868c2 6139static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 6140{
27c868c2
MW
6141 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
6142
6143 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
6144 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
6145
6146 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
6147 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
6148 (unsigned)h->wdtr_able);
6149
6150 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
6151 (unsigned)h->start_motor,
6152 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
6153
6154 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
6155 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
6156 (ulong)h->carr_freelist);
6157
6158 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
6159 (ulong)h->icq_sp, (ulong)h->irq_sp);
6160
6161 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
6162 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
6163
6164 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
6165 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
6166}
6167
6168/*
6169 * asc_prt_adv_dvc_cfg()
6170 *
6171 * Display an ADV_DVC_CFG structure.
6172 */
27c868c2 6173static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 6174{
27c868c2 6175 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 6176
27c868c2
MW
6177 printk(" disc_enable 0x%x, termination 0x%x\n",
6178 h->disc_enable, h->termination);
1da177e4 6179
27c868c2
MW
6180 printk(" chip_version 0x%x, mcode_date 0x%x\n",
6181 h->chip_version, h->mcode_date);
1da177e4 6182
27c868c2
MW
6183 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
6184 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 6185
13ac2d9c 6186 printk(" control_flag 0x%x\n", h->control_flag);
1da177e4
LT
6187}
6188
6189/*
6190 * asc_prt_adv_scsi_req_q()
6191 *
6192 * Display an ADV_SCSI_REQ_Q structure.
6193 */
27c868c2 6194static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 6195{
27c868c2
MW
6196 int sg_blk_cnt;
6197 struct asc_sg_block *sg_ptr;
6198
6199 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
6200
6201 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
6202 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
6203
6204 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
6205 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
6206
6207 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6208 (ulong)le32_to_cpu(q->data_cnt),
6209 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
6210
6211 printk
6212 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
6213 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
6214
6215 printk(" sg_working_ix 0x%x, target_cmd %u\n",
6216 q->sg_working_ix, q->target_cmd);
6217
6218 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
6219 (ulong)le32_to_cpu(q->scsiq_rptr),
6220 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
6221
6222 /* Display the request's ADV_SG_BLOCK structures. */
6223 if (q->sg_list_ptr != NULL) {
6224 sg_blk_cnt = 0;
6225 while (1) {
6226 /*
6227 * 'sg_ptr' is a physical address. Convert it to a virtual
6228 * address by indexing 'sg_blk_cnt' into the virtual address
6229 * array 'sg_list_ptr'.
6230 *
6231 * XXX - Assumes all SG physical blocks are virtually contiguous.
6232 */
6233 sg_ptr =
6234 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
6235 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
6236 if (sg_ptr->sg_ptr == 0) {
6237 break;
6238 }
6239 sg_blk_cnt++;
6240 }
6241 }
1da177e4
LT
6242}
6243
6244/*
6245 * asc_prt_adv_sgblock()
6246 *
6247 * Display an ADV_SG_BLOCK structure.
6248 */
27c868c2 6249static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 6250{
27c868c2
MW
6251 int i;
6252
6253 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
6254 (ulong)b, sgblockno);
6255 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
6256 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
b009bef6
MW
6257 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
6258 if (b->sg_ptr != 0)
6259 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
27c868c2
MW
6260 for (i = 0; i < b->sg_cnt; i++) {
6261 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
6262 i, (ulong)b->sg_list[i].sg_addr,
6263 (ulong)b->sg_list[i].sg_count);
6264 }
1da177e4
LT
6265}
6266
6267/*
6268 * asc_prt_hex()
6269 *
6270 * Print hexadecimal output in 4 byte groupings 32 bytes
6271 * or 8 double-words per line.
6272 */
27c868c2 6273static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 6274{
27c868c2
MW
6275 int i;
6276 int j;
6277 int k;
6278 int m;
6279
6280 printk("%s: (%d bytes)\n", f, l);
6281
6282 for (i = 0; i < l; i += 32) {
6283
6284 /* Display a maximum of 8 double-words per line. */
6285 if ((k = (l - i) / 4) >= 8) {
6286 k = 8;
6287 m = 0;
6288 } else {
6289 m = (l - i) % 4;
6290 }
6291
6292 for (j = 0; j < k; j++) {
6293 printk(" %2.2X%2.2X%2.2X%2.2X",
6294 (unsigned)s[i + (j * 4)],
6295 (unsigned)s[i + (j * 4) + 1],
6296 (unsigned)s[i + (j * 4) + 2],
6297 (unsigned)s[i + (j * 4) + 3]);
6298 }
6299
6300 switch (m) {
6301 case 0:
6302 default:
6303 break;
6304 case 1:
6305 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
6306 break;
6307 case 2:
6308 printk(" %2.2X%2.2X",
6309 (unsigned)s[i + (j * 4)],
6310 (unsigned)s[i + (j * 4) + 1]);
6311 break;
6312 case 3:
6313 printk(" %2.2X%2.2X%2.2X",
6314 (unsigned)s[i + (j * 4) + 1],
6315 (unsigned)s[i + (j * 4) + 2],
6316 (unsigned)s[i + (j * 4) + 3]);
6317 break;
6318 }
6319
6320 printk("\n");
6321 }
1da177e4
LT
6322}
6323#endif /* ADVANSYS_DEBUG */
6324
6325/*
6326 * --- Asc Library Functions
6327 */
6328
78e77d8b 6329static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 6330{
27c868c2 6331 PortAddr eisa_cfg_iop;
1da177e4 6332
27c868c2
MW
6333 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
6334 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
6335 return (inpw(eisa_cfg_iop));
1da177e4
LT
6336}
6337
78e77d8b 6338static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 6339{
27c868c2 6340 ushort cfg_lsw;
1da177e4 6341
27c868c2
MW
6342 if (AscGetChipScsiID(iop_base) == new_host_id) {
6343 return (new_host_id);
6344 }
6345 cfg_lsw = AscGetChipCfgLsw(iop_base);
6346 cfg_lsw &= 0xF8FF;
6347 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
6348 AscSetChipCfgLsw(iop_base, cfg_lsw);
6349 return (AscGetChipScsiID(iop_base));
1da177e4
LT
6350}
6351
ecec1947 6352static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 6353{
ecec1947 6354 unsigned char sc;
1da177e4 6355
27c868c2
MW
6356 AscSetBank(iop_base, 1);
6357 sc = inp(iop_base + IOP_REG_SC);
6358 AscSetBank(iop_base, 0);
ecec1947 6359 return sc;
1da177e4
LT
6360}
6361
ecec1947
MW
6362static unsigned char __devinit
6363AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
1da177e4 6364{
ecec1947 6365 if (bus_type & ASC_IS_EISA) {
27c868c2 6366 PortAddr eisa_iop;
ecec1947 6367 unsigned char revision;
27c868c2
MW
6368 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
6369 (PortAddr) ASC_EISA_REV_IOP_MASK;
6370 revision = inp(eisa_iop);
ecec1947 6371 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
27c868c2 6372 }
ecec1947 6373 return AscGetChipVerNo(iop_base);
1da177e4
LT
6374}
6375
27c868c2
MW
6376static ASC_DCNT
6377AscLoadMicroCode(PortAddr iop_base,
6378 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 6379{
27c868c2
MW
6380 ASC_DCNT chksum;
6381 ushort mcode_word_size;
6382 ushort mcode_chksum;
6383
6384 /* Write the microcode buffer starting at LRAM address 0. */
6385 mcode_word_size = (ushort)(mcode_size >> 1);
6386 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
6387 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
6388
6389 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
6390 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
6391 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
6392 (ushort)ASC_CODE_SEC_BEG,
6393 (ushort)((mcode_size -
6394 s_addr - (ushort)
6395 ASC_CODE_SEC_BEG) /
6396 2));
6397 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
6398 (ulong)mcode_chksum);
6399 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
6400 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
6401 return (chksum);
1da177e4
LT
6402}
6403
27c868c2 6404static int AscFindSignature(PortAddr iop_base)
1da177e4 6405{
27c868c2
MW
6406 ushort sig_word;
6407
6408 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
6409 iop_base, AscGetChipSignatureByte(iop_base));
6410 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
6411 ASC_DBG2(1,
6412 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
6413 iop_base, AscGetChipSignatureWord(iop_base));
6414 sig_word = AscGetChipSignatureWord(iop_base);
6415 if ((sig_word == (ushort)ASC_1000_ID0W) ||
6416 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
6417 return (1);
6418 }
6419 }
6420 return (0);
1da177e4
LT
6421}
6422
78e77d8b 6423static void __devinit AscToggleIRQAct(PortAddr iop_base)
1da177e4 6424{
27c868c2
MW
6425 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
6426 AscSetChipStatus(iop_base, 0);
6427 return;
1da177e4
LT
6428}
6429
78e77d8b 6430static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 6431{
27c868c2
MW
6432 ushort cfg_lsw;
6433 uchar chip_irq;
6434
6435 if ((bus_type & ASC_IS_EISA) != 0) {
6436 cfg_lsw = AscGetEisaChipCfg(iop_base);
6437 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
6438 if ((chip_irq == 13) || (chip_irq > 15)) {
6439 return (0);
6440 }
6441 return (chip_irq);
6442 }
6443 if ((bus_type & ASC_IS_VL) != 0) {
6444 cfg_lsw = AscGetChipCfgLsw(iop_base);
6445 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
6446 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
6447 return (0);
6448 }
6449 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
6450 }
6451 cfg_lsw = AscGetChipCfgLsw(iop_base);
6452 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
6453 if (chip_irq == 3)
6454 chip_irq += (uchar)2;
6455 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
6456}
6457
78e77d8b 6458static uchar __devinit
27c868c2 6459AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 6460{
27c868c2
MW
6461 ushort cfg_lsw;
6462
6463 if ((bus_type & ASC_IS_VL) != 0) {
6464 if (irq_no != 0) {
6465 if ((irq_no < ASC_MIN_IRQ_NO)
6466 || (irq_no > ASC_MAX_IRQ_NO)) {
6467 irq_no = 0;
6468 } else {
6469 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
6470 }
6471 }
6472 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
6473 cfg_lsw |= (ushort)0x0010;
6474 AscSetChipCfgLsw(iop_base, cfg_lsw);
6475 AscToggleIRQAct(iop_base);
6476 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
6477 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
6478 AscSetChipCfgLsw(iop_base, cfg_lsw);
6479 AscToggleIRQAct(iop_base);
6480 return (AscGetChipIRQ(iop_base, bus_type));
6481 }
6482 if ((bus_type & (ASC_IS_ISA)) != 0) {
6483 if (irq_no == 15)
6484 irq_no -= (uchar)2;
6485 irq_no -= (uchar)ASC_MIN_IRQ_NO;
6486 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
6487 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
6488 AscSetChipCfgLsw(iop_base, cfg_lsw);
6489 return (AscGetChipIRQ(iop_base, bus_type));
6490 }
6491 return (0);
1da177e4
LT
6492}
6493
6494#ifdef CONFIG_ISA
78e77d8b 6495static void __devinit AscEnableIsaDma(uchar dma_channel)
1da177e4 6496{
27c868c2
MW
6497 if (dma_channel < 4) {
6498 outp(0x000B, (ushort)(0xC0 | dma_channel));
6499 outp(0x000A, dma_channel);
6500 } else if (dma_channel < 8) {
6501 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
6502 outp(0x00D4, (ushort)(dma_channel - 4));
6503 }
6504 return;
1da177e4
LT
6505}
6506#endif /* CONFIG_ISA */
6507
27c868c2 6508static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 6509{
27c868c2
MW
6510 EXT_MSG ext_msg;
6511 EXT_MSG out_msg;
6512 ushort halt_q_addr;
6513 int sdtr_accept;
6514 ushort int_halt_code;
6515 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6516 ASC_SCSI_BIT_ID_TYPE target_id;
6517 PortAddr iop_base;
6518 uchar tag_code;
6519 uchar q_status;
6520 uchar halt_qp;
6521 uchar sdtr_data;
6522 uchar target_ix;
6523 uchar q_cntl, tid_no;
6524 uchar cur_dvc_qng;
6525 uchar asyn_sdtr;
6526 uchar scsi_status;
6527 asc_board_t *boardp;
6528
b009bef6 6529 BUG_ON(!asc_dvc->drv_ptr);
27c868c2
MW
6530 boardp = asc_dvc->drv_ptr;
6531
6532 iop_base = asc_dvc->iop_base;
6533 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
6534
6535 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
6536 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
6537 target_ix = AscReadLramByte(iop_base,
6538 (ushort)(halt_q_addr +
6539 (ushort)ASC_SCSIQ_B_TARGET_IX));
6540 q_cntl =
6541 AscReadLramByte(iop_base,
6542 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6543 tid_no = ASC_TIX_TO_TID(target_ix);
6544 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
6545 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6546 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
6547 } else {
6548 asyn_sdtr = 0;
6549 }
6550 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
6551 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6552 AscSetChipSDTR(iop_base, 0, tid_no);
6553 boardp->sdtr_data[tid_no] = 0;
6554 }
6555 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6556 return (0);
6557 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
6558 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6559 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6560 boardp->sdtr_data[tid_no] = asyn_sdtr;
6561 }
6562 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6563 return (0);
6564 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
6565
6566 AscMemWordCopyPtrFromLram(iop_base,
6567 ASCV_MSGIN_BEG,
6568 (uchar *)&ext_msg,
6569 sizeof(EXT_MSG) >> 1);
6570
47d853cc
MW
6571 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6572 ext_msg.msg_req == EXTENDED_SDTR &&
27c868c2
MW
6573 ext_msg.msg_len == MS_SDTR_LEN) {
6574 sdtr_accept = TRUE;
6575 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
6576
6577 sdtr_accept = FALSE;
6578 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
6579 }
6580 if ((ext_msg.xfer_period <
6581 asc_dvc->sdtr_period_tbl[asc_dvc->
6582 host_init_sdtr_index])
6583 || (ext_msg.xfer_period >
6584 asc_dvc->sdtr_period_tbl[asc_dvc->
6585 max_sdtr_index])) {
6586 sdtr_accept = FALSE;
6587 ext_msg.xfer_period =
6588 asc_dvc->sdtr_period_tbl[asc_dvc->
6589 host_init_sdtr_index];
6590 }
6591 if (sdtr_accept) {
6592 sdtr_data =
6593 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
6594 ext_msg.req_ack_offset);
6595 if ((sdtr_data == 0xFF)) {
6596
6597 q_cntl |= QC_MSG_OUT;
6598 asc_dvc->init_sdtr &= ~target_id;
6599 asc_dvc->sdtr_done &= ~target_id;
6600 AscSetChipSDTR(iop_base, asyn_sdtr,
6601 tid_no);
6602 boardp->sdtr_data[tid_no] = asyn_sdtr;
6603 }
6604 }
6605 if (ext_msg.req_ack_offset == 0) {
6606
6607 q_cntl &= ~QC_MSG_OUT;
6608 asc_dvc->init_sdtr &= ~target_id;
6609 asc_dvc->sdtr_done &= ~target_id;
6610 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6611 } else {
6612 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
6613
6614 q_cntl &= ~QC_MSG_OUT;
6615 asc_dvc->sdtr_done |= target_id;
6616 asc_dvc->init_sdtr |= target_id;
6617 asc_dvc->pci_fix_asyn_xfer &=
6618 ~target_id;
6619 sdtr_data =
6620 AscCalSDTRData(asc_dvc,
6621 ext_msg.xfer_period,
6622 ext_msg.
6623 req_ack_offset);
6624 AscSetChipSDTR(iop_base, sdtr_data,
6625 tid_no);
6626 boardp->sdtr_data[tid_no] = sdtr_data;
6627 } else {
6628
6629 q_cntl |= QC_MSG_OUT;
6630 AscMsgOutSDTR(asc_dvc,
6631 ext_msg.xfer_period,
6632 ext_msg.req_ack_offset);
6633 asc_dvc->pci_fix_asyn_xfer &=
6634 ~target_id;
6635 sdtr_data =
6636 AscCalSDTRData(asc_dvc,
6637 ext_msg.xfer_period,
6638 ext_msg.
6639 req_ack_offset);
6640 AscSetChipSDTR(iop_base, sdtr_data,
6641 tid_no);
6642 boardp->sdtr_data[tid_no] = sdtr_data;
6643 asc_dvc->sdtr_done |= target_id;
6644 asc_dvc->init_sdtr |= target_id;
6645 }
6646 }
6647
6648 AscWriteLramByte(iop_base,
6649 (ushort)(halt_q_addr +
6650 (ushort)ASC_SCSIQ_B_CNTL),
6651 q_cntl);
6652 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6653 return (0);
47d853cc
MW
6654 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6655 ext_msg.msg_req == EXTENDED_WDTR &&
27c868c2
MW
6656 ext_msg.msg_len == MS_WDTR_LEN) {
6657
6658 ext_msg.wdtr_width = 0;
6659 AscMemWordCopyPtrToLram(iop_base,
6660 ASCV_MSGOUT_BEG,
6661 (uchar *)&ext_msg,
6662 sizeof(EXT_MSG) >> 1);
6663 q_cntl |= QC_MSG_OUT;
6664 AscWriteLramByte(iop_base,
6665 (ushort)(halt_q_addr +
6666 (ushort)ASC_SCSIQ_B_CNTL),
6667 q_cntl);
6668 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6669 return (0);
6670 } else {
6671
6672 ext_msg.msg_type = MESSAGE_REJECT;
6673 AscMemWordCopyPtrToLram(iop_base,
6674 ASCV_MSGOUT_BEG,
6675 (uchar *)&ext_msg,
6676 sizeof(EXT_MSG) >> 1);
6677 q_cntl |= QC_MSG_OUT;
6678 AscWriteLramByte(iop_base,
6679 (ushort)(halt_q_addr +
6680 (ushort)ASC_SCSIQ_B_CNTL),
6681 q_cntl);
6682 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6683 return (0);
6684 }
6685 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
6686
6687 q_cntl |= QC_REQ_SENSE;
6688
6689 if ((asc_dvc->init_sdtr & target_id) != 0) {
6690
6691 asc_dvc->sdtr_done &= ~target_id;
6692
6693 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
6694 q_cntl |= QC_MSG_OUT;
6695 AscMsgOutSDTR(asc_dvc,
6696 asc_dvc->
6697 sdtr_period_tbl[(sdtr_data >> 4) &
6698 (uchar)(asc_dvc->
6699 max_sdtr_index -
6700 1)],
6701 (uchar)(sdtr_data & (uchar)
6702 ASC_SYN_MAX_OFFSET));
6703 }
6704
6705 AscWriteLramByte(iop_base,
6706 (ushort)(halt_q_addr +
6707 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6708
6709 tag_code = AscReadLramByte(iop_base,
6710 (ushort)(halt_q_addr + (ushort)
6711 ASC_SCSIQ_B_TAG_CODE));
6712 tag_code &= 0xDC;
6713 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
6714 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
6715 ) {
6716
6717 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
6718 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
6719
6720 }
6721 AscWriteLramByte(iop_base,
6722 (ushort)(halt_q_addr +
6723 (ushort)ASC_SCSIQ_B_TAG_CODE),
6724 tag_code);
6725
6726 q_status = AscReadLramByte(iop_base,
6727 (ushort)(halt_q_addr + (ushort)
6728 ASC_SCSIQ_B_STATUS));
6729 q_status |= (QS_READY | QS_BUSY);
6730 AscWriteLramByte(iop_base,
6731 (ushort)(halt_q_addr +
6732 (ushort)ASC_SCSIQ_B_STATUS),
6733 q_status);
6734
6735 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
6736 scsi_busy &= ~target_id;
6737 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6738
6739 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6740 return (0);
6741 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
6742
6743 AscMemWordCopyPtrFromLram(iop_base,
6744 ASCV_MSGOUT_BEG,
6745 (uchar *)&out_msg,
6746 sizeof(EXT_MSG) >> 1);
6747
47d853cc 6748 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
27c868c2 6749 (out_msg.msg_len == MS_SDTR_LEN) &&
47d853cc 6750 (out_msg.msg_req == EXTENDED_SDTR)) {
27c868c2
MW
6751
6752 asc_dvc->init_sdtr &= ~target_id;
6753 asc_dvc->sdtr_done &= ~target_id;
6754 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6755 boardp->sdtr_data[tid_no] = asyn_sdtr;
6756 }
6757 q_cntl &= ~QC_MSG_OUT;
6758 AscWriteLramByte(iop_base,
6759 (ushort)(halt_q_addr +
6760 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6761 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6762 return (0);
6763 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
6764
6765 scsi_status = AscReadLramByte(iop_base,
6766 (ushort)((ushort)halt_q_addr +
6767 (ushort)
6768 ASC_SCSIQ_SCSI_STATUS));
6769 cur_dvc_qng =
6770 AscReadLramByte(iop_base,
6771 (ushort)((ushort)ASC_QADR_BEG +
6772 (ushort)target_ix));
6773 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
6774
6775 scsi_busy = AscReadLramByte(iop_base,
6776 (ushort)ASCV_SCSIBUSY_B);
6777 scsi_busy |= target_id;
6778 AscWriteLramByte(iop_base,
6779 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6780 asc_dvc->queue_full_or_busy |= target_id;
6781
6782 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
6783 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
6784 cur_dvc_qng -= 1;
6785 asc_dvc->max_dvc_qng[tid_no] =
6786 cur_dvc_qng;
6787
6788 AscWriteLramByte(iop_base,
6789 (ushort)((ushort)
6790 ASCV_MAX_DVC_QNG_BEG
6791 + (ushort)
6792 tid_no),
6793 cur_dvc_qng);
6794
6795 /*
6796 * Set the device queue depth to the number of
6797 * active requests when the QUEUE FULL condition
6798 * was encountered.
6799 */
6800 boardp->queue_full |= target_id;
6801 boardp->queue_full_cnt[tid_no] =
6802 cur_dvc_qng;
6803 }
6804 }
6805 }
6806 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6807 return (0);
6808 }
1da177e4 6809#if CC_VERY_LONG_SG_LIST
27c868c2
MW
6810 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
6811 uchar q_no;
6812 ushort q_addr;
6813 uchar sg_wk_q_no;
6814 uchar first_sg_wk_q_no;
6815 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
6816 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
6817 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
6818 ushort sg_list_dwords;
6819 ushort sg_entry_cnt;
6820 uchar next_qp;
6821 int i;
6822
6823 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
6824 if (q_no == ASC_QLINK_END) {
6825 return (0);
6826 }
6827
6828 q_addr = ASC_QNO_TO_QADDR(q_no);
6829
6830 /*
6831 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
6832 * structure pointer using a macro provided by the driver.
6833 * The ASC_SCSI_REQ pointer provides a pointer to the
6834 * host ASC_SG_HEAD structure.
6835 */
6836 /* Read request's SRB pointer. */
6837 scsiq = (ASC_SCSI_Q *)
6838 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
6839 (ushort)
6840 (q_addr +
6841 ASC_SCSIQ_D_SRBPTR))));
6842
6843 /*
6844 * Get request's first and working SG queue.
6845 */
6846 sg_wk_q_no = AscReadLramByte(iop_base,
6847 (ushort)(q_addr +
6848 ASC_SCSIQ_B_SG_WK_QP));
6849
6850 first_sg_wk_q_no = AscReadLramByte(iop_base,
6851 (ushort)(q_addr +
6852 ASC_SCSIQ_B_FIRST_SG_WK_QP));
6853
6854 /*
6855 * Reset request's working SG queue back to the
6856 * first SG queue.
6857 */
6858 AscWriteLramByte(iop_base,
6859 (ushort)(q_addr +
6860 (ushort)ASC_SCSIQ_B_SG_WK_QP),
6861 first_sg_wk_q_no);
6862
6863 sg_head = scsiq->sg_head;
6864
6865 /*
6866 * Set sg_entry_cnt to the number of SG elements
6867 * that will be completed on this interrupt.
6868 *
6869 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
6870 * SG elements. The data_cnt and data_addr fields which
6871 * add 1 to the SG element capacity are not used when
6872 * restarting SG handling after a halt.
6873 */
6874 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
6875 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
6876
6877 /*
6878 * Keep track of remaining number of SG elements that will
6879 * need to be handled on the next interrupt.
6880 */
6881 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
6882 } else {
6883 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
6884 scsiq->remain_sg_entry_cnt = 0;
6885 }
6886
6887 /*
6888 * Copy SG elements into the list of allocated SG queues.
6889 *
6890 * Last index completed is saved in scsiq->next_sg_index.
6891 */
6892 next_qp = first_sg_wk_q_no;
6893 q_addr = ASC_QNO_TO_QADDR(next_qp);
6894 scsi_sg_q.sg_head_qp = q_no;
6895 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
6896 for (i = 0; i < sg_head->queue_cnt; i++) {
6897 scsi_sg_q.seq_no = i + 1;
6898 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
6899 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
6900 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
6901 /*
6902 * After very first SG queue RISC FW uses next
6903 * SG queue first element then checks sg_list_cnt
6904 * against zero and then decrements, so set
6905 * sg_list_cnt 1 less than number of SG elements
6906 * in each SG queue.
6907 */
6908 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
6909 scsi_sg_q.sg_cur_list_cnt =
6910 ASC_SG_LIST_PER_Q - 1;
6911 } else {
6912 /*
6913 * This is the last SG queue in the list of
6914 * allocated SG queues. If there are more
6915 * SG elements than will fit in the allocated
6916 * queues, then set the QCSG_SG_XFER_MORE flag.
6917 */
6918 if (scsiq->remain_sg_entry_cnt != 0) {
6919 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
6920 } else {
6921 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
6922 }
6923 /* equals sg_entry_cnt * 2 */
6924 sg_list_dwords = sg_entry_cnt << 1;
6925 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
6926 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
6927 sg_entry_cnt = 0;
6928 }
6929
6930 scsi_sg_q.q_no = next_qp;
6931 AscMemWordCopyPtrToLram(iop_base,
6932 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
6933 (uchar *)&scsi_sg_q,
6934 sizeof(ASC_SG_LIST_Q) >> 1);
6935
6936 AscMemDWordCopyPtrToLram(iop_base,
6937 q_addr + ASC_SGQ_LIST_BEG,
6938 (uchar *)&sg_head->
6939 sg_list[scsiq->next_sg_index],
6940 sg_list_dwords);
6941
6942 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
6943
6944 /*
6945 * If the just completed SG queue contained the
6946 * last SG element, then no more SG queues need
6947 * to be written.
6948 */
6949 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
6950 break;
6951 }
6952
6953 next_qp = AscReadLramByte(iop_base,
6954 (ushort)(q_addr +
6955 ASC_SCSIQ_B_FWD));
6956 q_addr = ASC_QNO_TO_QADDR(next_qp);
6957 }
6958
6959 /*
6960 * Clear the halt condition so the RISC will be restarted
6961 * after the return.
6962 */
6963 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6964 return (0);
6965 }
1da177e4 6966#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 6967 return (0);
1da177e4
LT
6968}
6969
27c868c2
MW
6970static uchar
6971_AscCopyLramScsiDoneQ(PortAddr iop_base,
6972 ushort q_addr,
6973 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 6974{
27c868c2
MW
6975 ushort _val;
6976 uchar sg_queue_cnt;
6977
6978 DvcGetQinfo(iop_base,
6979 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
6980 (uchar *)scsiq,
6981 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
6982
6983 _val = AscReadLramWord(iop_base,
6984 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
6985 scsiq->q_status = (uchar)_val;
6986 scsiq->q_no = (uchar)(_val >> 8);
6987 _val = AscReadLramWord(iop_base,
6988 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6989 scsiq->cntl = (uchar)_val;
6990 sg_queue_cnt = (uchar)(_val >> 8);
6991 _val = AscReadLramWord(iop_base,
6992 (ushort)(q_addr +
6993 (ushort)ASC_SCSIQ_B_SENSE_LEN));
6994 scsiq->sense_len = (uchar)_val;
6995 scsiq->extra_bytes = (uchar)(_val >> 8);
6996
6997 /*
6998 * Read high word of remain bytes from alternate location.
6999 */
7000 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
7001 (ushort)(q_addr +
7002 (ushort)
7003 ASC_SCSIQ_W_ALT_DC1)))
7004 << 16);
7005 /*
7006 * Read low word of remain bytes from original location.
7007 */
7008 scsiq->remain_bytes += AscReadLramWord(iop_base,
7009 (ushort)(q_addr + (ushort)
7010 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
7011
7012 scsiq->remain_bytes &= max_dma_count;
7013 return (sg_queue_cnt);
1da177e4
LT
7014}
7015
27c868c2 7016static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 7017{
27c868c2
MW
7018 uchar next_qp;
7019 uchar n_q_used;
7020 uchar sg_list_qp;
7021 uchar sg_queue_cnt;
7022 uchar q_cnt;
7023 uchar done_q_tail;
7024 uchar tid_no;
7025 ASC_SCSI_BIT_ID_TYPE scsi_busy;
7026 ASC_SCSI_BIT_ID_TYPE target_id;
7027 PortAddr iop_base;
7028 ushort q_addr;
7029 ushort sg_q_addr;
7030 uchar cur_target_qng;
7031 ASC_QDONE_INFO scsiq_buf;
7032 ASC_QDONE_INFO *scsiq;
7033 int false_overrun;
27c868c2
MW
7034
7035 iop_base = asc_dvc->iop_base;
27c868c2
MW
7036 n_q_used = 1;
7037 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
7038 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
7039 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
7040 next_qp = AscReadLramByte(iop_base,
7041 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
7042 if (next_qp != ASC_QLINK_END) {
7043 AscPutVarDoneQTail(iop_base, next_qp);
7044 q_addr = ASC_QNO_TO_QADDR(next_qp);
7045 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
7046 asc_dvc->max_dma_count);
7047 AscWriteLramByte(iop_base,
7048 (ushort)(q_addr +
7049 (ushort)ASC_SCSIQ_B_STATUS),
7050 (uchar)(scsiq->
7051 q_status & (uchar)~(QS_READY |
7052 QS_ABORTED)));
7053 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
7054 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
7055 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
7056 sg_q_addr = q_addr;
7057 sg_list_qp = next_qp;
7058 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
7059 sg_list_qp = AscReadLramByte(iop_base,
7060 (ushort)(sg_q_addr
7061 + (ushort)
7062 ASC_SCSIQ_B_FWD));
7063 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
7064 if (sg_list_qp == ASC_QLINK_END) {
7065 AscSetLibErrorCode(asc_dvc,
7066 ASCQ_ERR_SG_Q_LINKS);
7067 scsiq->d3.done_stat = QD_WITH_ERROR;
7068 scsiq->d3.host_stat =
7069 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
7070 goto FATAL_ERR_QDONE;
7071 }
7072 AscWriteLramByte(iop_base,
7073 (ushort)(sg_q_addr + (ushort)
7074 ASC_SCSIQ_B_STATUS),
7075 QS_FREE);
7076 }
7077 n_q_used = sg_queue_cnt + 1;
7078 AscPutVarDoneQTail(iop_base, sg_list_qp);
7079 }
7080 if (asc_dvc->queue_full_or_busy & target_id) {
7081 cur_target_qng = AscReadLramByte(iop_base,
7082 (ushort)((ushort)
7083 ASC_QADR_BEG
7084 + (ushort)
7085 scsiq->d2.
7086 target_ix));
7087 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
7088 scsi_busy = AscReadLramByte(iop_base, (ushort)
7089 ASCV_SCSIBUSY_B);
7090 scsi_busy &= ~target_id;
7091 AscWriteLramByte(iop_base,
7092 (ushort)ASCV_SCSIBUSY_B,
7093 scsi_busy);
7094 asc_dvc->queue_full_or_busy &= ~target_id;
7095 }
7096 }
7097 if (asc_dvc->cur_total_qng >= n_q_used) {
7098 asc_dvc->cur_total_qng -= n_q_used;
7099 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
7100 asc_dvc->cur_dvc_qng[tid_no]--;
7101 }
7102 } else {
7103 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
7104 scsiq->d3.done_stat = QD_WITH_ERROR;
7105 goto FATAL_ERR_QDONE;
7106 }
7107 if ((scsiq->d2.srb_ptr == 0UL) ||
7108 ((scsiq->q_status & QS_ABORTED) != 0)) {
7109 return (0x11);
7110 } else if (scsiq->q_status == QS_DONE) {
7111 false_overrun = FALSE;
7112 if (scsiq->extra_bytes != 0) {
7113 scsiq->remain_bytes +=
7114 (ADV_DCNT)scsiq->extra_bytes;
7115 }
7116 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
7117 if (scsiq->d3.host_stat ==
7118 QHSTA_M_DATA_OVER_RUN) {
7119 if ((scsiq->
7120 cntl & (QC_DATA_IN | QC_DATA_OUT))
7121 == 0) {
7122 scsiq->d3.done_stat =
7123 QD_NO_ERROR;
7124 scsiq->d3.host_stat =
7125 QHSTA_NO_ERROR;
7126 } else if (false_overrun) {
7127 scsiq->d3.done_stat =
7128 QD_NO_ERROR;
7129 scsiq->d3.host_stat =
7130 QHSTA_NO_ERROR;
7131 }
7132 } else if (scsiq->d3.host_stat ==
7133 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
7134 AscStopChip(iop_base);
7135 AscSetChipControl(iop_base,
7136 (uchar)(CC_SCSI_RESET
7137 | CC_HALT));
b009bef6 7138 udelay(60);
27c868c2
MW
7139 AscSetChipControl(iop_base, CC_HALT);
7140 AscSetChipStatus(iop_base,
7141 CIW_CLR_SCSI_RESET_INT);
7142 AscSetChipStatus(iop_base, 0);
7143 AscSetChipControl(iop_base, 0);
7144 }
7145 }
7146 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 7147 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
7148 } else {
7149 if ((AscReadLramByte(iop_base,
7150 (ushort)(q_addr + (ushort)
7151 ASC_SCSIQ_CDB_BEG))
7152 == START_STOP)) {
7153 asc_dvc->unit_not_ready &= ~target_id;
7154 if (scsiq->d3.done_stat != QD_NO_ERROR) {
7155 asc_dvc->start_motor &=
7156 ~target_id;
7157 }
7158 }
7159 }
7160 return (1);
7161 } else {
7162 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
7163 FATAL_ERR_QDONE:
7164 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 7165 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
7166 }
7167 return (0x80);
7168 }
7169 }
7170 return (0);
1da177e4
LT
7171}
7172
27c868c2 7173static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 7174{
27c868c2
MW
7175 ASC_CS_TYPE chipstat;
7176 PortAddr iop_base;
7177 ushort saved_ram_addr;
7178 uchar ctrl_reg;
7179 uchar saved_ctrl_reg;
7180 int int_pending;
7181 int status;
7182 uchar host_flag;
7183
7184 iop_base = asc_dvc->iop_base;
7185 int_pending = FALSE;
7186
7187 if (AscIsIntPending(iop_base) == 0) {
7188 return int_pending;
7189 }
1da177e4 7190
895d6b4c 7191 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
27c868c2
MW
7192 return (ERR);
7193 }
7194 if (asc_dvc->in_critical_cnt != 0) {
7195 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
7196 return (ERR);
7197 }
7198 if (asc_dvc->is_in_int) {
7199 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
7200 return (ERR);
7201 }
7202 asc_dvc->is_in_int = TRUE;
7203 ctrl_reg = AscGetChipControl(iop_base);
7204 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
7205 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
7206 chipstat = AscGetChipStatus(iop_base);
7207 if (chipstat & CSW_SCSI_RESET_LATCH) {
7208 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
7209 int i = 10;
7210 int_pending = TRUE;
7211 asc_dvc->sdtr_done = 0;
7212 saved_ctrl_reg &= (uchar)(~CC_HALT);
7213 while ((AscGetChipStatus(iop_base) &
7214 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
b009bef6 7215 mdelay(100);
27c868c2
MW
7216 }
7217 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
7218 AscSetChipControl(iop_base, CC_HALT);
7219 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
7220 AscSetChipStatus(iop_base, 0);
7221 chipstat = AscGetChipStatus(iop_base);
7222 }
7223 }
7224 saved_ram_addr = AscGetChipLramAddr(iop_base);
7225 host_flag = AscReadLramByte(iop_base,
7226 ASCV_HOST_FLAG_B) &
7227 (uchar)(~ASC_HOST_FLAG_IN_ISR);
7228 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
7229 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
7230 if ((chipstat & CSW_INT_PENDING)
7231 || (int_pending)
7232 ) {
7233 AscAckInterrupt(iop_base);
7234 int_pending = TRUE;
7235 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
7236 if (AscIsrChipHalted(asc_dvc) == ERR) {
7237 goto ISR_REPORT_QDONE_FATAL_ERROR;
7238 } else {
7239 saved_ctrl_reg &= (uchar)(~CC_HALT);
7240 }
7241 } else {
7242 ISR_REPORT_QDONE_FATAL_ERROR:
7243 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
7244 while (((status =
7245 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
7246 }
7247 } else {
7248 do {
7249 if ((status =
7250 AscIsrQDone(asc_dvc)) == 1) {
7251 break;
7252 }
7253 } while (status == 0x11);
7254 }
7255 if ((status & 0x80) != 0)
7256 int_pending = ERR;
7257 }
7258 }
7259 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
7260 AscSetChipLramAddr(iop_base, saved_ram_addr);
7261 AscSetChipControl(iop_base, saved_ctrl_reg);
7262 asc_dvc->is_in_int = FALSE;
7263 return (int_pending);
1da177e4
LT
7264}
7265
7266/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
7267static uchar _asc_mcode_buf[] = {
7268 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d 7269 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
27c868c2 7270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d
MW
7272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
7274 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7275 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7276 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
629d688d
MW
7277 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
7278 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
7279 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
27c868c2 7280 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
629d688d
MW
7281 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
7282 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
7283 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
27c868c2 7284 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
629d688d
MW
7285 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
7286 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
7287 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
27c868c2 7288 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
629d688d
MW
7289 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
7290 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
7291 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
27c868c2 7292 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
629d688d
MW
7293 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
7294 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
7295 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
27c868c2 7296 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
629d688d
MW
7297 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
7298 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
7299 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
27c868c2 7300 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
629d688d
MW
7301 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
7302 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
7303 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
27c868c2 7304 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
629d688d
MW
7305 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
7306 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
7307 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
27c868c2 7308 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
629d688d
MW
7309 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
7310 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
7311 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
27c868c2 7312 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
629d688d
MW
7313 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
7314 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
7315 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
27c868c2 7316 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
629d688d
MW
7317 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
7318 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
7319 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
27c868c2 7320 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
629d688d
MW
7321 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
7322 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
7323 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
27c868c2 7324 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
629d688d
MW
7325 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
7326 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
7327 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
27c868c2 7328 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
629d688d
MW
7329 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
7330 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
7331 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
27c868c2 7332 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
629d688d
MW
7333 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
7334 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
7335 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
27c868c2 7336 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
629d688d
MW
7337 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
7338 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
7339 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
27c868c2 7340 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
629d688d
MW
7341 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
7342 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
7343 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
27c868c2 7344 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
629d688d
MW
7345 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
7346 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
7347 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
27c868c2 7348 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
629d688d
MW
7349 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
7350 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
7351 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
27c868c2 7352 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
629d688d
MW
7353 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
7354 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
7355 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
27c868c2 7356 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
629d688d
MW
7357 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
7358 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
7359 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
27c868c2 7360 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
629d688d
MW
7361 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
7362 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
7363 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
27c868c2 7364 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
629d688d
MW
7365 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
7366 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
7367 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
27c868c2 7368 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
629d688d
MW
7369 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
7370 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
7371 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
27c868c2 7372 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
629d688d
MW
7373 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
7374 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
7375 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
27c868c2 7376 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
629d688d
MW
7377 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
7378 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
7379 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
27c868c2 7380 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
7381 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
7382 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
7383 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
27c868c2 7384 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
629d688d
MW
7385 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
7386 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
7387 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
27c868c2 7388 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
629d688d
MW
7389 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
7390 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
7391 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
27c868c2 7392 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
629d688d
MW
7393 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
7394 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
7395 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
27c868c2 7396 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
629d688d
MW
7397 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
7398 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
7399 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
27c868c2 7400 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
629d688d
MW
7401 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
7402 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
7403 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
27c868c2 7404 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
629d688d
MW
7405 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
7406 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
7407 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
27c868c2 7408 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
629d688d
MW
7409 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
7410 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
7411 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
27c868c2 7412 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
629d688d
MW
7413 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
7414 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
7415 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
27c868c2 7416 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
629d688d
MW
7417 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
7418 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
7419 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
27c868c2 7420 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
629d688d
MW
7421 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
7422 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
7423 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
27c868c2 7424 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
629d688d
MW
7425 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
7426 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
7427 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
27c868c2 7428 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
629d688d
MW
7429 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
7430 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
7431 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
27c868c2 7432 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
629d688d
MW
7433 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
7434 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
7435 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
27c868c2 7436 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
7437 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
7438 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
7439 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
27c868c2 7440 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
629d688d
MW
7441 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
7442 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
7443 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
27c868c2 7444 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
629d688d
MW
7445 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
7446 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
7447 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
27c868c2 7448 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
629d688d
MW
7449 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
7450 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
7451 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
27c868c2 7452 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
629d688d
MW
7453 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
7454 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
7455 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
27c868c2 7456 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
629d688d
MW
7457 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
7458 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
7459 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
7460};
7461
27c868c2
MW
7462static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
7463static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
7464
7465#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
7466static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
7467 INQUIRY,
7468 REQUEST_SENSE,
7469 READ_CAPACITY,
7470 READ_TOC,
7471 MODE_SELECT,
7472 MODE_SENSE,
7473 MODE_SELECT_10,
7474 MODE_SENSE_10,
7475 0xFF,
7476 0xFF,
7477 0xFF,
7478 0xFF,
7479 0xFF,
7480 0xFF,
7481 0xFF,
7482 0xFF
1da177e4
LT
7483};
7484
27c868c2 7485static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 7486{
27c868c2 7487 PortAddr iop_base;
27c868c2
MW
7488 int sta;
7489 int n_q_required;
7490 int disable_syn_offset_one_fix;
7491 int i;
7492 ASC_PADDR addr;
27c868c2
MW
7493 ushort sg_entry_cnt = 0;
7494 ushort sg_entry_cnt_minus_one = 0;
7495 uchar target_ix;
7496 uchar tid_no;
7497 uchar sdtr_data;
7498 uchar extra_bytes;
7499 uchar scsi_cmd;
7500 uchar disable_cmd;
7501 ASC_SG_HEAD *sg_head;
7502 ASC_DCNT data_cnt;
7503
7504 iop_base = asc_dvc->iop_base;
7505 sg_head = scsiq->sg_head;
27c868c2
MW
7506 if (asc_dvc->err_code != 0)
7507 return (ERR);
27c868c2
MW
7508 scsiq->q1.q_no = 0;
7509 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
7510 scsiq->q1.extra_bytes = 0;
7511 }
7512 sta = 0;
7513 target_ix = scsiq->q2.target_ix;
7514 tid_no = ASC_TIX_TO_TID(target_ix);
7515 n_q_required = 1;
7516 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
7517 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
7518 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
7519 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7520 AscMsgOutSDTR(asc_dvc,
7521 asc_dvc->
7522 sdtr_period_tbl[(sdtr_data >> 4) &
7523 (uchar)(asc_dvc->
7524 max_sdtr_index -
7525 1)],
7526 (uchar)(sdtr_data & (uchar)
7527 ASC_SYN_MAX_OFFSET));
7528 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
7529 }
7530 }
27c868c2 7531 if (asc_dvc->in_critical_cnt != 0) {
27c868c2
MW
7532 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
7533 return (ERR);
7534 }
7535 asc_dvc->in_critical_cnt++;
7536 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
7537 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
7538 asc_dvc->in_critical_cnt--;
27c868c2
MW
7539 return (ERR);
7540 }
1da177e4 7541#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
7542 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
7543 asc_dvc->in_critical_cnt--;
27c868c2
MW
7544 return (ERR);
7545 }
1da177e4 7546#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
7547 if (sg_entry_cnt == 1) {
7548 scsiq->q1.data_addr =
7549 (ADV_PADDR)sg_head->sg_list[0].addr;
7550 scsiq->q1.data_cnt =
7551 (ADV_DCNT)sg_head->sg_list[0].bytes;
7552 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
7553 }
7554 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
7555 }
7556 scsi_cmd = scsiq->cdbptr[0];
7557 disable_syn_offset_one_fix = FALSE;
7558 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
7559 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
7560 if (scsiq->q1.cntl & QC_SG_HEAD) {
7561 data_cnt = 0;
7562 for (i = 0; i < sg_entry_cnt; i++) {
7563 data_cnt +=
7564 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
7565 bytes);
7566 }
7567 } else {
7568 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
7569 }
7570 if (data_cnt != 0UL) {
7571 if (data_cnt < 512UL) {
7572 disable_syn_offset_one_fix = TRUE;
7573 } else {
7574 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
7575 i++) {
7576 disable_cmd =
7577 _syn_offset_one_disable_cmd[i];
7578 if (disable_cmd == 0xFF) {
7579 break;
7580 }
7581 if (scsi_cmd == disable_cmd) {
7582 disable_syn_offset_one_fix =
7583 TRUE;
7584 break;
7585 }
7586 }
7587 }
7588 }
7589 }
7590 if (disable_syn_offset_one_fix) {
7591 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
7592 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
7593 ASC_TAG_FLAG_DISABLE_DISCONNECT);
7594 } else {
7595 scsiq->q2.tag_code &= 0x27;
7596 }
7597 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
7598 if (asc_dvc->bug_fix_cntl) {
7599 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
7600 if ((scsi_cmd == READ_6) ||
7601 (scsi_cmd == READ_10)) {
7602 addr =
7603 (ADV_PADDR)le32_to_cpu(sg_head->
7604 sg_list
7605 [sg_entry_cnt_minus_one].
7606 addr) +
7607 (ADV_DCNT)le32_to_cpu(sg_head->
7608 sg_list
7609 [sg_entry_cnt_minus_one].
7610 bytes);
7611 extra_bytes =
7612 (uchar)((ushort)addr & 0x0003);
7613 if ((extra_bytes != 0)
7614 &&
7615 ((scsiq->q2.
7616 tag_code &
7617 ASC_TAG_FLAG_EXTRA_BYTES)
7618 == 0)) {
7619 scsiq->q2.tag_code |=
7620 ASC_TAG_FLAG_EXTRA_BYTES;
7621 scsiq->q1.extra_bytes =
7622 extra_bytes;
7623 data_cnt =
7624 le32_to_cpu(sg_head->
7625 sg_list
7626 [sg_entry_cnt_minus_one].
7627 bytes);
7628 data_cnt -=
7629 (ASC_DCNT) extra_bytes;
7630 sg_head->
7631 sg_list
7632 [sg_entry_cnt_minus_one].
7633 bytes =
7634 cpu_to_le32(data_cnt);
7635 }
7636 }
7637 }
7638 }
7639 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 7640#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7641 /*
7642 * Set the sg_entry_cnt to the maximum possible. The rest of
7643 * the SG elements will be copied when the RISC completes the
7644 * SG elements that fit and halts.
7645 */
7646 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
7647 sg_entry_cnt = ASC_MAX_SG_LIST;
7648 }
1da177e4 7649#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7650 n_q_required = AscSgListToQueue(sg_entry_cnt);
7651 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
7652 (uint) n_q_required)
7653 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
7654 if ((sta =
7655 AscSendScsiQueue(asc_dvc, scsiq,
7656 n_q_required)) == 1) {
7657 asc_dvc->in_critical_cnt--;
27c868c2
MW
7658 return (sta);
7659 }
7660 }
7661 } else {
7662 if (asc_dvc->bug_fix_cntl) {
7663 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
7664 if ((scsi_cmd == READ_6) ||
7665 (scsi_cmd == READ_10)) {
7666 addr =
7667 le32_to_cpu(scsiq->q1.data_addr) +
7668 le32_to_cpu(scsiq->q1.data_cnt);
7669 extra_bytes =
7670 (uchar)((ushort)addr & 0x0003);
7671 if ((extra_bytes != 0)
7672 &&
7673 ((scsiq->q2.
7674 tag_code &
7675 ASC_TAG_FLAG_EXTRA_BYTES)
7676 == 0)) {
7677 data_cnt =
7678 le32_to_cpu(scsiq->q1.
7679 data_cnt);
7680 if (((ushort)data_cnt & 0x01FF)
7681 == 0) {
7682 scsiq->q2.tag_code |=
7683 ASC_TAG_FLAG_EXTRA_BYTES;
7684 data_cnt -= (ASC_DCNT)
7685 extra_bytes;
7686 scsiq->q1.data_cnt =
7687 cpu_to_le32
7688 (data_cnt);
7689 scsiq->q1.extra_bytes =
7690 extra_bytes;
7691 }
7692 }
7693 }
7694 }
7695 }
7696 n_q_required = 1;
7697 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
7698 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
7699 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
7700 n_q_required)) == 1) {
7701 asc_dvc->in_critical_cnt--;
27c868c2
MW
7702 return (sta);
7703 }
7704 }
7705 }
7706 asc_dvc->in_critical_cnt--;
27c868c2 7707 return (sta);
1da177e4
LT
7708}
7709
27c868c2
MW
7710static int
7711AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 7712{
27c868c2
MW
7713 PortAddr iop_base;
7714 uchar free_q_head;
7715 uchar next_qp;
7716 uchar tid_no;
7717 uchar target_ix;
7718 int sta;
7719
7720 iop_base = asc_dvc->iop_base;
7721 target_ix = scsiq->q2.target_ix;
7722 tid_no = ASC_TIX_TO_TID(target_ix);
7723 sta = 0;
7724 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
7725 if (n_q_required > 1) {
7726 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
7727 free_q_head, (uchar)
7728 (n_q_required)))
7729 != (uchar)ASC_QLINK_END) {
7730 asc_dvc->last_q_shortage = 0;
7731 scsiq->sg_head->queue_cnt = n_q_required - 1;
7732 scsiq->q1.q_no = free_q_head;
7733 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
7734 free_q_head)) == 1) {
7735 AscPutVarFreeQHead(iop_base, next_qp);
7736 asc_dvc->cur_total_qng += (uchar)(n_q_required);
7737 asc_dvc->cur_dvc_qng[tid_no]++;
7738 }
7739 return (sta);
7740 }
7741 } else if (n_q_required == 1) {
7742 if ((next_qp = AscAllocFreeQueue(iop_base,
7743 free_q_head)) !=
7744 ASC_QLINK_END) {
7745 scsiq->q1.q_no = free_q_head;
7746 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
7747 free_q_head)) == 1) {
7748 AscPutVarFreeQHead(iop_base, next_qp);
7749 asc_dvc->cur_total_qng++;
7750 asc_dvc->cur_dvc_qng[tid_no]++;
7751 }
7752 return (sta);
7753 }
7754 }
7755 return (sta);
1da177e4
LT
7756}
7757
27c868c2 7758static int AscSgListToQueue(int sg_list)
1da177e4 7759{
27c868c2 7760 int n_sg_list_qs;
1da177e4 7761
27c868c2
MW
7762 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
7763 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
7764 n_sg_list_qs++;
7765 return (n_sg_list_qs + 1);
1da177e4
LT
7766}
7767
27c868c2
MW
7768static uint
7769AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 7770{
27c868c2
MW
7771 uint cur_used_qs;
7772 uint cur_free_qs;
7773 ASC_SCSI_BIT_ID_TYPE target_id;
7774 uchar tid_no;
7775
7776 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
7777 tid_no = ASC_TIX_TO_TID(target_ix);
7778 if ((asc_dvc->unit_not_ready & target_id) ||
7779 (asc_dvc->queue_full_or_busy & target_id)) {
7780 return (0);
7781 }
7782 if (n_qs == 1) {
7783 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7784 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
7785 } else {
7786 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7787 (uint) ASC_MIN_FREE_Q;
7788 }
7789 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
7790 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
7791 if (asc_dvc->cur_dvc_qng[tid_no] >=
7792 asc_dvc->max_dvc_qng[tid_no]) {
7793 return (0);
7794 }
7795 return (cur_free_qs);
7796 }
7797 if (n_qs > 1) {
7798 if ((n_qs > asc_dvc->last_q_shortage)
7799 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
7800 asc_dvc->last_q_shortage = n_qs;
7801 }
7802 }
7803 return (0);
1da177e4
LT
7804}
7805
27c868c2 7806static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 7807{
27c868c2
MW
7808 ushort q_addr;
7809 uchar tid_no;
7810 uchar sdtr_data;
7811 uchar syn_period_ix;
7812 uchar syn_offset;
7813 PortAddr iop_base;
7814
7815 iop_base = asc_dvc->iop_base;
7816 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
7817 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
7818 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
7819 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7820 syn_period_ix =
7821 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
7822 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
7823 AscMsgOutSDTR(asc_dvc,
7824 asc_dvc->sdtr_period_tbl[syn_period_ix],
7825 syn_offset);
7826 scsiq->q1.cntl |= QC_MSG_OUT;
7827 }
7828 q_addr = ASC_QNO_TO_QADDR(q_no);
7829 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
7830 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
7831 }
7832 scsiq->q1.status = QS_FREE;
7833 AscMemWordCopyPtrToLram(iop_base,
7834 q_addr + ASC_SCSIQ_CDB_BEG,
7835 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
7836
7837 DvcPutScsiQ(iop_base,
7838 q_addr + ASC_SCSIQ_CPY_BEG,
7839 (uchar *)&scsiq->q1.cntl,
7840 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
7841 AscWriteLramWord(iop_base,
7842 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
7843 (ushort)(((ushort)scsiq->q1.
7844 q_no << 8) | (ushort)QS_READY));
7845 return (1);
1da177e4
LT
7846}
7847
27c868c2
MW
7848static int
7849AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 7850{
27c868c2
MW
7851 int sta;
7852 int i;
7853 ASC_SG_HEAD *sg_head;
7854 ASC_SG_LIST_Q scsi_sg_q;
7855 ASC_DCNT saved_data_addr;
7856 ASC_DCNT saved_data_cnt;
7857 PortAddr iop_base;
7858 ushort sg_list_dwords;
7859 ushort sg_index;
7860 ushort sg_entry_cnt;
7861 ushort q_addr;
7862 uchar next_qp;
7863
7864 iop_base = asc_dvc->iop_base;
7865 sg_head = scsiq->sg_head;
7866 saved_data_addr = scsiq->q1.data_addr;
7867 saved_data_cnt = scsiq->q1.data_cnt;
7868 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
7869 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 7870#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7871 /*
7872 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
7873 * then not all SG elements will fit in the allocated queues.
7874 * The rest of the SG elements will be copied when the RISC
7875 * completes the SG elements that fit and halts.
7876 */
7877 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
7878 /*
7879 * Set sg_entry_cnt to be the number of SG elements that
7880 * will fit in the allocated SG queues. It is minus 1, because
7881 * the first SG element is handled above. ASC_MAX_SG_LIST is
7882 * already inflated by 1 to account for this. For example it
7883 * may be 50 which is 1 + 7 queues * 7 SG elements.
7884 */
7885 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
7886
7887 /*
7888 * Keep track of remaining number of SG elements that will
7889 * need to be handled from a_isr.c.
7890 */
7891 scsiq->remain_sg_entry_cnt =
7892 sg_head->entry_cnt - ASC_MAX_SG_LIST;
7893 } else {
1da177e4 7894#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7895 /*
7896 * Set sg_entry_cnt to be the number of SG elements that
7897 * will fit in the allocated SG queues. It is minus 1, because
7898 * the first SG element is handled above.
7899 */
7900 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 7901#if CC_VERY_LONG_SG_LIST
27c868c2 7902 }
1da177e4 7903#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7904 if (sg_entry_cnt != 0) {
7905 scsiq->q1.cntl |= QC_SG_HEAD;
7906 q_addr = ASC_QNO_TO_QADDR(q_no);
7907 sg_index = 1;
7908 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
7909 scsi_sg_q.sg_head_qp = q_no;
7910 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
7911 for (i = 0; i < sg_head->queue_cnt; i++) {
7912 scsi_sg_q.seq_no = i + 1;
7913 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
7914 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
7915 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
7916 if (i == 0) {
7917 scsi_sg_q.sg_list_cnt =
7918 ASC_SG_LIST_PER_Q;
7919 scsi_sg_q.sg_cur_list_cnt =
7920 ASC_SG_LIST_PER_Q;
7921 } else {
7922 scsi_sg_q.sg_list_cnt =
7923 ASC_SG_LIST_PER_Q - 1;
7924 scsi_sg_q.sg_cur_list_cnt =
7925 ASC_SG_LIST_PER_Q - 1;
7926 }
7927 } else {
1da177e4 7928#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7929 /*
7930 * This is the last SG queue in the list of
7931 * allocated SG queues. If there are more
7932 * SG elements than will fit in the allocated
7933 * queues, then set the QCSG_SG_XFER_MORE flag.
7934 */
7935 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
7936 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
7937 } else {
1da177e4 7938#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 7939 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 7940#if CC_VERY_LONG_SG_LIST
27c868c2 7941 }
1da177e4 7942#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7943 sg_list_dwords = sg_entry_cnt << 1;
7944 if (i == 0) {
7945 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
7946 scsi_sg_q.sg_cur_list_cnt =
7947 sg_entry_cnt;
7948 } else {
7949 scsi_sg_q.sg_list_cnt =
7950 sg_entry_cnt - 1;
7951 scsi_sg_q.sg_cur_list_cnt =
7952 sg_entry_cnt - 1;
7953 }
7954 sg_entry_cnt = 0;
7955 }
7956 next_qp = AscReadLramByte(iop_base,
7957 (ushort)(q_addr +
7958 ASC_SCSIQ_B_FWD));
7959 scsi_sg_q.q_no = next_qp;
7960 q_addr = ASC_QNO_TO_QADDR(next_qp);
7961 AscMemWordCopyPtrToLram(iop_base,
7962 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
7963 (uchar *)&scsi_sg_q,
7964 sizeof(ASC_SG_LIST_Q) >> 1);
7965 AscMemDWordCopyPtrToLram(iop_base,
7966 q_addr + ASC_SGQ_LIST_BEG,
7967 (uchar *)&sg_head->
7968 sg_list[sg_index],
7969 sg_list_dwords);
7970 sg_index += ASC_SG_LIST_PER_Q;
7971 scsiq->next_sg_index = sg_index;
7972 }
7973 } else {
7974 scsiq->q1.cntl &= ~QC_SG_HEAD;
7975 }
7976 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
7977 scsiq->q1.data_addr = saved_data_addr;
7978 scsiq->q1.data_cnt = saved_data_cnt;
7979 return (sta);
1da177e4
LT
7980}
7981
27c868c2
MW
7982static int
7983AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 7984{
27c868c2 7985 int sta = FALSE;
1da177e4 7986
27c868c2
MW
7987 if (AscHostReqRiscHalt(iop_base)) {
7988 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
7989 AscStartChip(iop_base);
7990 return (sta);
7991 }
7992 return (sta);
1da177e4
LT
7993}
7994
27c868c2 7995static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 7996{
27c868c2
MW
7997 ASC_SCSI_BIT_ID_TYPE org_id;
7998 int i;
7999 int sta = TRUE;
8000
8001 AscSetBank(iop_base, 1);
8002 org_id = AscReadChipDvcID(iop_base);
8003 for (i = 0; i <= ASC_MAX_TID; i++) {
8004 if (org_id == (0x01 << i))
8005 break;
8006 }
8007 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8008 AscWriteChipDvcID(iop_base, id);
8009 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8010 AscSetBank(iop_base, 0);
8011 AscSetChipSyn(iop_base, sdtr_data);
8012 if (AscGetChipSyn(iop_base) != sdtr_data) {
8013 sta = FALSE;
8014 }
8015 } else {
8016 sta = FALSE;
8017 }
8018 AscSetBank(iop_base, 1);
8019 AscWriteChipDvcID(iop_base, org_id);
8020 AscSetBank(iop_base, 0);
8021 return (sta);
8022}
1da177e4 8023
27c868c2 8024static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 8025{
27c868c2
MW
8026 uchar i;
8027 ushort s_addr;
8028 PortAddr iop_base;
8029 ushort warn_code;
8030
8031 iop_base = asc_dvc->iop_base;
8032 warn_code = 0;
8033 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
8034 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
8035 64) >> 1)
8036 );
8037 i = ASC_MIN_ACTIVE_QNO;
8038 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
8039 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8040 (uchar)(i + 1));
8041 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8042 (uchar)(asc_dvc->max_total_qng));
8043 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8044 (uchar)i);
8045 i++;
8046 s_addr += ASC_QBLK_SIZE;
8047 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
8048 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8049 (uchar)(i + 1));
8050 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8051 (uchar)(i - 1));
8052 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8053 (uchar)i);
8054 }
8055 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8056 (uchar)ASC_QLINK_END);
8057 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8058 (uchar)(asc_dvc->max_total_qng - 1));
8059 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8060 (uchar)asc_dvc->max_total_qng);
8061 i++;
8062 s_addr += ASC_QBLK_SIZE;
8063 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
8064 i++, s_addr += ASC_QBLK_SIZE) {
8065 AscWriteLramByte(iop_base,
8066 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
8067 AscWriteLramByte(iop_base,
8068 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
8069 AscWriteLramByte(iop_base,
8070 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
8071 }
8072 return (warn_code);
1da177e4
LT
8073}
8074
27c868c2 8075static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8076{
27c868c2
MW
8077 PortAddr iop_base;
8078 int i;
8079 ushort lram_addr;
8080
8081 iop_base = asc_dvc->iop_base;
8082 AscPutRiscVarFreeQHead(iop_base, 1);
8083 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
8084 AscPutVarFreeQHead(iop_base, 1);
8085 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
8086 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
8087 (uchar)((int)asc_dvc->max_total_qng + 1));
8088 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
8089 (uchar)((int)asc_dvc->max_total_qng + 2));
8090 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
8091 asc_dvc->max_total_qng);
8092 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
8093 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8094 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
8095 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
8096 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
8097 AscPutQDoneInProgress(iop_base, 0);
8098 lram_addr = ASC_QADR_BEG;
8099 for (i = 0; i < 32; i++, lram_addr += 2) {
8100 AscWriteLramWord(iop_base, lram_addr, 0);
8101 }
8102 return (0);
1da177e4
LT
8103}
8104
27c868c2 8105static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 8106{
27c868c2
MW
8107 if (asc_dvc->err_code == 0) {
8108 asc_dvc->err_code = err_code;
8109 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8110 err_code);
8111 }
8112 return (err_code);
1da177e4
LT
8113}
8114
27c868c2
MW
8115static uchar
8116AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 8117{
27c868c2
MW
8118 EXT_MSG sdtr_buf;
8119 uchar sdtr_period_index;
8120 PortAddr iop_base;
8121
8122 iop_base = asc_dvc->iop_base;
47d853cc 8123 sdtr_buf.msg_type = EXTENDED_MESSAGE;
27c868c2 8124 sdtr_buf.msg_len = MS_SDTR_LEN;
47d853cc 8125 sdtr_buf.msg_req = EXTENDED_SDTR;
27c868c2
MW
8126 sdtr_buf.xfer_period = sdtr_period;
8127 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8128 sdtr_buf.req_ack_offset = sdtr_offset;
8129 if ((sdtr_period_index =
8130 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
8131 asc_dvc->max_sdtr_index) {
8132 AscMemWordCopyPtrToLram(iop_base,
8133 ASCV_MSGOUT_BEG,
8134 (uchar *)&sdtr_buf,
8135 sizeof(EXT_MSG) >> 1);
8136 return ((sdtr_period_index << 4) | sdtr_offset);
8137 } else {
8138
8139 sdtr_buf.req_ack_offset = 0;
8140 AscMemWordCopyPtrToLram(iop_base,
8141 ASCV_MSGOUT_BEG,
8142 (uchar *)&sdtr_buf,
8143 sizeof(EXT_MSG) >> 1);
8144 return (0);
8145 }
1da177e4
LT
8146}
8147
27c868c2
MW
8148static uchar
8149AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 8150{
27c868c2
MW
8151 uchar byte;
8152 uchar sdtr_period_ix;
8153
8154 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8155 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
8156 ) {
8157 return (0xFF);
8158 }
8159 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8160 return (byte);
1da177e4
LT
8161}
8162
27c868c2 8163static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 8164{
27c868c2
MW
8165 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8166 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8167 return;
1da177e4
LT
8168}
8169
27c868c2 8170static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 8171{
27c868c2
MW
8172 uchar *period_table;
8173 int max_index;
8174 int min_index;
8175 int i;
8176
8177 period_table = asc_dvc->sdtr_period_tbl;
8178 max_index = (int)asc_dvc->max_sdtr_index;
8179 min_index = (int)asc_dvc->host_init_sdtr_index;
8180 if ((syn_time <= period_table[max_index])) {
8181 for (i = min_index; i < (max_index - 1); i++) {
8182 if (syn_time <= period_table[i]) {
8183 return ((uchar)i);
8184 }
8185 }
8186 return ((uchar)max_index);
8187 } else {
8188 return ((uchar)(max_index + 1));
8189 }
1da177e4
LT
8190}
8191
27c868c2 8192static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 8193{
27c868c2
MW
8194 ushort q_addr;
8195 uchar next_qp;
8196 uchar q_status;
8197
8198 q_addr = ASC_QNO_TO_QADDR(free_q_head);
8199 q_status = (uchar)AscReadLramByte(iop_base,
8200 (ushort)(q_addr +
8201 ASC_SCSIQ_B_STATUS));
8202 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
8203 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
8204 return (next_qp);
8205 }
8206 return (ASC_QLINK_END);
1da177e4
LT
8207}
8208
27c868c2
MW
8209static uchar
8210AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 8211{
27c868c2 8212 uchar i;
1da177e4 8213
27c868c2
MW
8214 for (i = 0; i < n_free_q; i++) {
8215 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
8216 == ASC_QLINK_END) {
8217 return (ASC_QLINK_END);
8218 }
8219 }
8220 return (free_q_head);
1da177e4
LT
8221}
8222
27c868c2 8223static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 8224{
27c868c2
MW
8225 int count = 0;
8226 int sta = 0;
8227 uchar saved_stop_code;
8228
8229 if (AscIsChipHalted(iop_base))
8230 return (1);
8231 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
8232 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8233 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
8234 do {
8235 if (AscIsChipHalted(iop_base)) {
8236 sta = 1;
8237 break;
8238 }
b009bef6 8239 mdelay(100);
27c868c2
MW
8240 } while (count++ < 20);
8241 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
8242 return (sta);
1da177e4
LT
8243}
8244
27c868c2 8245static int AscStopQueueExe(PortAddr iop_base)
1da177e4 8246{
27c868c2
MW
8247 int count = 0;
8248
8249 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
8250 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8251 ASC_STOP_REQ_RISC_STOP);
8252 do {
8253 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
8254 ASC_STOP_ACK_RISC_STOP) {
8255 return (1);
8256 }
b009bef6 8257 mdelay(100);
27c868c2
MW
8258 } while (count++ < 20);
8259 }
8260 return (0);
1da177e4
LT
8261}
8262
27c868c2 8263static int AscStartChip(PortAddr iop_base)
1da177e4 8264{
27c868c2
MW
8265 AscSetChipControl(iop_base, 0);
8266 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8267 return (0);
8268 }
8269 return (1);
1da177e4
LT
8270}
8271
27c868c2 8272static int AscStopChip(PortAddr iop_base)
1da177e4 8273{
27c868c2
MW
8274 uchar cc_val;
8275
8276 cc_val =
8277 AscGetChipControl(iop_base) &
8278 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
8279 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
8280 AscSetChipIH(iop_base, INS_HALT);
8281 AscSetChipIH(iop_base, INS_RFLAG_WTM);
8282 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
8283 return (0);
8284 }
8285 return (1);
1da177e4
LT
8286}
8287
27c868c2 8288static int AscIsChipHalted(PortAddr iop_base)
1da177e4 8289{
27c868c2
MW
8290 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8291 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
8292 return (1);
8293 }
8294 }
8295 return (0);
1da177e4
LT
8296}
8297
27c868c2 8298static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 8299{
27c868c2
MW
8300 AscSetBank(iop_base, 1);
8301 AscWriteChipIH(iop_base, ins_code);
8302 AscSetBank(iop_base, 0);
8303 return;
1da177e4
LT
8304}
8305
27c868c2 8306static void AscAckInterrupt(PortAddr iop_base)
1da177e4 8307{
27c868c2
MW
8308 uchar host_flag;
8309 uchar risc_flag;
8310 ushort loop;
8311
8312 loop = 0;
8313 do {
8314 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8315 if (loop++ > 0x7FFF) {
8316 break;
8317 }
8318 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8319 host_flag =
8320 AscReadLramByte(iop_base,
8321 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8322 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8323 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8324 AscSetChipStatus(iop_base, CIW_INT_ACK);
8325 loop = 0;
8326 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8327 AscSetChipStatus(iop_base, CIW_INT_ACK);
8328 if (loop++ > 3) {
8329 break;
8330 }
8331 }
8332 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8333 return;
1da177e4
LT
8334}
8335
27c868c2 8336static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 8337{
27c868c2 8338 ushort cfg;
1da177e4 8339
27c868c2
MW
8340 cfg = AscGetChipCfgLsw(iop_base);
8341 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
8342 return;
1da177e4
LT
8343}
8344
27c868c2 8345static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 8346{
27c868c2 8347 ushort cfg;
1da177e4 8348
27c868c2
MW
8349 cfg = AscGetChipCfgLsw(iop_base);
8350 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
8351 return;
1da177e4
LT
8352}
8353
27c868c2 8354static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 8355{
27c868c2
MW
8356 uchar val;
8357
8358 val = AscGetChipControl(iop_base) &
8359 (~
8360 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
8361 CC_CHIP_RESET));
8362 if (bank == 1) {
8363 val |= CC_BANK_ONE;
8364 } else if (bank == 2) {
8365 val |= CC_DIAG | CC_BANK_ONE;
8366 } else {
8367 val &= ~CC_BANK_ONE;
8368 }
8369 AscSetChipControl(iop_base, val);
8370 return;
1da177e4
LT
8371}
8372
27c868c2 8373static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 8374{
27c868c2
MW
8375 PortAddr iop_base;
8376 int i = 10;
1da177e4 8377
27c868c2
MW
8378 iop_base = asc_dvc->iop_base;
8379 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
8380 && (i-- > 0)) {
b009bef6 8381 mdelay(100);
27c868c2
MW
8382 }
8383 AscStopChip(iop_base);
8384 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
b009bef6 8385 udelay(60);
27c868c2
MW
8386 AscSetChipIH(iop_base, INS_RFLAG_WTM);
8387 AscSetChipIH(iop_base, INS_HALT);
8388 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
8389 AscSetChipControl(iop_base, CC_HALT);
b009bef6 8390 mdelay(200);
27c868c2
MW
8391 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8392 AscSetChipStatus(iop_base, 0);
8393 return (AscIsChipHalted(iop_base));
1da177e4
LT
8394}
8395
78e77d8b 8396static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
1da177e4 8397{
27c868c2
MW
8398 if (bus_type & ASC_IS_ISA)
8399 return (ASC_MAX_ISA_DMA_COUNT);
8400 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
8401 return (ASC_MAX_VL_DMA_COUNT);
8402 return (ASC_MAX_PCI_DMA_COUNT);
1da177e4
LT
8403}
8404
8405#ifdef CONFIG_ISA
78e77d8b 8406static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 8407{
27c868c2
MW
8408 ushort channel;
8409
8410 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
8411 if (channel == 0x03)
8412 return (0);
8413 else if (channel == 0x00)
8414 return (7);
8415 return (channel + 4);
1da177e4
LT
8416}
8417
78e77d8b 8418static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 8419{
27c868c2
MW
8420 ushort cfg_lsw;
8421 uchar value;
8422
8423 if ((dma_channel >= 5) && (dma_channel <= 7)) {
8424 if (dma_channel == 7)
8425 value = 0x00;
8426 else
8427 value = dma_channel - 4;
8428 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
8429 cfg_lsw |= value;
8430 AscSetChipCfgLsw(iop_base, cfg_lsw);
8431 return (AscGetIsaDmaChannel(iop_base));
8432 }
8433 return (0);
1da177e4
LT
8434}
8435
78e77d8b 8436static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 8437{
27c868c2
MW
8438 speed_value &= 0x07;
8439 AscSetBank(iop_base, 1);
8440 AscWriteChipDmaSpeed(iop_base, speed_value);
8441 AscSetBank(iop_base, 0);
8442 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
8443}
8444
78e77d8b 8445static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 8446{
27c868c2 8447 uchar speed_value;
1da177e4 8448
27c868c2
MW
8449 AscSetBank(iop_base, 1);
8450 speed_value = AscReadChipDmaSpeed(iop_base);
8451 speed_value &= 0x07;
8452 AscSetBank(iop_base, 0);
8453 return (speed_value);
1da177e4
LT
8454}
8455#endif /* CONFIG_ISA */
8456
c2dce2fa 8457static int __devinit AscInitGetConfig(asc_board_t *boardp)
1da177e4 8458{
c2dce2fa 8459 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9649af39 8460 unsigned short warn_code = 0;
27c868c2 8461
27c868c2 8462 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9649af39 8463 if (asc_dvc->err_code != 0)
c2dce2fa 8464 return asc_dvc->err_code;
27c868c2 8465
9649af39 8466 if (AscFindSignature(asc_dvc->iop_base)) {
27c868c2
MW
8467 warn_code |= AscInitAscDvcVar(asc_dvc);
8468 warn_code |= AscInitFromEEP(asc_dvc);
8469 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
ecec1947 8470 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
27c868c2 8471 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
27c868c2
MW
8472 } else {
8473 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
8474 }
c2dce2fa
MW
8475
8476 switch (warn_code) {
8477 case 0: /* No error */
8478 break;
8479 case ASC_WARN_IO_PORT_ROTATE:
8480 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
8481 "modified\n", boardp->id);
8482 break;
8483 case ASC_WARN_AUTO_CONFIG:
8484 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
8485 "switch enabled\n", boardp->id);
8486 break;
8487 case ASC_WARN_EEPROM_CHKSUM:
8488 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
8489 "error\n", boardp->id);
8490 break;
8491 case ASC_WARN_IRQ_MODIFIED:
8492 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
8493 boardp->id);
8494 break;
8495 case ASC_WARN_CMD_QNG_CONFLICT:
8496 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
8497 "w/o disconnects\n", boardp->id);
8498 break;
8499 default:
8500 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
8501 "0x%x\n", boardp->id, warn_code);
8502 break;
8503 }
8504
8505 if (asc_dvc->err_code != 0) {
8506 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
8507 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
8508 asc_dvc->err_code);
8509 }
8510
8511 return asc_dvc->err_code;
1da177e4
LT
8512}
8513
c2dce2fa 8514static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 8515{
c2dce2fa 8516 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
394dbf3f
MW
8517 PortAddr iop_base = asc_dvc->iop_base;
8518 unsigned short cfg_msw;
8519 unsigned short warn_code = 0;
27c868c2
MW
8520
8521 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
8522 if (asc_dvc->err_code != 0)
c2dce2fa 8523 return asc_dvc->err_code;
394dbf3f 8524 if (!AscFindSignature(asc_dvc->iop_base)) {
27c868c2 8525 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
c2dce2fa 8526 return asc_dvc->err_code;
27c868c2 8527 }
1da177e4 8528
27c868c2
MW
8529 cfg_msw = AscGetChipCfgMsw(iop_base);
8530 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 8531 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
8532 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
8533 AscSetChipCfgMsw(iop_base, cfg_msw);
8534 }
8535 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
8536 asc_dvc->cfg->cmd_qng_enabled) {
8537 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
8538 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
8539 }
8540 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
8541 warn_code |= ASC_WARN_AUTO_CONFIG;
8542 }
8543 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
8544 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
8545 != asc_dvc->irq_no) {
8546 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
8547 }
8548 }
9649af39 8549#ifdef CONFIG_PCI
27c868c2
MW
8550 if (asc_dvc->bus_type & ASC_IS_PCI) {
8551 cfg_msw &= 0xFFC0;
8552 AscSetChipCfgMsw(iop_base, cfg_msw);
8553 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
8554 } else {
9649af39
MW
8555 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
8556 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
27c868c2
MW
8557 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
8558 asc_dvc->bug_fix_cntl |=
8559 ASC_BUG_FIX_ASYN_USE_SYN;
8560 }
8561 }
9649af39
MW
8562 } else
8563#endif /* CONFIG_PCI */
8564 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
27c868c2
MW
8565 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
8566 == ASC_CHIP_VER_ASYN_BUG) {
8567 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
8568 }
8569 }
8570 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
8571 asc_dvc->cfg->chip_scsi_id) {
8572 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
8573 }
1da177e4 8574#ifdef CONFIG_ISA
27c868c2
MW
8575 if (asc_dvc->bus_type & ASC_IS_ISA) {
8576 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
8577 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
8578 }
1da177e4 8579#endif /* CONFIG_ISA */
394dbf3f
MW
8580
8581 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
c2dce2fa
MW
8582
8583 switch (warn_code) {
8584 case 0: /* No error. */
8585 break;
8586 case ASC_WARN_IO_PORT_ROTATE:
8587 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
8588 "modified\n", boardp->id);
8589 break;
8590 case ASC_WARN_AUTO_CONFIG:
8591 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
8592 "switch enabled\n", boardp->id);
8593 break;
8594 case ASC_WARN_EEPROM_CHKSUM:
8595 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
8596 "error\n", boardp->id);
8597 break;
8598 case ASC_WARN_IRQ_MODIFIED:
8599 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
8600 boardp->id);
8601 break;
8602 case ASC_WARN_CMD_QNG_CONFLICT:
8603 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
8604 "disconnects\n",
8605 boardp->id);
8606 break;
8607 default:
8608 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
8609 "0x%x\n", boardp->id, warn_code);
8610 break;
8611 }
8612
8613 if (asc_dvc->err_code != 0) {
8614 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
8615 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
8616 asc_dvc->err_code);
8617 }
8618
8619 return asc_dvc->err_code;
1da177e4
LT
8620}
8621
27c868c2 8622static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 8623{
27c868c2
MW
8624 ushort warn_code;
8625 PortAddr iop_base;
8626
8627 iop_base = asc_dvc->iop_base;
8628 warn_code = 0;
8629 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
8630 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
8631 AscResetChipAndScsiBus(asc_dvc);
b009bef6 8632 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
27c868c2
MW
8633 }
8634 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
8635 if (asc_dvc->err_code != 0)
8636 return (UW_ERR);
8637 if (!AscFindSignature(asc_dvc->iop_base)) {
8638 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
8639 return (warn_code);
8640 }
8641 AscDisableInterrupt(iop_base);
8642 warn_code |= AscInitLram(asc_dvc);
8643 if (asc_dvc->err_code != 0)
8644 return (UW_ERR);
8645 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
8646 (ulong)_asc_mcode_chksum);
8647 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
8648 _asc_mcode_size) != _asc_mcode_chksum) {
8649 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
8650 return (warn_code);
8651 }
8652 warn_code |= AscInitMicroCodeVar(asc_dvc);
8653 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
8654 AscEnableInterrupt(iop_base);
8655 return (warn_code);
1da177e4
LT
8656}
8657
78e77d8b 8658static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8659{
27c868c2
MW
8660 int i;
8661 PortAddr iop_base;
8662 ushort warn_code;
8663 uchar chip_version;
8664
8665 iop_base = asc_dvc->iop_base;
8666 warn_code = 0;
8667 asc_dvc->err_code = 0;
8668 if ((asc_dvc->bus_type &
8669 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
8670 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
8671 }
8672 AscSetChipControl(iop_base, CC_HALT);
8673 AscSetChipStatus(iop_base, 0);
8674 asc_dvc->bug_fix_cntl = 0;
8675 asc_dvc->pci_fix_asyn_xfer = 0;
8676 asc_dvc->pci_fix_asyn_xfer_always = 0;
8677 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
8678 asc_dvc->sdtr_done = 0;
8679 asc_dvc->cur_total_qng = 0;
8680 asc_dvc->is_in_int = 0;
8681 asc_dvc->in_critical_cnt = 0;
8682 asc_dvc->last_q_shortage = 0;
8683 asc_dvc->use_tagged_qng = 0;
8684 asc_dvc->no_scam = 0;
8685 asc_dvc->unit_not_ready = 0;
8686 asc_dvc->queue_full_or_busy = 0;
8687 asc_dvc->redo_scam = 0;
8688 asc_dvc->res2 = 0;
8689 asc_dvc->host_init_sdtr_index = 0;
8690 asc_dvc->cfg->can_tagged_qng = 0;
8691 asc_dvc->cfg->cmd_qng_enabled = 0;
8692 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
8693 asc_dvc->init_sdtr = 0;
8694 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
8695 asc_dvc->scsi_reset_wait = 3;
8696 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
8697 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
8698 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
8699 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
8700 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
8701 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
8702 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
8703 ASC_LIB_VERSION_MINOR;
8704 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
8705 asc_dvc->cfg->chip_version = chip_version;
8706 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
8707 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
8708 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
8709 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
8710 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
8711 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
8712 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
8713 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
8714 asc_dvc->max_sdtr_index = 7;
8715 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
8716 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
8717 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
8718 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
8719 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
8720 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
8721 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
8722 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
8723 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
8724 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
8725 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
8726 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
8727 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
8728 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
8729 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
8730 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
8731 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
8732 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
8733 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
8734 asc_dvc->max_sdtr_index = 15;
8735 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
8736 AscSetExtraControl(iop_base,
8737 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8738 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
8739 AscSetExtraControl(iop_base,
8740 (SEC_ACTIVE_NEGATE |
8741 SEC_ENABLE_FILTER));
8742 }
8743 }
8744 if (asc_dvc->bus_type == ASC_IS_PCI) {
8745 AscSetExtraControl(iop_base,
8746 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8747 }
1da177e4 8748
27c868c2 8749 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
1da177e4 8750#ifdef CONFIG_ISA
27c868c2 8751 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
59fcf844
MW
8752 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
8753 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
8754 asc_dvc->bus_type = ASC_IS_ISAPNP;
8755 }
27c868c2
MW
8756 asc_dvc->cfg->isa_dma_channel =
8757 (uchar)AscGetIsaDmaChannel(iop_base);
8758 }
1da177e4 8759#endif /* CONFIG_ISA */
27c868c2
MW
8760 for (i = 0; i <= ASC_MAX_TID; i++) {
8761 asc_dvc->cur_dvc_qng[i] = 0;
8762 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
8763 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
8764 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
8765 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
8766 }
8767 return (warn_code);
1da177e4
LT
8768}
8769
78e77d8b 8770static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 8771{
27c868c2
MW
8772 ASCEEP_CONFIG eep_config_buf;
8773 ASCEEP_CONFIG *eep_config;
8774 PortAddr iop_base;
8775 ushort chksum;
8776 ushort warn_code;
8777 ushort cfg_msw, cfg_lsw;
8778 int i;
8779 int write_eep = 0;
8780
8781 iop_base = asc_dvc->iop_base;
8782 warn_code = 0;
8783 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
8784 AscStopQueueExe(iop_base);
8785 if ((AscStopChip(iop_base) == FALSE) ||
8786 (AscGetChipScsiCtrl(iop_base) != 0)) {
8787 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
8788 AscResetChipAndScsiBus(asc_dvc);
b009bef6 8789 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
27c868c2
MW
8790 }
8791 if (AscIsChipHalted(iop_base) == FALSE) {
8792 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
8793 return (warn_code);
8794 }
8795 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
8796 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
8797 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
8798 return (warn_code);
8799 }
8800 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
8801 cfg_msw = AscGetChipCfgMsw(iop_base);
8802 cfg_lsw = AscGetChipCfgLsw(iop_base);
8803 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 8804 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
8805 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
8806 AscSetChipCfgMsw(iop_base, cfg_msw);
8807 }
8808 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
8809 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
8810 if (chksum == 0) {
8811 chksum = 0xaa55;
8812 }
8813 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
8814 warn_code |= ASC_WARN_AUTO_CONFIG;
8815 if (asc_dvc->cfg->chip_version == 3) {
8816 if (eep_config->cfg_lsw != cfg_lsw) {
8817 warn_code |= ASC_WARN_EEPROM_RECOVER;
8818 eep_config->cfg_lsw =
8819 AscGetChipCfgLsw(iop_base);
8820 }
8821 if (eep_config->cfg_msw != cfg_msw) {
8822 warn_code |= ASC_WARN_EEPROM_RECOVER;
8823 eep_config->cfg_msw =
8824 AscGetChipCfgMsw(iop_base);
8825 }
8826 }
8827 }
8828 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
8829 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
8830 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
8831 eep_config->chksum);
8832 if (chksum != eep_config->chksum) {
8833 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
8834 ASC_CHIP_VER_PCI_ULTRA_3050) {
8835 ASC_DBG(1,
8836 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
8837 eep_config->init_sdtr = 0xFF;
8838 eep_config->disc_enable = 0xFF;
8839 eep_config->start_motor = 0xFF;
8840 eep_config->use_cmd_qng = 0;
8841 eep_config->max_total_qng = 0xF0;
8842 eep_config->max_tag_qng = 0x20;
8843 eep_config->cntl = 0xBFFF;
8844 ASC_EEP_SET_CHIP_ID(eep_config, 7);
8845 eep_config->no_scam = 0;
8846 eep_config->adapter_info[0] = 0;
8847 eep_config->adapter_info[1] = 0;
8848 eep_config->adapter_info[2] = 0;
8849 eep_config->adapter_info[3] = 0;
8850 eep_config->adapter_info[4] = 0;
8851 /* Indicate EEPROM-less board. */
8852 eep_config->adapter_info[5] = 0xBB;
8853 } else {
8854 ASC_PRINT
8855 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
8856 write_eep = 1;
8857 warn_code |= ASC_WARN_EEPROM_CHKSUM;
8858 }
8859 }
8860 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
8861 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
8862 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
8863 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
8864 asc_dvc->start_motor = eep_config->start_motor;
8865 asc_dvc->dvc_cntl = eep_config->cntl;
8866 asc_dvc->no_scam = eep_config->no_scam;
8867 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
8868 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
8869 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
8870 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
8871 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
8872 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
8873 if (!AscTestExternalLram(asc_dvc)) {
8874 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
8875 ASC_IS_PCI_ULTRA)) {
8876 eep_config->max_total_qng =
8877 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
8878 eep_config->max_tag_qng =
8879 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
8880 } else {
8881 eep_config->cfg_msw |= 0x0800;
8882 cfg_msw |= 0x0800;
8883 AscSetChipCfgMsw(iop_base, cfg_msw);
8884 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
8885 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
8886 }
8887 } else {
8888 }
8889 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
8890 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
8891 }
8892 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
8893 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
8894 }
8895 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
8896 eep_config->max_tag_qng = eep_config->max_total_qng;
8897 }
8898 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
8899 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
8900 }
8901 asc_dvc->max_total_qng = eep_config->max_total_qng;
8902 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
8903 eep_config->use_cmd_qng) {
8904 eep_config->disc_enable = eep_config->use_cmd_qng;
8905 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
8906 }
8907 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
8908 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
8909 }
8910 ASC_EEP_SET_CHIP_ID(eep_config,
8911 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
8912 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
8913 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
8914 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
8915 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
8916 }
1da177e4 8917
27c868c2
MW
8918 for (i = 0; i <= ASC_MAX_TID; i++) {
8919 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
8920 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
8921 asc_dvc->cfg->sdtr_period_offset[i] =
8922 (uchar)(ASC_DEF_SDTR_OFFSET |
8923 (asc_dvc->host_init_sdtr_index << 4));
8924 }
8925 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
8926 if (write_eep) {
8927 if ((i =
8928 AscSetEEPConfig(iop_base, eep_config,
8929 asc_dvc->bus_type)) != 0) {
8930 ASC_PRINT1
8931 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
8932 i);
8933 } else {
8934 ASC_PRINT
8935 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
8936 }
8937 }
8938 return (warn_code);
1da177e4
LT
8939}
8940
27c868c2 8941static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8942{
27c868c2
MW
8943 int i;
8944 ushort warn_code;
8945 PortAddr iop_base;
8946 ASC_PADDR phy_addr;
8947 ASC_DCNT phy_size;
8948
8949 iop_base = asc_dvc->iop_base;
8950 warn_code = 0;
8951 for (i = 0; i <= ASC_MAX_TID; i++) {
8952 AscPutMCodeInitSDTRAtID(iop_base, i,
8953 asc_dvc->cfg->sdtr_period_offset[i]
8954 );
8955 }
1da177e4 8956
27c868c2
MW
8957 AscInitQLinkVar(asc_dvc);
8958 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
8959 asc_dvc->cfg->disc_enable);
8960 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
8961 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
8962
8963 /* Align overrun buffer on an 8 byte boundary. */
8964 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
8965 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
8966 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
8967 (uchar *)&phy_addr, 1);
8968 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
8969 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
8970 (uchar *)&phy_size, 1);
8971
8972 asc_dvc->cfg->mcode_date =
8973 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
8974 asc_dvc->cfg->mcode_version =
8975 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
8976
8977 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
8978 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
8979 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
8980 return (warn_code);
8981 }
8982 if (AscStartChip(iop_base) != 1) {
8983 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
8984 return (warn_code);
8985 }
1da177e4 8986
27c868c2 8987 return (warn_code);
1da177e4
LT
8988}
8989
78e77d8b 8990static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 8991{
27c868c2
MW
8992 PortAddr iop_base;
8993 ushort q_addr;
8994 ushort saved_word;
8995 int sta;
8996
8997 iop_base = asc_dvc->iop_base;
8998 sta = 0;
8999 q_addr = ASC_QNO_TO_QADDR(241);
9000 saved_word = AscReadLramWord(iop_base, q_addr);
9001 AscSetChipLramAddr(iop_base, q_addr);
9002 AscSetChipLramData(iop_base, 0x55AA);
b009bef6 9003 mdelay(10);
27c868c2
MW
9004 AscSetChipLramAddr(iop_base, q_addr);
9005 if (AscGetChipLramData(iop_base) == 0x55AA) {
9006 sta = 1;
9007 AscWriteLramWord(iop_base, q_addr, saved_word);
9008 }
9009 return (sta);
1da177e4
LT
9010}
9011
78e77d8b 9012static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 9013{
27c868c2
MW
9014 uchar read_back;
9015 int retry;
9016
9017 retry = 0;
9018 while (TRUE) {
9019 AscSetChipEEPCmd(iop_base, cmd_reg);
b009bef6 9020 mdelay(1);
27c868c2
MW
9021 read_back = AscGetChipEEPCmd(iop_base);
9022 if (read_back == cmd_reg) {
9023 return (1);
9024 }
9025 if (retry++ > ASC_EEP_MAX_RETRY) {
9026 return (0);
9027 }
9028 }
1da177e4
LT
9029}
9030
78e77d8b 9031static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 9032{
27c868c2
MW
9033 ushort read_back;
9034 int retry;
9035
9036 retry = 0;
9037 while (TRUE) {
9038 AscSetChipEEPData(iop_base, data_reg);
b009bef6 9039 mdelay(1);
27c868c2
MW
9040 read_back = AscGetChipEEPData(iop_base);
9041 if (read_back == data_reg) {
9042 return (1);
9043 }
9044 if (retry++ > ASC_EEP_MAX_RETRY) {
9045 return (0);
9046 }
9047 }
1da177e4
LT
9048}
9049
78e77d8b 9050static void __devinit AscWaitEEPRead(void)
1da177e4 9051{
b009bef6 9052 mdelay(1);
27c868c2 9053 return;
1da177e4
LT
9054}
9055
78e77d8b 9056static void __devinit AscWaitEEPWrite(void)
1da177e4 9057{
b009bef6 9058 mdelay(20);
27c868c2 9059 return;
1da177e4
LT
9060}
9061
78e77d8b 9062static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 9063{
27c868c2
MW
9064 ushort read_wval;
9065 uchar cmd_reg;
9066
9067 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9068 AscWaitEEPRead();
9069 cmd_reg = addr | ASC_EEP_CMD_READ;
9070 AscWriteEEPCmdReg(iop_base, cmd_reg);
9071 AscWaitEEPRead();
9072 read_wval = AscGetChipEEPData(iop_base);
9073 AscWaitEEPRead();
9074 return (read_wval);
1da177e4
LT
9075}
9076
78e77d8b 9077static ushort __devinit
27c868c2 9078AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 9079{
27c868c2
MW
9080 ushort read_wval;
9081
9082 read_wval = AscReadEEPWord(iop_base, addr);
9083 if (read_wval != word_val) {
9084 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
9085 AscWaitEEPRead();
9086 AscWriteEEPDataReg(iop_base, word_val);
9087 AscWaitEEPRead();
9088 AscWriteEEPCmdReg(iop_base,
9089 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
9090 AscWaitEEPWrite();
9091 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9092 AscWaitEEPRead();
9093 return (AscReadEEPWord(iop_base, addr));
9094 }
9095 return (read_wval);
1da177e4
LT
9096}
9097
78e77d8b 9098static ushort __devinit
27c868c2 9099AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9100{
27c868c2
MW
9101 ushort wval;
9102 ushort sum;
9103 ushort *wbuf;
9104 int cfg_beg;
9105 int cfg_end;
9106 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
9107 int s_addr;
9108
9109 wbuf = (ushort *)cfg_buf;
9110 sum = 0;
9111 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
9112 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9113 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
9114 sum += *wbuf;
9115 }
9116 if (bus_type & ASC_IS_VL) {
9117 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9118 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9119 } else {
9120 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9121 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9122 }
9123 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9124 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
9125 if (s_addr <= uchar_end_in_config) {
9126 /*
9127 * Swap all char fields - must unswap bytes already swapped
9128 * by AscReadEEPWord().
9129 */
9130 *wbuf = le16_to_cpu(wval);
9131 } else {
9132 /* Don't swap word field at the end - cntl field. */
9133 *wbuf = wval;
9134 }
9135 sum += wval; /* Checksum treats all EEPROM data as words. */
9136 }
9137 /*
9138 * Read the checksum word which will be compared against 'sum'
9139 * by the caller. Word field already swapped.
9140 */
9141 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
9142 return (sum);
1da177e4
LT
9143}
9144
78e77d8b 9145static int __devinit
27c868c2 9146AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9147{
27c868c2
MW
9148 int n_error;
9149 ushort *wbuf;
9150 ushort word;
9151 ushort sum;
9152 int s_addr;
9153 int cfg_beg;
9154 int cfg_end;
9155 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
9156
9157 wbuf = (ushort *)cfg_buf;
9158 n_error = 0;
9159 sum = 0;
9160 /* Write two config words; AscWriteEEPWord() will swap bytes. */
9161 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9162 sum += *wbuf;
9163 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9164 n_error++;
9165 }
9166 }
9167 if (bus_type & ASC_IS_VL) {
9168 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9169 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9170 } else {
9171 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9172 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9173 }
9174 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9175 if (s_addr <= uchar_end_in_config) {
9176 /*
9177 * This is a char field. Swap char fields before they are
9178 * swapped again by AscWriteEEPWord().
9179 */
9180 word = cpu_to_le16(*wbuf);
9181 if (word !=
9182 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
9183 n_error++;
9184 }
9185 } else {
9186 /* Don't swap word field at the end - cntl field. */
9187 if (*wbuf !=
9188 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9189 n_error++;
9190 }
9191 }
9192 sum += *wbuf; /* Checksum calculated from word values. */
9193 }
9194 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
9195 *wbuf = sum;
9196 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
9197 n_error++;
9198 }
1da177e4 9199
27c868c2
MW
9200 /* Read EEPROM back again. */
9201 wbuf = (ushort *)cfg_buf;
9202 /*
9203 * Read two config words; Byte-swapping done by AscReadEEPWord().
9204 */
9205 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9206 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
9207 n_error++;
9208 }
9209 }
9210 if (bus_type & ASC_IS_VL) {
9211 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9212 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9213 } else {
9214 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9215 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9216 }
9217 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9218 if (s_addr <= uchar_end_in_config) {
9219 /*
9220 * Swap all char fields. Must unswap bytes already swapped
9221 * by AscReadEEPWord().
9222 */
9223 word =
9224 le16_to_cpu(AscReadEEPWord
9225 (iop_base, (uchar)s_addr));
9226 } else {
9227 /* Don't swap word field at the end - cntl field. */
9228 word = AscReadEEPWord(iop_base, (uchar)s_addr);
9229 }
9230 if (*wbuf != word) {
9231 n_error++;
9232 }
9233 }
9234 /* Read checksum; Byte swapping not needed. */
9235 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
9236 n_error++;
9237 }
9238 return (n_error);
1da177e4
LT
9239}
9240
78e77d8b 9241static int __devinit
27c868c2 9242AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9243{
27c868c2
MW
9244 int retry;
9245 int n_error;
9246
9247 retry = 0;
9248 while (TRUE) {
9249 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
9250 bus_type)) == 0) {
9251 break;
9252 }
9253 if (++retry > ASC_EEP_MAX_RETRY) {
9254 break;
9255 }
9256 }
9257 return (n_error);
1da177e4
LT
9258}
9259
47d853cc 9260static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
1da177e4 9261{
47d853cc
MW
9262 char type = sdev->type;
9263 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
27c868c2
MW
9264
9265 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
9266 if (!(asc_dvc->init_sdtr & tid_bits)) {
47d853cc
MW
9267 if ((type == TYPE_ROM) &&
9268 (strncmp(sdev->vendor, "HP ", 3) == 0)) {
27c868c2
MW
9269 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9270 }
9271 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
47d853cc
MW
9272 if ((type == TYPE_PROCESSOR) ||
9273 (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
9274 (type == TYPE_TAPE)) {
27c868c2
MW
9275 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9276 }
9277
9278 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
9279 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
47d853cc
MW
9280 sdev->id,
9281 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
27c868c2
MW
9282 }
9283 }
9284 }
1da177e4
LT
9285}
9286
27c868c2 9287static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 9288{
27c868c2
MW
9289 uchar byte_data;
9290 ushort word_data;
9291
9292 if (isodd_word(addr)) {
9293 AscSetChipLramAddr(iop_base, addr - 1);
9294 word_data = AscGetChipLramData(iop_base);
9295 byte_data = (uchar)((word_data >> 8) & 0xFF);
9296 } else {
9297 AscSetChipLramAddr(iop_base, addr);
9298 word_data = AscGetChipLramData(iop_base);
9299 byte_data = (uchar)(word_data & 0xFF);
9300 }
9301 return (byte_data);
1da177e4 9302}
27c868c2
MW
9303
9304static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 9305{
27c868c2 9306 ushort word_data;
1da177e4 9307
27c868c2
MW
9308 AscSetChipLramAddr(iop_base, addr);
9309 word_data = AscGetChipLramData(iop_base);
9310 return (word_data);
1da177e4
LT
9311}
9312
9313#if CC_VERY_LONG_SG_LIST
27c868c2 9314static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 9315{
27c868c2
MW
9316 ushort val_low, val_high;
9317 ASC_DCNT dword_data;
9318
9319 AscSetChipLramAddr(iop_base, addr);
9320 val_low = AscGetChipLramData(iop_base);
9321 val_high = AscGetChipLramData(iop_base);
9322 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
9323 return (dword_data);
1da177e4
LT
9324}
9325#endif /* CC_VERY_LONG_SG_LIST */
9326
27c868c2 9327static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 9328{
27c868c2
MW
9329 AscSetChipLramAddr(iop_base, addr);
9330 AscSetChipLramData(iop_base, word_val);
9331 return;
1da177e4
LT
9332}
9333
27c868c2 9334static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 9335{
27c868c2
MW
9336 ushort word_data;
9337
9338 if (isodd_word(addr)) {
9339 addr--;
9340 word_data = AscReadLramWord(iop_base, addr);
9341 word_data &= 0x00FF;
9342 word_data |= (((ushort)byte_val << 8) & 0xFF00);
9343 } else {
9344 word_data = AscReadLramWord(iop_base, addr);
9345 word_data &= 0xFF00;
9346 word_data |= ((ushort)byte_val & 0x00FF);
9347 }
9348 AscWriteLramWord(iop_base, addr, word_data);
9349 return;
1da177e4
LT
9350}
9351
9352/*
9353 * Copy 2 bytes to LRAM.
9354 *
9355 * The source data is assumed to be in little-endian order in memory
9356 * and is maintained in little-endian order when written to LRAM.
9357 */
27c868c2
MW
9358static void
9359AscMemWordCopyPtrToLram(PortAddr iop_base,
9360 ushort s_addr, uchar *s_buffer, int words)
1da177e4 9361{
27c868c2
MW
9362 int i;
9363
9364 AscSetChipLramAddr(iop_base, s_addr);
9365 for (i = 0; i < 2 * words; i += 2) {
9366 /*
9367 * On a little-endian system the second argument below
9368 * produces a little-endian ushort which is written to
9369 * LRAM in little-endian order. On a big-endian system
9370 * the second argument produces a big-endian ushort which
9371 * is "transparently" byte-swapped by outpw() and written
9372 * in little-endian order to LRAM.
9373 */
9374 outpw(iop_base + IOP_RAM_DATA,
9375 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
9376 }
9377 return;
1da177e4
LT
9378}
9379
9380/*
9381 * Copy 4 bytes to LRAM.
9382 *
9383 * The source data is assumed to be in little-endian order in memory
9384 * and is maintained in little-endian order when writen to LRAM.
9385 */
27c868c2
MW
9386static void
9387AscMemDWordCopyPtrToLram(PortAddr iop_base,
9388 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 9389{
27c868c2
MW
9390 int i;
9391
9392 AscSetChipLramAddr(iop_base, s_addr);
9393 for (i = 0; i < 4 * dwords; i += 4) {
9394 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
9395 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
9396 }
9397 return;
1da177e4
LT
9398}
9399
9400/*
9401 * Copy 2 bytes from LRAM.
9402 *
9403 * The source data is assumed to be in little-endian order in LRAM
9404 * and is maintained in little-endian order when written to memory.
9405 */
27c868c2
MW
9406static void
9407AscMemWordCopyPtrFromLram(PortAddr iop_base,
9408 ushort s_addr, uchar *d_buffer, int words)
1da177e4 9409{
27c868c2
MW
9410 int i;
9411 ushort word;
9412
9413 AscSetChipLramAddr(iop_base, s_addr);
9414 for (i = 0; i < 2 * words; i += 2) {
9415 word = inpw(iop_base + IOP_RAM_DATA);
9416 d_buffer[i] = word & 0xff;
9417 d_buffer[i + 1] = (word >> 8) & 0xff;
9418 }
9419 return;
1da177e4
LT
9420}
9421
27c868c2 9422static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 9423{
27c868c2
MW
9424 ASC_DCNT sum;
9425 int i;
1da177e4 9426
27c868c2
MW
9427 sum = 0L;
9428 for (i = 0; i < words; i++, s_addr += 2) {
9429 sum += AscReadLramWord(iop_base, s_addr);
9430 }
9431 return (sum);
1da177e4
LT
9432}
9433
27c868c2
MW
9434static void
9435AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 9436{
27c868c2 9437 int i;
1da177e4 9438
27c868c2
MW
9439 AscSetChipLramAddr(iop_base, s_addr);
9440 for (i = 0; i < words; i++) {
9441 AscSetChipLramData(iop_base, set_wval);
9442 }
9443 return;
1da177e4
LT
9444}
9445
1da177e4
LT
9446/*
9447 * --- Adv Library Functions
9448 */
9449
9450/* a_mcode.h */
9451
9452/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9453static unsigned char _adv_asc3550_buf[] = {
9454 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
629d688d
MW
9455 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
9456 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
9457 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
27c868c2 9458 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
629d688d
MW
9459 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
9460 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
9461 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
27c868c2 9462 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
629d688d
MW
9463 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
9464 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
9465 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
27c868c2 9466 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
629d688d
MW
9467 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
9468 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
9469 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
27c868c2 9470 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
629d688d
MW
9471 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
9472 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
9473 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
27c868c2 9474 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
629d688d
MW
9475 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
9476 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
9477 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
27c868c2 9478 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
629d688d
MW
9479 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
9480 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
9481 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
27c868c2 9482 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
629d688d
MW
9483 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
9484 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
9485 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
27c868c2 9486 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
629d688d
MW
9487 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
9488 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
9489 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
27c868c2 9490 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
629d688d
MW
9491 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
9492 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
9493 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
27c868c2 9494 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
629d688d
MW
9495 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
9496 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
9497 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
27c868c2 9498 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
9499 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
9500 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
9501 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
27c868c2 9502 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
9503 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
9504 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
9505 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
27c868c2 9506 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
629d688d
MW
9507 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
9508 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
9509 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
27c868c2 9510 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
629d688d
MW
9511 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
9512 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
9513 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
27c868c2 9514 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
629d688d
MW
9515 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
9516 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
9517 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
27c868c2 9518 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
9519 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
9520 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
9521 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
27c868c2 9522 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
629d688d
MW
9523 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
9524 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
9525 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
27c868c2 9526 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
629d688d
MW
9527 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
9528 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
9529 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
27c868c2 9530 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
629d688d
MW
9531 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
9532 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
9533 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
27c868c2 9534 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
629d688d
MW
9535 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
9536 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
9537 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
27c868c2 9538 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
629d688d
MW
9539 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
9540 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
9541 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
27c868c2 9542 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
629d688d
MW
9543 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
9544 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
9545 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
27c868c2 9546 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
629d688d
MW
9547 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
9548 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
9549 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
27c868c2 9550 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
629d688d
MW
9551 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
9552 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
9553 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
27c868c2 9554 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
629d688d
MW
9555 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
9556 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
9557 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
27c868c2 9558 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
629d688d
MW
9559 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
9560 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
9561 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
27c868c2 9562 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
629d688d
MW
9563 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
9564 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
9565 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
27c868c2 9566 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
629d688d
MW
9567 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
9568 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
9569 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
27c868c2 9570 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
629d688d
MW
9571 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
9572 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
9573 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
27c868c2 9574 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
629d688d
MW
9575 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
9576 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
9577 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
27c868c2 9578 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
629d688d
MW
9579 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
9580 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
9581 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
27c868c2 9582 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
629d688d
MW
9583 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
9584 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
9585 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
27c868c2 9586 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
629d688d
MW
9587 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
9588 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
9589 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
27c868c2 9590 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
629d688d
MW
9591 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
9592 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
9593 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
27c868c2 9594 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
629d688d
MW
9595 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
9596 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
9597 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
27c868c2 9598 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
629d688d
MW
9599 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
9600 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
9601 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
27c868c2 9602 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
629d688d
MW
9603 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
9604 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
9605 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
27c868c2 9606 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
629d688d
MW
9607 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
9608 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
9609 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
27c868c2 9610 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
629d688d
MW
9611 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
9612 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
9613 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
27c868c2 9614 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
629d688d
MW
9615 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
9616 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
9617 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
27c868c2 9618 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
629d688d
MW
9619 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
9620 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
9621 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
27c868c2 9622 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
629d688d
MW
9623 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
9624 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
9625 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
27c868c2 9626 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
629d688d
MW
9627 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
9628 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
9629 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
27c868c2 9630 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
629d688d
MW
9631 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
9632 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
9633 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
27c868c2 9634 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
629d688d
MW
9635 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
9636 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
9637 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
27c868c2 9638 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
629d688d
MW
9639 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
9640 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
9641 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
27c868c2 9642 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
629d688d
MW
9643 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
9644 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
9645 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
27c868c2 9646 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
629d688d
MW
9647 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
9648 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
9649 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
27c868c2 9650 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
629d688d
MW
9651 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
9652 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
9653 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
27c868c2 9654 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
629d688d
MW
9655 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
9656 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
9657 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
27c868c2 9658 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
629d688d
MW
9659 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
9660 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
9661 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
27c868c2 9662 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
629d688d
MW
9663 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
9664 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
9665 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
27c868c2 9666 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
629d688d
MW
9667 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
9668 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
9669 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
27c868c2 9670 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
629d688d
MW
9671 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
9672 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
9673 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
27c868c2 9674 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
629d688d
MW
9675 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
9676 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
9677 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
27c868c2 9678 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
629d688d
MW
9679 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
9680 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
9681 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
27c868c2 9682 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
629d688d
MW
9683 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
9684 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
9685 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
27c868c2 9686 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
629d688d
MW
9687 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
9688 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
9689 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
27c868c2 9690 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
629d688d
MW
9691 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
9692 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
9693 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
27c868c2 9694 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
629d688d
MW
9695 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
9696 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
9697 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
27c868c2 9698 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
629d688d
MW
9699 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
9700 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
9701 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
27c868c2 9702 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
629d688d
MW
9703 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
9704 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
9705 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
27c868c2 9706 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
629d688d
MW
9707 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
9708 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
9709 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
27c868c2 9710 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
629d688d
MW
9711 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
9712 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
9713 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
27c868c2 9714 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
629d688d
MW
9715 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
9716 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
9717 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
27c868c2 9718 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
629d688d
MW
9719 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
9720 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
9721 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
27c868c2 9722 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
629d688d
MW
9723 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
9724 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
9725 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
27c868c2 9726 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
629d688d
MW
9727 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
9728 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
9729 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
27c868c2 9730 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
629d688d
MW
9731 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
9732 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
9733 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
27c868c2 9734 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
629d688d
MW
9735 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
9736 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
9737 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
27c868c2 9738 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
629d688d
MW
9739 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
9740 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
9741 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
27c868c2 9742 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
629d688d
MW
9743 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
9744 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
9745 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
27c868c2 9746 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
629d688d
MW
9747 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
9748 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
9749 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
27c868c2 9750 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
629d688d
MW
9751 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
9752 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
9753 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
27c868c2 9754 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
629d688d
MW
9755 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
9756 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
9757 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
27c868c2 9758 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
629d688d
MW
9759 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
9760 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
9761 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
27c868c2 9762 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
629d688d
MW
9763 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
9764 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
9765 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
27c868c2 9766 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
629d688d
MW
9767 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
9768 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
9769 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
27c868c2 9770 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
629d688d
MW
9771 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
9772 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
9773 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
27c868c2 9774 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
629d688d
MW
9775 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
9776 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
9777 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
27c868c2 9778 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
629d688d
MW
9779 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
9780 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
9781 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
27c868c2 9782 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
629d688d
MW
9783 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
9784 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
9785 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
27c868c2 9786 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
629d688d
MW
9787 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
9788 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
9789 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
27c868c2 9790 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
629d688d
MW
9791 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
9792 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
9793 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
27c868c2 9794 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
629d688d
MW
9795 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
9796 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
9797 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
27c868c2 9798 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
629d688d
MW
9799 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
9800 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
9801 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
27c868c2 9802 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
629d688d
MW
9803 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
9804 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
9805 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
27c868c2 9806 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
629d688d
MW
9807 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
9808 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
9809 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
27c868c2 9810 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
629d688d
MW
9811 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
9812 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
9813 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
27c868c2 9814 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
629d688d
MW
9815 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
9816 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
9817 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
27c868c2 9818 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
629d688d
MW
9819 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
9820 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
9821 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
27c868c2 9822 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
629d688d
MW
9823 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
9824 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
9825 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
27c868c2 9826 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
629d688d
MW
9827 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
9828 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
9829 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
27c868c2 9830 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
629d688d
MW
9831 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
9832 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
9833 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
27c868c2 9834 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
629d688d
MW
9835 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
9836 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
9837 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
27c868c2 9838 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
629d688d
MW
9839 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
9840 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
9841 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
27c868c2 9842 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
629d688d
MW
9843 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
9844 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
9845 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
27c868c2 9846 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
629d688d
MW
9847 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
9848 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
9849 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
27c868c2 9850 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
629d688d
MW
9851 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
9852 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
9853 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
27c868c2 9854 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
629d688d
MW
9855 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
9856 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
9857 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
27c868c2 9858 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
629d688d
MW
9859 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
9860 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
9861 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
27c868c2 9862 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
629d688d
MW
9863 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
9864 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
9865 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
27c868c2 9866 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
629d688d
MW
9867 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
9868 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
9869 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
27c868c2 9870 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
629d688d
MW
9871 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
9872 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
1da177e4
LT
9873};
9874
27c868c2
MW
9875static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
9876static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
9877
9878/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9879static unsigned char _adv_asc38C0800_buf[] = {
9880 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
629d688d
MW
9881 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
9882 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
9883 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
27c868c2 9884 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
629d688d
MW
9885 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
9886 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
9887 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
27c868c2 9888 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
629d688d
MW
9889 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
9890 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
9891 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
27c868c2 9892 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
629d688d
MW
9893 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
9894 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
9895 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
27c868c2 9896 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
629d688d
MW
9897 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
9898 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
9899 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
27c868c2 9900 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
629d688d
MW
9901 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
9902 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
9903 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
27c868c2 9904 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
629d688d
MW
9905 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
9906 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
9907 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
27c868c2 9908 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
629d688d
MW
9909 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
9910 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
9911 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
27c868c2 9912 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
629d688d
MW
9913 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
9914 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
9915 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
27c868c2 9916 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
629d688d
MW
9917 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
9918 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
9919 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
27c868c2 9920 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
629d688d
MW
9921 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
9922 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
9923 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
27c868c2 9924 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
9925 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
9926 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
9927 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
27c868c2 9928 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
9929 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
9930 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
9931 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
27c868c2 9932 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
629d688d
MW
9933 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
9934 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
9935 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
27c868c2 9936 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
629d688d
MW
9937 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
9938 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
9939 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
27c868c2 9940 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
629d688d
MW
9941 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
9942 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
9943 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
27c868c2 9944 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
9945 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
9946 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
9947 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
27c868c2 9948 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
629d688d
MW
9949 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
9950 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
9951 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
27c868c2 9952 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
629d688d
MW
9953 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
9954 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
9955 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
27c868c2 9956 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
629d688d
MW
9957 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
9958 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
9959 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
27c868c2 9960 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
629d688d
MW
9961 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
9962 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
9963 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
27c868c2 9964 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
629d688d
MW
9965 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
9966 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
9967 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
27c868c2 9968 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
629d688d
MW
9969 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
9970 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
9971 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
27c868c2 9972 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
629d688d
MW
9973 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
9974 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
9975 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
27c868c2 9976 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
629d688d
MW
9977 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
9978 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
9979 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
27c868c2 9980 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
629d688d
MW
9981 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
9982 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
9983 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
27c868c2 9984 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
629d688d
MW
9985 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
9986 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
9987 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
27c868c2 9988 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
629d688d
MW
9989 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
9990 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
9991 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
27c868c2 9992 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
629d688d
MW
9993 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
9994 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
9995 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
27c868c2 9996 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
629d688d
MW
9997 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
9998 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
9999 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
27c868c2 10000 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
629d688d
MW
10001 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
10002 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
10003 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
27c868c2 10004 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
629d688d
MW
10005 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
10006 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
10007 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
27c868c2 10008 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
629d688d
MW
10009 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
10010 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
10011 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
27c868c2 10012 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
629d688d
MW
10013 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
10014 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
10015 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
27c868c2 10016 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
629d688d
MW
10017 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
10018 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
10019 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
27c868c2 10020 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
629d688d
MW
10021 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
10022 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
10023 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
27c868c2 10024 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
629d688d
MW
10025 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
10026 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
10027 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
27c868c2 10028 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
629d688d
MW
10029 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
10030 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
10031 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
27c868c2 10032 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
629d688d
MW
10033 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
10034 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
10035 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
27c868c2 10036 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
629d688d
MW
10037 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
10038 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
10039 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
27c868c2 10040 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
629d688d
MW
10041 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
10042 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
10043 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
27c868c2 10044 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
629d688d
MW
10045 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
10046 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
10047 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
27c868c2 10048 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
629d688d
MW
10049 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
10050 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
10051 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
27c868c2 10052 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
629d688d
MW
10053 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
10054 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
10055 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
27c868c2 10056 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
629d688d
MW
10057 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
10058 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
10059 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
27c868c2 10060 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
629d688d
MW
10061 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
10062 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
10063 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
27c868c2 10064 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
629d688d
MW
10065 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
10066 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
10067 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
27c868c2 10068 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
629d688d
MW
10069 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
10070 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
10071 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
27c868c2 10072 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
629d688d
MW
10073 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
10074 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
10075 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
27c868c2 10076 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
629d688d
MW
10077 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
10078 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
10079 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
27c868c2 10080 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
629d688d
MW
10081 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
10082 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
10083 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
27c868c2 10084 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
629d688d
MW
10085 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
10086 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
10087 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
27c868c2 10088 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
629d688d
MW
10089 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
10090 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
10091 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
27c868c2 10092 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
629d688d
MW
10093 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
10094 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
10095 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
27c868c2 10096 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
629d688d
MW
10097 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
10098 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
10099 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
27c868c2 10100 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
629d688d
MW
10101 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
10102 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
10103 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
27c868c2 10104 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
629d688d
MW
10105 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
10106 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
10107 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
27c868c2 10108 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
629d688d
MW
10109 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
10110 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
10111 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
27c868c2 10112 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
629d688d
MW
10113 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
10114 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
10115 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
27c868c2 10116 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
629d688d
MW
10117 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
10118 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
10119 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
27c868c2 10120 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
629d688d
MW
10121 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
10122 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
10123 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
27c868c2 10124 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
629d688d
MW
10125 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
10126 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
10127 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
27c868c2 10128 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
629d688d
MW
10129 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
10130 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
10131 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
27c868c2 10132 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
629d688d
MW
10133 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
10134 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
10135 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
27c868c2 10136 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
629d688d
MW
10137 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
10138 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
10139 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
27c868c2 10140 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
629d688d
MW
10141 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
10142 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
10143 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
27c868c2 10144 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
629d688d
MW
10145 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
10146 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
10147 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
27c868c2 10148 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
629d688d
MW
10149 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
10150 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
10151 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
27c868c2 10152 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
629d688d
MW
10153 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
10154 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
10155 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
27c868c2 10156 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
629d688d
MW
10157 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
10158 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
10159 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
27c868c2 10160 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
629d688d
MW
10161 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
10162 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
10163 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
27c868c2 10164 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
629d688d
MW
10165 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
10166 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
10167 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
27c868c2 10168 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
629d688d
MW
10169 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
10170 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
10171 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
27c868c2 10172 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
629d688d
MW
10173 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
10174 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
10175 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
27c868c2 10176 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
629d688d
MW
10177 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
10178 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
10179 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
27c868c2 10180 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
629d688d
MW
10181 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
10182 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
10183 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
27c868c2 10184 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
629d688d
MW
10185 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
10186 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
10187 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
27c868c2 10188 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
629d688d
MW
10189 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
10190 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
10191 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
27c868c2 10192 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
629d688d
MW
10193 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
10194 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
10195 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
27c868c2 10196 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
629d688d
MW
10197 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
10198 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
10199 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
27c868c2 10200 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
629d688d
MW
10201 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
10202 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
10203 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
27c868c2 10204 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
629d688d
MW
10205 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
10206 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
10207 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
27c868c2 10208 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
629d688d
MW
10209 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
10210 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
10211 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
27c868c2 10212 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
629d688d
MW
10213 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
10214 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
10215 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
27c868c2 10216 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
629d688d
MW
10217 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
10218 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
10219 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
27c868c2 10220 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
629d688d
MW
10221 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
10222 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
10223 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
27c868c2 10224 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
629d688d
MW
10225 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
10226 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10227 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
27c868c2 10228 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
629d688d
MW
10229 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10230 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
10231 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
27c868c2 10232 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
629d688d
MW
10233 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
10234 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
10235 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
27c868c2 10236 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
629d688d
MW
10237 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
10238 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
10239 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
27c868c2 10240 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
629d688d
MW
10241 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
10242 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
10243 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
27c868c2 10244 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
629d688d
MW
10245 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
10246 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
10247 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
27c868c2 10248 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
629d688d
MW
10249 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
10250 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
10251 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
27c868c2 10252 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
629d688d
MW
10253 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
10254 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
10255 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
27c868c2 10256 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
629d688d
MW
10257 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
10258 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
10259 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
27c868c2 10260 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
629d688d
MW
10261 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
10262 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
10263 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
27c868c2 10264 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
629d688d
MW
10265 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
10266 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
10267 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
27c868c2 10268 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
629d688d
MW
10269 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
10270 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
10271 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
27c868c2 10272 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
629d688d
MW
10273 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
10274 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
10275 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
27c868c2 10276 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
629d688d
MW
10277 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
10278 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
10279 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
27c868c2 10280 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
629d688d
MW
10281 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
10282 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
10283 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
27c868c2 10284 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
629d688d
MW
10285 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
10286 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
10287 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
27c868c2 10288 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
629d688d
MW
10289 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
10290 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
10291 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
27c868c2 10292 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
629d688d
MW
10293 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
10294 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
10295 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
27c868c2 10296 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
629d688d
MW
10297 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
10298 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
10299 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
27c868c2 10300 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
629d688d
MW
10301 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
10302 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
10303 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
27c868c2 10304 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
629d688d
MW
10305 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
10306 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
10307 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
27c868c2 10308 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
629d688d
MW
10309 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
10310 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
10311 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
27c868c2 10312 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
629d688d
MW
10313 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
10314 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
10315 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
27c868c2 10316 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
629d688d
MW
10317 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
10318 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
10319 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
27c868c2 10320 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
629d688d
MW
10321 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
10322 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
10323 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
27c868c2 10324 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
10325};
10326
27c868c2
MW
10327static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
10328static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
10329
10330/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
10331static unsigned char _adv_asc38C1600_buf[] = {
10332 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
629d688d
MW
10333 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
10334 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
10335 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
27c868c2 10336 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
629d688d
MW
10337 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
10338 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
10339 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
27c868c2 10340 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
629d688d
MW
10341 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
10342 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
10343 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
27c868c2 10344 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
629d688d
MW
10345 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
10346 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
10347 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
27c868c2 10348 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
629d688d
MW
10349 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
10350 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
10351 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
27c868c2 10352 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
629d688d
MW
10353 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
10354 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
10355 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
27c868c2 10356 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
629d688d
MW
10357 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
10358 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
10359 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
27c868c2 10360 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
629d688d
MW
10361 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
10362 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
10363 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
27c868c2 10364 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
629d688d
MW
10365 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
10366 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
10367 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
27c868c2 10368 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
629d688d
MW
10369 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
10370 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
10371 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
27c868c2 10372 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
629d688d
MW
10373 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
10374 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
10375 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
27c868c2 10376 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
10377 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
10378 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
10379 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
27c868c2 10380 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
10381 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
10382 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
10383 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
27c868c2 10384 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
629d688d
MW
10385 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
10386 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
10387 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
27c868c2 10388 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
629d688d
MW
10389 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
10390 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
10391 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
27c868c2 10392 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
629d688d
MW
10393 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
10394 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
10395 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
27c868c2 10396 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
629d688d
MW
10397 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
10398 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
10399 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
27c868c2 10400 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
629d688d
MW
10401 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
10402 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
10403 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
27c868c2 10404 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
629d688d
MW
10405 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
10406 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
10407 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
27c868c2 10408 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
629d688d
MW
10409 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
10410 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
10411 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
27c868c2 10412 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
629d688d
MW
10413 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
10414 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
10415 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
27c868c2 10416 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
629d688d
MW
10417 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
10418 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
10419 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
27c868c2 10420 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
629d688d
MW
10421 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
10422 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
10423 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
27c868c2 10424 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
629d688d
MW
10425 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
10426 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
10427 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
27c868c2 10428 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
629d688d
MW
10429 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
10430 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
10431 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
27c868c2 10432 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
629d688d
MW
10433 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
10434 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
10435 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
27c868c2 10436 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
629d688d
MW
10437 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
10438 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
10439 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
27c868c2 10440 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
629d688d
MW
10441 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
10442 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
10443 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
27c868c2 10444 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
629d688d
MW
10445 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
10446 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
10447 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
27c868c2 10448 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
629d688d
MW
10449 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
10450 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
10451 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
27c868c2 10452 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
629d688d
MW
10453 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
10454 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
10455 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
27c868c2 10456 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
629d688d
MW
10457 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
10458 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
10459 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
27c868c2 10460 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
629d688d
MW
10461 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
10462 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
10463 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
27c868c2 10464 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
629d688d
MW
10465 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
10466 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
10467 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
27c868c2 10468 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
629d688d
MW
10469 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
10470 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
10471 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
27c868c2 10472 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
629d688d
MW
10473 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
10474 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
10475 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
27c868c2 10476 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
629d688d
MW
10477 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
10478 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
10479 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
27c868c2 10480 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
629d688d
MW
10481 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
10482 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
10483 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
27c868c2 10484 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
629d688d
MW
10485 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
10486 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
10487 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
27c868c2 10488 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
629d688d
MW
10489 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
10490 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
10491 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
27c868c2 10492 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
629d688d
MW
10493 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
10494 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
10495 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
27c868c2 10496 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
629d688d
MW
10497 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
10498 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
10499 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 10500 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
629d688d
MW
10501 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
10502 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
10503 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
27c868c2 10504 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
629d688d
MW
10505 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
10506 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
10507 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 10508 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
629d688d
MW
10509 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
10510 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
10511 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
27c868c2 10512 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
629d688d
MW
10513 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
10514 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
10515 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
27c868c2 10516 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
629d688d
MW
10517 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
10518 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
10519 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
27c868c2 10520 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
629d688d
MW
10521 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
10522 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
10523 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
27c868c2 10524 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
629d688d
MW
10525 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
10526 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
10527 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
27c868c2 10528 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
629d688d
MW
10529 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
10530 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
10531 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
27c868c2 10532 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
629d688d
MW
10533 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
10534 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
10535 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
27c868c2 10536 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
629d688d
MW
10537 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
10538 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
10539 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
27c868c2 10540 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
629d688d
MW
10541 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
10542 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
10543 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
27c868c2 10544 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
629d688d
MW
10545 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
10546 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
10547 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
27c868c2 10548 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
629d688d
MW
10549 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
10550 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
10551 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
27c868c2 10552 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
629d688d
MW
10553 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
10554 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
10555 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
27c868c2 10556 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
629d688d
MW
10557 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
10558 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
10559 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
27c868c2 10560 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
629d688d
MW
10561 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
10562 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
10563 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
27c868c2 10564 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
629d688d
MW
10565 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
10566 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
10567 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
27c868c2 10568 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
629d688d
MW
10569 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
10570 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
10571 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
27c868c2 10572 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
629d688d
MW
10573 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
10574 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
10575 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
27c868c2 10576 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
629d688d
MW
10577 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
10578 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
10579 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
27c868c2 10580 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
629d688d
MW
10581 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
10582 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
10583 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
27c868c2 10584 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
629d688d
MW
10585 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
10586 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
10587 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
27c868c2 10588 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
629d688d
MW
10589 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
10590 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
10591 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
27c868c2 10592 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
629d688d
MW
10593 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
10594 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
10595 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
27c868c2 10596 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
629d688d
MW
10597 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
10598 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
10599 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
27c868c2 10600 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
629d688d
MW
10601 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
10602 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
10603 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
27c868c2 10604 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
629d688d
MW
10605 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
10606 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
10607 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
27c868c2 10608 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
629d688d
MW
10609 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
10610 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
10611 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
27c868c2 10612 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
629d688d
MW
10613 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
10614 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
10615 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
27c868c2 10616 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
629d688d
MW
10617 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
10618 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
10619 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
27c868c2 10620 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
629d688d
MW
10621 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
10622 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
10623 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
27c868c2 10624 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
629d688d
MW
10625 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
10626 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
10627 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
27c868c2 10628 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
629d688d
MW
10629 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
10630 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
10631 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
27c868c2 10632 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
629d688d
MW
10633 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
10634 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
10635 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
27c868c2 10636 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
629d688d
MW
10637 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
10638 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
10639 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
27c868c2 10640 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
629d688d
MW
10641 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
10642 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
10643 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
27c868c2 10644 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
629d688d
MW
10645 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
10646 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
10647 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
27c868c2 10648 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
629d688d
MW
10649 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
10650 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
10651 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
27c868c2 10652 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
629d688d
MW
10653 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
10654 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
10655 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
27c868c2 10656 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
629d688d
MW
10657 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
10658 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
10659 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
27c868c2 10660 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
629d688d
MW
10661 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
10662 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
10663 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
27c868c2 10664 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
629d688d
MW
10665 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
10666 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
10667 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
27c868c2 10668 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
629d688d
MW
10669 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
10670 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
10671 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
27c868c2 10672 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
629d688d
MW
10673 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
10674 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
10675 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
27c868c2 10676 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
629d688d
MW
10677 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
10678 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
10679 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
27c868c2 10680 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
629d688d
MW
10681 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
10682 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
10683 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
27c868c2 10684 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
629d688d
MW
10685 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
10686 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
10687 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
27c868c2 10688 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
629d688d
MW
10689 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
10690 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
10691 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
27c868c2 10692 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
629d688d
MW
10693 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
10694 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
10695 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
27c868c2 10696 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
629d688d
MW
10697 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
10698 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
10699 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
27c868c2 10700 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
629d688d
MW
10701 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
10702 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
10703 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
27c868c2 10704 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
629d688d
MW
10705 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
10706 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
10707 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
27c868c2 10708 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
629d688d
MW
10709 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
10710 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
10711 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
27c868c2 10712 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
629d688d
MW
10713 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
10714 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
10715 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
27c868c2 10716 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
629d688d
MW
10717 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
10718 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
10719 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
27c868c2 10720 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
629d688d
MW
10721 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
10722 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
10723 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
27c868c2 10724 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
629d688d
MW
10725 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
10726 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
10727 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
27c868c2 10728 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
629d688d
MW
10729 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
10730 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
10731 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
27c868c2 10732 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
629d688d
MW
10733 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
10734 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
10735 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
27c868c2 10736 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
629d688d
MW
10737 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
10738 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
10739 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
27c868c2 10740 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
629d688d
MW
10741 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
10742 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
10743 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
27c868c2 10744 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
629d688d
MW
10745 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
10746 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
10747 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
27c868c2 10748 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
629d688d
MW
10749 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
10750 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
10751 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
27c868c2 10752 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
629d688d
MW
10753 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
10754 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
10755 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
27c868c2 10756 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
629d688d
MW
10757 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
10758 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
10759 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
27c868c2 10760 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
629d688d
MW
10761 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
10762 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
10763 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
27c868c2 10764 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
629d688d
MW
10765 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
10766 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
10767 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
27c868c2 10768 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
629d688d
MW
10769 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
10770 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
10771 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
27c868c2 10772 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
629d688d
MW
10773 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
10774 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
10775 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
27c868c2 10776 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
629d688d
MW
10777 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
10778 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
10779 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
27c868c2 10780 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
629d688d
MW
10781 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
10782 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
10783 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
27c868c2 10784 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
629d688d
MW
10785 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
10786 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
10787 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
27c868c2 10788 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
629d688d
MW
10789 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
10790 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
10791 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
27c868c2 10792 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
629d688d
MW
10793 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
10794 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
10795 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
27c868c2 10796 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
629d688d
MW
10797 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
10798 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
10799 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
27c868c2 10800 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
629d688d
MW
10801 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
10802 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
10803 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
27c868c2 10804 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
629d688d
MW
10805 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
10806 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
10807 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
27c868c2 10808 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
629d688d
MW
10809 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
10810 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
10811 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
27c868c2 10812 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
629d688d
MW
10813 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
10814 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
10815 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
27c868c2 10816 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
629d688d
MW
10817 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
10818 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
10819 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
27c868c2 10820 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
629d688d
MW
10821 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
10822 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
10823 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
27c868c2 10824 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
629d688d
MW
10825 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
10826 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
10827 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
27c868c2 10828 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
629d688d
MW
10829 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
10830 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
10831 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
27c868c2 10832 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
629d688d
MW
10833 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
10834 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
10835 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
27c868c2 10836 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
629d688d
MW
10837 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
10838 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
10839 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
27c868c2 10840 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
629d688d
MW
10841 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
10842 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
10843 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
27c868c2 10844 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
629d688d
MW
10845 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
10846 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
10847 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
27c868c2 10848 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
629d688d
MW
10849 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
10850 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
10851 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 10852 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
10853 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
10854 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
10855 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 10856 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
10857 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
10858 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
10859 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
10860};
10861
27c868c2
MW
10862static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
10863static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4 10864
1da177e4
LT
10865/*
10866 * EEPROM Configuration.
10867 *
10868 * All drivers should use this structure to set the default EEPROM
10869 * configuration. The BIOS now uses this structure when it is built.
10870 * Additional structure information can be found in a_condor.h where
10871 * the structure is defined.
10872 *
10873 * The *_Field_IsChar structs are needed to correct for endianness.
10874 * These values are read from the board 16 bits at a time directly
10875 * into the structs. Because some fields are char, the values will be
10876 * in the wrong order. The *_Field_IsChar tells when to flip the
10877 * bytes. Data read and written to PCI memory is automatically swapped
10878 * on big-endian platforms so char fields read as words are actually being
10879 * unswapped on big-endian platforms.
10880 */
78e77d8b 10881static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
27c868c2
MW
10882 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
10883 0x0000, /* cfg_msw */
10884 0xFFFF, /* disc_enable */
10885 0xFFFF, /* wdtr_able */
10886 0xFFFF, /* sdtr_able */
10887 0xFFFF, /* start_motor */
10888 0xFFFF, /* tagqng_able */
10889 0xFFFF, /* bios_scan */
10890 0, /* scam_tolerant */
10891 7, /* adapter_scsi_id */
10892 0, /* bios_boot_delay */
10893 3, /* scsi_reset_delay */
10894 0, /* bios_id_lun */
10895 0, /* termination */
10896 0, /* reserved1 */
10897 0xFFE7, /* bios_ctrl */
10898 0xFFFF, /* ultra_able */
10899 0, /* reserved2 */
10900 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
10901 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
10902 0, /* dvc_cntl */
10903 0, /* bug_fix */
10904 0, /* serial_number_word1 */
10905 0, /* serial_number_word2 */
10906 0, /* serial_number_word3 */
10907 0, /* check_sum */
10908 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
10909 , /* oem_name[16] */
10910 0, /* dvc_err_code */
10911 0, /* adv_err_code */
10912 0, /* adv_err_addr */
10913 0, /* saved_dvc_err_code */
10914 0, /* saved_adv_err_code */
10915 0, /* saved_adv_err_addr */
10916 0 /* num_of_err */
1da177e4
LT
10917};
10918
78e77d8b 10919static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
27c868c2
MW
10920 0, /* cfg_lsw */
10921 0, /* cfg_msw */
10922 0, /* -disc_enable */
10923 0, /* wdtr_able */
10924 0, /* sdtr_able */
10925 0, /* start_motor */
10926 0, /* tagqng_able */
10927 0, /* bios_scan */
10928 0, /* scam_tolerant */
10929 1, /* adapter_scsi_id */
10930 1, /* bios_boot_delay */
10931 1, /* scsi_reset_delay */
10932 1, /* bios_id_lun */
10933 1, /* termination */
10934 1, /* reserved1 */
10935 0, /* bios_ctrl */
10936 0, /* ultra_able */
10937 0, /* reserved2 */
10938 1, /* max_host_qng */
10939 1, /* max_dvc_qng */
10940 0, /* dvc_cntl */
10941 0, /* bug_fix */
10942 0, /* serial_number_word1 */
10943 0, /* serial_number_word2 */
10944 0, /* serial_number_word3 */
10945 0, /* check_sum */
10946 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
10947 , /* oem_name[16] */
10948 0, /* dvc_err_code */
10949 0, /* adv_err_code */
10950 0, /* adv_err_addr */
10951 0, /* saved_dvc_err_code */
10952 0, /* saved_adv_err_code */
10953 0, /* saved_adv_err_addr */
10954 0 /* num_of_err */
1da177e4
LT
10955};
10956
78e77d8b 10957static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
27c868c2
MW
10958 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
10959 0x0000, /* 01 cfg_msw */
10960 0xFFFF, /* 02 disc_enable */
10961 0xFFFF, /* 03 wdtr_able */
10962 0x4444, /* 04 sdtr_speed1 */
10963 0xFFFF, /* 05 start_motor */
10964 0xFFFF, /* 06 tagqng_able */
10965 0xFFFF, /* 07 bios_scan */
10966 0, /* 08 scam_tolerant */
10967 7, /* 09 adapter_scsi_id */
10968 0, /* bios_boot_delay */
10969 3, /* 10 scsi_reset_delay */
10970 0, /* bios_id_lun */
10971 0, /* 11 termination_se */
10972 0, /* termination_lvd */
10973 0xFFE7, /* 12 bios_ctrl */
10974 0x4444, /* 13 sdtr_speed2 */
10975 0x4444, /* 14 sdtr_speed3 */
10976 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
10977 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
10978 0, /* 16 dvc_cntl */
10979 0x4444, /* 17 sdtr_speed4 */
10980 0, /* 18 serial_number_word1 */
10981 0, /* 19 serial_number_word2 */
10982 0, /* 20 serial_number_word3 */
10983 0, /* 21 check_sum */
10984 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
10985 , /* 22-29 oem_name[16] */
10986 0, /* 30 dvc_err_code */
10987 0, /* 31 adv_err_code */
10988 0, /* 32 adv_err_addr */
10989 0, /* 33 saved_dvc_err_code */
10990 0, /* 34 saved_adv_err_code */
10991 0, /* 35 saved_adv_err_addr */
10992 0, /* 36 reserved */
10993 0, /* 37 reserved */
10994 0, /* 38 reserved */
10995 0, /* 39 reserved */
10996 0, /* 40 reserved */
10997 0, /* 41 reserved */
10998 0, /* 42 reserved */
10999 0, /* 43 reserved */
11000 0, /* 44 reserved */
11001 0, /* 45 reserved */
11002 0, /* 46 reserved */
11003 0, /* 47 reserved */
11004 0, /* 48 reserved */
11005 0, /* 49 reserved */
11006 0, /* 50 reserved */
11007 0, /* 51 reserved */
11008 0, /* 52 reserved */
11009 0, /* 53 reserved */
11010 0, /* 54 reserved */
11011 0, /* 55 reserved */
11012 0, /* 56 cisptr_lsw */
11013 0, /* 57 cisprt_msw */
11014 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
11015 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
11016 0, /* 60 reserved */
11017 0, /* 61 reserved */
11018 0, /* 62 reserved */
11019 0 /* 63 reserved */
1da177e4
LT
11020};
11021
78e77d8b 11022static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11023 0, /* 00 cfg_lsw */
11024 0, /* 01 cfg_msw */
11025 0, /* 02 disc_enable */
11026 0, /* 03 wdtr_able */
11027 0, /* 04 sdtr_speed1 */
11028 0, /* 05 start_motor */
11029 0, /* 06 tagqng_able */
11030 0, /* 07 bios_scan */
11031 0, /* 08 scam_tolerant */
11032 1, /* 09 adapter_scsi_id */
11033 1, /* bios_boot_delay */
11034 1, /* 10 scsi_reset_delay */
11035 1, /* bios_id_lun */
11036 1, /* 11 termination_se */
11037 1, /* termination_lvd */
11038 0, /* 12 bios_ctrl */
11039 0, /* 13 sdtr_speed2 */
11040 0, /* 14 sdtr_speed3 */
11041 1, /* 15 max_host_qng */
11042 1, /* max_dvc_qng */
11043 0, /* 16 dvc_cntl */
11044 0, /* 17 sdtr_speed4 */
11045 0, /* 18 serial_number_word1 */
11046 0, /* 19 serial_number_word2 */
11047 0, /* 20 serial_number_word3 */
11048 0, /* 21 check_sum */
11049 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11050 , /* 22-29 oem_name[16] */
11051 0, /* 30 dvc_err_code */
11052 0, /* 31 adv_err_code */
11053 0, /* 32 adv_err_addr */
11054 0, /* 33 saved_dvc_err_code */
11055 0, /* 34 saved_adv_err_code */
11056 0, /* 35 saved_adv_err_addr */
11057 0, /* 36 reserved */
11058 0, /* 37 reserved */
11059 0, /* 38 reserved */
11060 0, /* 39 reserved */
11061 0, /* 40 reserved */
11062 0, /* 41 reserved */
11063 0, /* 42 reserved */
11064 0, /* 43 reserved */
11065 0, /* 44 reserved */
11066 0, /* 45 reserved */
11067 0, /* 46 reserved */
11068 0, /* 47 reserved */
11069 0, /* 48 reserved */
11070 0, /* 49 reserved */
11071 0, /* 50 reserved */
11072 0, /* 51 reserved */
11073 0, /* 52 reserved */
11074 0, /* 53 reserved */
11075 0, /* 54 reserved */
11076 0, /* 55 reserved */
11077 0, /* 56 cisptr_lsw */
11078 0, /* 57 cisprt_msw */
11079 0, /* 58 subsysvid */
11080 0, /* 59 subsysid */
11081 0, /* 60 reserved */
11082 0, /* 61 reserved */
11083 0, /* 62 reserved */
11084 0 /* 63 reserved */
1da177e4
LT
11085};
11086
78e77d8b 11087static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
27c868c2
MW
11088 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
11089 0x0000, /* 01 cfg_msw */
11090 0xFFFF, /* 02 disc_enable */
11091 0xFFFF, /* 03 wdtr_able */
11092 0x5555, /* 04 sdtr_speed1 */
11093 0xFFFF, /* 05 start_motor */
11094 0xFFFF, /* 06 tagqng_able */
11095 0xFFFF, /* 07 bios_scan */
11096 0, /* 08 scam_tolerant */
11097 7, /* 09 adapter_scsi_id */
11098 0, /* bios_boot_delay */
11099 3, /* 10 scsi_reset_delay */
11100 0, /* bios_id_lun */
11101 0, /* 11 termination_se */
11102 0, /* termination_lvd */
11103 0xFFE7, /* 12 bios_ctrl */
11104 0x5555, /* 13 sdtr_speed2 */
11105 0x5555, /* 14 sdtr_speed3 */
11106 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
11107 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11108 0, /* 16 dvc_cntl */
11109 0x5555, /* 17 sdtr_speed4 */
11110 0, /* 18 serial_number_word1 */
11111 0, /* 19 serial_number_word2 */
11112 0, /* 20 serial_number_word3 */
11113 0, /* 21 check_sum */
11114 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11115 , /* 22-29 oem_name[16] */
11116 0, /* 30 dvc_err_code */
11117 0, /* 31 adv_err_code */
11118 0, /* 32 adv_err_addr */
11119 0, /* 33 saved_dvc_err_code */
11120 0, /* 34 saved_adv_err_code */
11121 0, /* 35 saved_adv_err_addr */
11122 0, /* 36 reserved */
11123 0, /* 37 reserved */
11124 0, /* 38 reserved */
11125 0, /* 39 reserved */
11126 0, /* 40 reserved */
11127 0, /* 41 reserved */
11128 0, /* 42 reserved */
11129 0, /* 43 reserved */
11130 0, /* 44 reserved */
11131 0, /* 45 reserved */
11132 0, /* 46 reserved */
11133 0, /* 47 reserved */
11134 0, /* 48 reserved */
11135 0, /* 49 reserved */
11136 0, /* 50 reserved */
11137 0, /* 51 reserved */
11138 0, /* 52 reserved */
11139 0, /* 53 reserved */
11140 0, /* 54 reserved */
11141 0, /* 55 reserved */
11142 0, /* 56 cisptr_lsw */
11143 0, /* 57 cisprt_msw */
11144 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
11145 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
11146 0, /* 60 reserved */
11147 0, /* 61 reserved */
11148 0, /* 62 reserved */
11149 0 /* 63 reserved */
1da177e4
LT
11150};
11151
78e77d8b 11152static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11153 0, /* 00 cfg_lsw */
11154 0, /* 01 cfg_msw */
11155 0, /* 02 disc_enable */
11156 0, /* 03 wdtr_able */
11157 0, /* 04 sdtr_speed1 */
11158 0, /* 05 start_motor */
11159 0, /* 06 tagqng_able */
11160 0, /* 07 bios_scan */
11161 0, /* 08 scam_tolerant */
11162 1, /* 09 adapter_scsi_id */
11163 1, /* bios_boot_delay */
11164 1, /* 10 scsi_reset_delay */
11165 1, /* bios_id_lun */
11166 1, /* 11 termination_se */
11167 1, /* termination_lvd */
11168 0, /* 12 bios_ctrl */
11169 0, /* 13 sdtr_speed2 */
11170 0, /* 14 sdtr_speed3 */
11171 1, /* 15 max_host_qng */
11172 1, /* max_dvc_qng */
11173 0, /* 16 dvc_cntl */
11174 0, /* 17 sdtr_speed4 */
11175 0, /* 18 serial_number_word1 */
11176 0, /* 19 serial_number_word2 */
11177 0, /* 20 serial_number_word3 */
11178 0, /* 21 check_sum */
11179 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11180 , /* 22-29 oem_name[16] */
11181 0, /* 30 dvc_err_code */
11182 0, /* 31 adv_err_code */
11183 0, /* 32 adv_err_addr */
11184 0, /* 33 saved_dvc_err_code */
11185 0, /* 34 saved_adv_err_code */
11186 0, /* 35 saved_adv_err_addr */
11187 0, /* 36 reserved */
11188 0, /* 37 reserved */
11189 0, /* 38 reserved */
11190 0, /* 39 reserved */
11191 0, /* 40 reserved */
11192 0, /* 41 reserved */
11193 0, /* 42 reserved */
11194 0, /* 43 reserved */
11195 0, /* 44 reserved */
11196 0, /* 45 reserved */
11197 0, /* 46 reserved */
11198 0, /* 47 reserved */
11199 0, /* 48 reserved */
11200 0, /* 49 reserved */
11201 0, /* 50 reserved */
11202 0, /* 51 reserved */
11203 0, /* 52 reserved */
11204 0, /* 53 reserved */
11205 0, /* 54 reserved */
11206 0, /* 55 reserved */
11207 0, /* 56 cisptr_lsw */
11208 0, /* 57 cisprt_msw */
11209 0, /* 58 subsysvid */
11210 0, /* 59 subsysid */
11211 0, /* 60 reserved */
11212 0, /* 61 reserved */
11213 0, /* 62 reserved */
11214 0 /* 63 reserved */
1da177e4
LT
11215};
11216
c2dce2fa 11217#ifdef CONFIG_PCI
1da177e4
LT
11218/*
11219 * Initialize the ADV_DVC_VAR structure.
11220 *
11221 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11222 *
11223 * For a non-fatal error return a warning code. If there are no warnings
11224 * then 0 is returned.
11225 */
394dbf3f 11226static int __devinit
c2dce2fa 11227AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 11228{
c2dce2fa 11229 ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
9649af39
MW
11230 unsigned short warn_code = 0;
11231 AdvPortAddr iop_base = asc_dvc->iop_base;
9649af39 11232 u16 cmd;
27c868c2
MW
11233 int status;
11234
27c868c2 11235 asc_dvc->err_code = 0;
1da177e4 11236
27c868c2
MW
11237 /*
11238 * Save the state of the PCI Configuration Command Register
11239 * "Parity Error Response Control" Bit. If the bit is clear (0),
11240 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
11241 * DMA parity errors.
11242 */
11243 asc_dvc->cfg->control_flag = 0;
9649af39
MW
11244 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
11245 if ((cmd & PCI_COMMAND_PARITY) == 0)
27c868c2 11246 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
1da177e4 11247
27c868c2
MW
11248 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
11249 ADV_LIB_VERSION_MINOR;
11250 asc_dvc->cfg->chip_version =
11251 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
11252
11253 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
11254 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
11255 (ushort)ADV_CHIP_ID_BYTE);
11256
11257 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
11258 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
11259 (ushort)ADV_CHIP_ID_WORD);
11260
11261 /*
11262 * Reset the chip to start and allow register writes.
11263 */
11264 if (AdvFindSignature(iop_base) == 0) {
11265 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11266 return ADV_ERROR;
11267 } else {
11268 /*
11269 * The caller must set 'chip_type' to a valid setting.
11270 */
11271 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
11272 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
11273 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
11274 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
11275 return ADV_ERROR;
11276 }
1da177e4 11277
27c868c2
MW
11278 /*
11279 * Reset Chip.
11280 */
11281 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11282 ADV_CTRL_REG_CMD_RESET);
b009bef6 11283 mdelay(100);
27c868c2
MW
11284 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11285 ADV_CTRL_REG_CMD_WR_IO_REG);
11286
11287 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
9649af39 11288 status = AdvInitFrom38C1600EEP(asc_dvc);
27c868c2 11289 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
9649af39 11290 status = AdvInitFrom38C0800EEP(asc_dvc);
27c868c2 11291 } else {
9649af39 11292 status = AdvInitFrom3550EEP(asc_dvc);
27c868c2
MW
11293 }
11294 warn_code |= status;
11295 }
1da177e4 11296
c2dce2fa
MW
11297 if (warn_code != 0) {
11298 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
11299 boardp->id, warn_code);
11300 }
11301
11302 if (asc_dvc->err_code) {
11303 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
11304 boardp->id, asc_dvc->err_code);
11305 }
11306
11307 return asc_dvc->err_code;
1da177e4 11308}
c2dce2fa 11309#endif
1da177e4 11310
a9f4a59a
MW
11311static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
11312{
11313 ADV_CARR_T *carrp;
11314 ADV_SDCNT buf_size;
11315 ADV_PADDR carr_paddr;
11316
11317 BUG_ON(!asc_dvc->carrier_buf);
11318
11319 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
11320 asc_dvc->carr_freelist = NULL;
11321 if (carrp == asc_dvc->carrier_buf) {
11322 buf_size = ADV_CARRIER_BUFSIZE;
11323 } else {
11324 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
11325 }
11326
11327 do {
11328 /* Get physical address of the carrier 'carrp'. */
11329 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
11330 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
11331 (uchar *)carrp,
11332 (ADV_SDCNT *)&contig_len,
11333 ADV_IS_CARRIER_FLAG));
11334
11335 buf_size -= sizeof(ADV_CARR_T);
11336
11337 /*
11338 * If the current carrier is not physically contiguous, then
11339 * maybe there was a page crossing. Try the next carrier
11340 * aligned start address.
11341 */
11342 if (contig_len < sizeof(ADV_CARR_T)) {
11343 carrp++;
11344 continue;
11345 }
11346
11347 carrp->carr_pa = carr_paddr;
11348 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
11349
11350 /*
11351 * Insert the carrier at the beginning of the freelist.
11352 */
11353 carrp->next_vpa =
11354 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
11355 asc_dvc->carr_freelist = carrp;
11356
11357 carrp++;
11358 } while (buf_size > 0);
11359}
11360
b9d96614
MW
11361/*
11362 * Load the Microcode
11363 *
11364 * Write the microcode image to RISC memory starting at address 0.
11365 *
11366 * The microcode is stored compressed in the following format:
11367 *
11368 * 254 word (508 byte) table indexed by byte code followed
11369 * by the following byte codes:
11370 *
11371 * 1-Byte Code:
11372 * 00: Emit word 0 in table.
11373 * 01: Emit word 1 in table.
11374 * .
11375 * FD: Emit word 253 in table.
11376 *
11377 * Multi-Byte Code:
11378 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
11379 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
11380 *
11381 * Returns 0 or an error if the checksum doesn't match
11382 */
11383static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
11384 int memsize, int chksum)
11385{
11386 int i, j, end, len = 0;
11387 ADV_DCNT sum;
11388
11389 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
11390
11391 for (i = 253 * 2; i < size; i++) {
11392 if (buf[i] == 0xff) {
11393 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
11394 for (j = 0; j < buf[i + 1]; j++) {
11395 AdvWriteWordAutoIncLram(iop_base, word);
11396 len += 2;
11397 }
11398 i += 3;
11399 } else if (buf[i] == 0xfe) {
11400 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
11401 AdvWriteWordAutoIncLram(iop_base, word);
11402 i += 2;
11403 len += 2;
11404 } else {
11405 unsigned char off = buf[i] * 2;
11406 unsigned short word = (buf[off + 1] << 8) | buf[off];
11407 AdvWriteWordAutoIncLram(iop_base, word);
11408 len += 2;
11409 }
11410 }
11411
11412 end = len;
11413
11414 while (len < memsize) {
11415 AdvWriteWordAutoIncLram(iop_base, 0);
11416 len += 2;
11417 }
11418
11419 /* Verify the microcode checksum. */
11420 sum = 0;
11421 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
11422
11423 for (len = 0; len < end; len += 2) {
11424 sum += AdvReadWordAutoIncLram(iop_base);
11425 }
11426
11427 if (sum != chksum)
11428 return ASC_IERR_MCODE_CHKSUM;
11429
11430 return 0;
11431}
11432
1da177e4
LT
11433/*
11434 * Initialize the ASC-3550.
11435 *
11436 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11437 *
11438 * For a non-fatal error return a warning code. If there are no warnings
11439 * then 0 is returned.
11440 *
11441 * Needed after initialization for error recovery.
11442 */
27c868c2 11443static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 11444{
27c868c2
MW
11445 AdvPortAddr iop_base;
11446 ushort warn_code;
27c868c2
MW
11447 int begin_addr;
11448 int end_addr;
11449 ushort code_sum;
11450 int word;
27c868c2
MW
11451 int i;
11452 ushort scsi_cfg1;
11453 uchar tid;
11454 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
11455 ushort wdtr_able = 0, sdtr_able, tagqng_able;
11456 uchar max_cmd[ADV_MAX_TID + 1];
11457
11458 /* If there is already an error, don't continue. */
b9d96614 11459 if (asc_dvc->err_code != 0)
27c868c2 11460 return ADV_ERROR;
1da177e4 11461
27c868c2
MW
11462 /*
11463 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
11464 */
11465 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
b9d96614 11466 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
27c868c2
MW
11467 return ADV_ERROR;
11468 }
1da177e4 11469
27c868c2
MW
11470 warn_code = 0;
11471 iop_base = asc_dvc->iop_base;
11472
11473 /*
11474 * Save the RISC memory BIOS region before writing the microcode.
11475 * The BIOS may already be loaded and using its RISC LRAM region
11476 * so its region must be saved and restored.
11477 *
11478 * Note: This code makes the assumption, which is currently true,
11479 * that a chip reset does not clear RISC LRAM.
11480 */
11481 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11482 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11483 bios_mem[i]);
11484 }
1da177e4 11485
27c868c2
MW
11486 /*
11487 * Save current per TID negotiated values.
11488 */
11489 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
11490 ushort bios_version, major, minor;
11491
11492 bios_version =
11493 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
11494 major = (bios_version >> 12) & 0xF;
11495 minor = (bios_version >> 8) & 0xF;
11496 if (major < 3 || (major == 3 && minor == 1)) {
11497 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
11498 AdvReadWordLram(iop_base, 0x120, wdtr_able);
11499 } else {
11500 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11501 }
11502 }
11503 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11504 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
11505 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11506 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
11507 max_cmd[tid]);
11508 }
1da177e4 11509
b9d96614
MW
11510 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
11511 _adv_asc3550_size, ADV_3550_MEMSIZE,
11512 _adv_asc3550_chksum);
11513 if (asc_dvc->err_code)
27c868c2 11514 return ADV_ERROR;
1da177e4 11515
27c868c2
MW
11516 /*
11517 * Restore the RISC memory BIOS region.
11518 */
11519 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11520 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11521 bios_mem[i]);
11522 }
1da177e4 11523
27c868c2
MW
11524 /*
11525 * Calculate and write the microcode code checksum to the microcode
11526 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
11527 */
11528 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
11529 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
11530 code_sum = 0;
11531 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
11532 for (word = begin_addr; word < end_addr; word += 2) {
11533 code_sum += AdvReadWordAutoIncLram(iop_base);
11534 }
11535 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
11536
11537 /*
11538 * Read and save microcode version and date.
11539 */
11540 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
11541 asc_dvc->cfg->mcode_date);
11542 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
11543 asc_dvc->cfg->mcode_version);
11544
11545 /*
11546 * Set the chip type to indicate the ASC3550.
11547 */
11548 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
11549
11550 /*
11551 * If the PCI Configuration Command Register "Parity Error Response
11552 * Control" Bit was clear (0), then set the microcode variable
11553 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
11554 * to ignore DMA parity errors.
11555 */
11556 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
11557 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11558 word |= CONTROL_FLAG_IGNORE_PERR;
11559 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11560 }
1da177e4 11561
27c868c2
MW
11562 /*
11563 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
11564 * threshold of 128 bytes. This register is only accessible to the host.
11565 */
11566 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
11567 START_CTL_EMFU | READ_CMD_MRM);
11568
11569 /*
11570 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 11571 * queuing will be set in slave_configure() based on what a
27c868c2
MW
11572 * device reports it is capable of in Inquiry byte 7.
11573 *
11574 * If SCSI Bus Resets have been disabled, then directly set
11575 * SDTR and WDTR from the EEPROM configuration. This will allow
11576 * the BIOS and warm boot to work without a SCSI bus hang on
11577 * the Inquiry caused by host and target mismatched DTR values.
11578 * Without the SCSI Bus Reset, before an Inquiry a device can't
11579 * be assumed to be in Asynchronous, Narrow mode.
11580 */
11581 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
11582 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
11583 asc_dvc->wdtr_able);
11584 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
11585 asc_dvc->sdtr_able);
11586 }
1da177e4 11587
27c868c2
MW
11588 /*
11589 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
11590 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
11591 * bitmask. These values determine the maximum SDTR speed negotiated
11592 * with a device.
11593 *
11594 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
11595 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
11596 * without determining here whether the device supports SDTR.
11597 *
11598 * 4-bit speed SDTR speed name
11599 * =========== ===============
11600 * 0000b (0x0) SDTR disabled
11601 * 0001b (0x1) 5 Mhz
11602 * 0010b (0x2) 10 Mhz
11603 * 0011b (0x3) 20 Mhz (Ultra)
11604 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
11605 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
11606 * 0110b (0x6) Undefined
11607 * .
11608 * 1111b (0xF) Undefined
11609 */
11610 word = 0;
11611 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11612 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
11613 /* Set Ultra speed for TID 'tid'. */
11614 word |= (0x3 << (4 * (tid % 4)));
11615 } else {
11616 /* Set Fast speed for TID 'tid'. */
11617 word |= (0x2 << (4 * (tid % 4)));
11618 }
11619 if (tid == 3) { /* Check if done with sdtr_speed1. */
11620 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
11621 word = 0;
11622 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
11623 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
11624 word = 0;
11625 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
11626 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
11627 word = 0;
11628 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
11629 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
11630 /* End of loop. */
11631 }
11632 }
1da177e4 11633
27c868c2
MW
11634 /*
11635 * Set microcode operating variable for the disconnect per TID bitmask.
11636 */
11637 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
11638 asc_dvc->cfg->disc_enable);
11639
11640 /*
11641 * Set SCSI_CFG0 Microcode Default Value.
11642 *
11643 * The microcode will set the SCSI_CFG0 register using this value
11644 * after it is started below.
11645 */
11646 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
11647 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
11648 asc_dvc->chip_scsi_id);
11649
11650 /*
11651 * Determine SCSI_CFG1 Microcode Default Value.
11652 *
11653 * The microcode will set the SCSI_CFG1 register using this value
11654 * after it is started below.
11655 */
11656
11657 /* Read current SCSI_CFG1 Register value. */
11658 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
11659
11660 /*
11661 * If all three connectors are in use, return an error.
11662 */
11663 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
11664 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
11665 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
11666 return ADV_ERROR;
11667 }
1da177e4 11668
27c868c2
MW
11669 /*
11670 * If the internal narrow cable is reversed all of the SCSI_CTRL
11671 * register signals will be set. Check for and return an error if
11672 * this condition is found.
11673 */
11674 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
11675 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
11676 return ADV_ERROR;
11677 }
1da177e4 11678
27c868c2
MW
11679 /*
11680 * If this is a differential board and a single-ended device
11681 * is attached to one of the connectors, return an error.
11682 */
11683 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
11684 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
11685 return ADV_ERROR;
11686 }
1da177e4 11687
27c868c2
MW
11688 /*
11689 * If automatic termination control is enabled, then set the
11690 * termination value based on a table listed in a_condor.h.
11691 *
11692 * If manual termination was specified with an EEPROM setting
11693 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
11694 * is ready to be 'ored' into SCSI_CFG1.
11695 */
11696 if (asc_dvc->cfg->termination == 0) {
11697 /*
11698 * The software always controls termination by setting TERM_CTL_SEL.
11699 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
11700 */
11701 asc_dvc->cfg->termination |= TERM_CTL_SEL;
11702
11703 switch (scsi_cfg1 & CABLE_DETECT) {
11704 /* TERM_CTL_H: on, TERM_CTL_L: on */
11705 case 0x3:
11706 case 0x7:
11707 case 0xB:
11708 case 0xD:
11709 case 0xE:
11710 case 0xF:
11711 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
11712 break;
11713
11714 /* TERM_CTL_H: on, TERM_CTL_L: off */
11715 case 0x1:
11716 case 0x5:
11717 case 0x9:
11718 case 0xA:
11719 case 0xC:
11720 asc_dvc->cfg->termination |= TERM_CTL_H;
11721 break;
11722
11723 /* TERM_CTL_H: off, TERM_CTL_L: off */
11724 case 0x2:
11725 case 0x6:
11726 break;
11727 }
11728 }
1da177e4 11729
27c868c2
MW
11730 /*
11731 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
11732 */
11733 scsi_cfg1 &= ~TERM_CTL;
11734
11735 /*
11736 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
11737 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
11738 * referenced, because the hardware internally inverts
11739 * the Termination High and Low bits if TERM_POL is set.
11740 */
11741 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
11742
11743 /*
11744 * Set SCSI_CFG1 Microcode Default Value
11745 *
11746 * Set filter value and possibly modified termination control
11747 * bits in the Microcode SCSI_CFG1 Register Value.
11748 *
11749 * The microcode will set the SCSI_CFG1 register using this value
11750 * after it is started below.
11751 */
11752 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
11753 FLTR_DISABLE | scsi_cfg1);
11754
11755 /*
11756 * Set MEM_CFG Microcode Default Value
11757 *
11758 * The microcode will set the MEM_CFG register using this value
11759 * after it is started below.
11760 *
11761 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
11762 * are defined.
11763 *
11764 * ASC-3550 has 8KB internal memory.
11765 */
11766 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
11767 BIOS_EN | RAM_SZ_8KB);
11768
11769 /*
11770 * Set SEL_MASK Microcode Default Value
11771 *
11772 * The microcode will set the SEL_MASK register using this value
11773 * after it is started below.
11774 */
11775 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
11776 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
11777
a9f4a59a 11778 AdvBuildCarrierFreelist(asc_dvc);
1da177e4 11779
27c868c2
MW
11780 /*
11781 * Set-up the Host->RISC Initiator Command Queue (ICQ).
11782 */
1da177e4 11783
27c868c2
MW
11784 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
11785 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
11786 return ADV_ERROR;
11787 }
11788 asc_dvc->carr_freelist = (ADV_CARR_T *)
11789 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
11790
11791 /*
11792 * The first command issued will be placed in the stopper carrier.
11793 */
11794 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11795
11796 /*
11797 * Set RISC ICQ physical address start value.
11798 */
11799 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
11800
11801 /*
11802 * Set-up the RISC->Host Initiator Response Queue (IRQ).
11803 */
11804 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
11805 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
11806 return ADV_ERROR;
11807 }
11808 asc_dvc->carr_freelist = (ADV_CARR_T *)
11809 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
11810
11811 /*
11812 * The first command completed by the RISC will be placed in
11813 * the stopper.
11814 *
11815 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
11816 * completed the RISC will set the ASC_RQ_STOPPER bit.
11817 */
11818 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11819
11820 /*
11821 * Set RISC IRQ physical address start value.
11822 */
11823 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
11824 asc_dvc->carr_pending_cnt = 0;
11825
11826 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
11827 (ADV_INTR_ENABLE_HOST_INTR |
11828 ADV_INTR_ENABLE_GLOBAL_INTR));
11829
11830 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
11831 AdvWriteWordRegister(iop_base, IOPW_PC, word);
11832
11833 /* finally, finally, gentlemen, start your engine */
11834 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
11835
11836 /*
11837 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
11838 * Resets should be performed. The RISC has to be running
11839 * to issue a SCSI Bus Reset.
11840 */
11841 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
11842 /*
11843 * If the BIOS Signature is present in memory, restore the
11844 * BIOS Handshake Configuration Table and do not perform
11845 * a SCSI Bus Reset.
11846 */
11847 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
11848 0x55AA) {
11849 /*
11850 * Restore per TID negotiated values.
11851 */
11852 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11853 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11854 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
11855 tagqng_able);
11856 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11857 AdvWriteByteLram(iop_base,
11858 ASC_MC_NUMBER_OF_MAX_CMD + tid,
11859 max_cmd[tid]);
11860 }
11861 } else {
11862 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
11863 warn_code = ASC_WARN_BUSRESET_ERROR;
11864 }
11865 }
11866 }
1da177e4 11867
27c868c2
MW
11868 return warn_code;
11869}
1da177e4 11870
27c868c2
MW
11871/*
11872 * Initialize the ASC-38C0800.
11873 *
11874 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11875 *
11876 * For a non-fatal error return a warning code. If there are no warnings
11877 * then 0 is returned.
11878 *
11879 * Needed after initialization for error recovery.
11880 */
11881static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
11882{
11883 AdvPortAddr iop_base;
11884 ushort warn_code;
27c868c2
MW
11885 int begin_addr;
11886 int end_addr;
11887 ushort code_sum;
11888 int word;
27c868c2
MW
11889 int i;
11890 ushort scsi_cfg1;
11891 uchar byte;
11892 uchar tid;
11893 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
11894 ushort wdtr_able, sdtr_able, tagqng_able;
11895 uchar max_cmd[ADV_MAX_TID + 1];
11896
11897 /* If there is already an error, don't continue. */
b9d96614 11898 if (asc_dvc->err_code != 0)
27c868c2 11899 return ADV_ERROR;
1da177e4 11900
27c868c2
MW
11901 /*
11902 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
11903 */
11904 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
11905 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
11906 return ADV_ERROR;
11907 }
1da177e4 11908
27c868c2
MW
11909 warn_code = 0;
11910 iop_base = asc_dvc->iop_base;
11911
11912 /*
11913 * Save the RISC memory BIOS region before writing the microcode.
11914 * The BIOS may already be loaded and using its RISC LRAM region
11915 * so its region must be saved and restored.
11916 *
11917 * Note: This code makes the assumption, which is currently true,
11918 * that a chip reset does not clear RISC LRAM.
11919 */
11920 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11921 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11922 bios_mem[i]);
11923 }
1da177e4 11924
27c868c2
MW
11925 /*
11926 * Save current per TID negotiated values.
11927 */
11928 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11929 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11930 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
11931 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11932 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
11933 max_cmd[tid]);
11934 }
1da177e4 11935
27c868c2
MW
11936 /*
11937 * RAM BIST (RAM Built-In Self Test)
11938 *
11939 * Address : I/O base + offset 0x38h register (byte).
11940 * Function: Bit 7-6(RW) : RAM mode
11941 * Normal Mode : 0x00
11942 * Pre-test Mode : 0x40
11943 * RAM Test Mode : 0x80
11944 * Bit 5 : unused
11945 * Bit 4(RO) : Done bit
11946 * Bit 3-0(RO) : Status
11947 * Host Error : 0x08
11948 * Int_RAM Error : 0x04
11949 * RISC Error : 0x02
11950 * SCSI Error : 0x01
11951 * No Error : 0x00
11952 *
11953 * Note: RAM BIST code should be put right here, before loading the
11954 * microcode and after saving the RISC memory BIOS region.
11955 */
11956
11957 /*
11958 * LRAM Pre-test
11959 *
11960 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
11961 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
11962 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
11963 * to NORMAL_MODE, return an error too.
11964 */
11965 for (i = 0; i < 2; i++) {
11966 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
b009bef6 11967 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
11968 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
11969 if ((byte & RAM_TEST_DONE) == 0
11970 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 11971 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
11972 return ADV_ERROR;
11973 }
11974
11975 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
b009bef6 11976 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
11977 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
11978 != NORMAL_VALUE) {
b9d96614 11979 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
11980 return ADV_ERROR;
11981 }
11982 }
1da177e4 11983
27c868c2
MW
11984 /*
11985 * LRAM Test - It takes about 1.5 ms to run through the test.
11986 *
11987 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
11988 * If Done bit not set or Status not 0, save register byte, set the
11989 * err_code, and return an error.
11990 */
11991 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
b009bef6 11992 mdelay(10); /* Wait for 10ms before checking status. */
27c868c2
MW
11993
11994 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
11995 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
11996 /* Get here if Done bit not set or Status not 0. */
11997 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 11998 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
11999 return ADV_ERROR;
12000 }
1da177e4 12001
27c868c2
MW
12002 /* We need to reset back to normal mode after LRAM test passes. */
12003 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12004
b9d96614
MW
12005 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
12006 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
12007 _adv_asc38C0800_chksum);
12008 if (asc_dvc->err_code)
27c868c2 12009 return ADV_ERROR;
1da177e4 12010
27c868c2
MW
12011 /*
12012 * Restore the RISC memory BIOS region.
12013 */
12014 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12015 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12016 bios_mem[i]);
12017 }
1da177e4 12018
27c868c2
MW
12019 /*
12020 * Calculate and write the microcode code checksum to the microcode
12021 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
12022 */
12023 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
12024 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
12025 code_sum = 0;
12026 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
12027 for (word = begin_addr; word < end_addr; word += 2) {
12028 code_sum += AdvReadWordAutoIncLram(iop_base);
12029 }
12030 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
12031
12032 /*
12033 * Read microcode version and date.
12034 */
12035 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
12036 asc_dvc->cfg->mcode_date);
12037 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
12038 asc_dvc->cfg->mcode_version);
12039
12040 /*
12041 * Set the chip type to indicate the ASC38C0800.
12042 */
12043 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
12044
12045 /*
12046 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
12047 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
12048 * cable detection and then we are able to read C_DET[3:0].
12049 *
12050 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
12051 * Microcode Default Value' section below.
12052 */
12053 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12054 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
12055 scsi_cfg1 | DIS_TERM_DRV);
12056
12057 /*
12058 * If the PCI Configuration Command Register "Parity Error Response
12059 * Control" Bit was clear (0), then set the microcode variable
12060 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
12061 * to ignore DMA parity errors.
12062 */
12063 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
12064 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12065 word |= CONTROL_FLAG_IGNORE_PERR;
12066 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12067 }
1da177e4 12068
27c868c2
MW
12069 /*
12070 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
12071 * bits for the default FIFO threshold.
12072 *
12073 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
12074 *
12075 * For DMA Errata #4 set the BC_THRESH_ENB bit.
12076 */
12077 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
12078 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
12079 READ_CMD_MRM);
12080
12081 /*
12082 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 12083 * queuing will be set in slave_configure() based on what a
27c868c2
MW
12084 * device reports it is capable of in Inquiry byte 7.
12085 *
12086 * If SCSI Bus Resets have been disabled, then directly set
12087 * SDTR and WDTR from the EEPROM configuration. This will allow
12088 * the BIOS and warm boot to work without a SCSI bus hang on
12089 * the Inquiry caused by host and target mismatched DTR values.
12090 * Without the SCSI Bus Reset, before an Inquiry a device can't
12091 * be assumed to be in Asynchronous, Narrow mode.
12092 */
12093 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
12094 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
12095 asc_dvc->wdtr_able);
12096 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
12097 asc_dvc->sdtr_able);
12098 }
1da177e4 12099
27c868c2
MW
12100 /*
12101 * Set microcode operating variables for DISC and SDTR_SPEED1,
12102 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
12103 * configuration values.
12104 *
12105 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
12106 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
12107 * without determining here whether the device supports SDTR.
12108 */
12109 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
12110 asc_dvc->cfg->disc_enable);
12111 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
12112 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
12113 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
12114 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
12115
12116 /*
12117 * Set SCSI_CFG0 Microcode Default Value.
12118 *
12119 * The microcode will set the SCSI_CFG0 register using this value
12120 * after it is started below.
12121 */
12122 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
12123 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
12124 asc_dvc->chip_scsi_id);
12125
12126 /*
12127 * Determine SCSI_CFG1 Microcode Default Value.
12128 *
12129 * The microcode will set the SCSI_CFG1 register using this value
12130 * after it is started below.
12131 */
12132
12133 /* Read current SCSI_CFG1 Register value. */
12134 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12135
12136 /*
12137 * If the internal narrow cable is reversed all of the SCSI_CTRL
12138 * register signals will be set. Check for and return an error if
12139 * this condition is found.
12140 */
12141 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
12142 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
12143 return ADV_ERROR;
12144 }
1da177e4 12145
27c868c2 12146 /*
b9d96614
MW
12147 * All kind of combinations of devices attached to one of four
12148 * connectors are acceptable except HVD device attached. For example,
12149 * LVD device can be attached to SE connector while SE device attached
12150 * to LVD connector. If LVD device attached to SE connector, it only
12151 * runs up to Ultra speed.
27c868c2 12152 *
b9d96614
MW
12153 * If an HVD device is attached to one of LVD connectors, return an
12154 * error. However, there is no way to detect HVD device attached to
12155 * SE connectors.
27c868c2
MW
12156 */
12157 if (scsi_cfg1 & HVD) {
b9d96614 12158 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
27c868c2
MW
12159 return ADV_ERROR;
12160 }
1da177e4 12161
27c868c2
MW
12162 /*
12163 * If either SE or LVD automatic termination control is enabled, then
12164 * set the termination value based on a table listed in a_condor.h.
12165 *
12166 * If manual termination was specified with an EEPROM setting then
b9d96614
MW
12167 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
12168 * to be 'ored' into SCSI_CFG1.
27c868c2
MW
12169 */
12170 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
12171 /* SE automatic termination control is enabled. */
12172 switch (scsi_cfg1 & C_DET_SE) {
12173 /* TERM_SE_HI: on, TERM_SE_LO: on */
12174 case 0x1:
12175 case 0x2:
12176 case 0x3:
12177 asc_dvc->cfg->termination |= TERM_SE;
12178 break;
12179
12180 /* TERM_SE_HI: on, TERM_SE_LO: off */
12181 case 0x0:
12182 asc_dvc->cfg->termination |= TERM_SE_HI;
12183 break;
12184 }
12185 }
12186
12187 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
12188 /* LVD automatic termination control is enabled. */
12189 switch (scsi_cfg1 & C_DET_LVD) {
12190 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
12191 case 0x4:
12192 case 0x8:
12193 case 0xC:
12194 asc_dvc->cfg->termination |= TERM_LVD;
12195 break;
12196
12197 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
12198 case 0x0:
12199 break;
12200 }
12201 }
12202
12203 /*
12204 * Clear any set TERM_SE and TERM_LVD bits.
12205 */
12206 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
12207
12208 /*
12209 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
12210 */
12211 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
12212
12213 /*
b9d96614
MW
12214 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
12215 * bits and set possibly modified termination control bits in the
12216 * Microcode SCSI_CFG1 Register Value.
27c868c2
MW
12217 */
12218 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
12219
12220 /*
12221 * Set SCSI_CFG1 Microcode Default Value
12222 *
12223 * Set possibly modified termination control and reset DIS_TERM_DRV
12224 * bits in the Microcode SCSI_CFG1 Register Value.
12225 *
12226 * The microcode will set the SCSI_CFG1 register using this value
12227 * after it is started below.
12228 */
12229 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
12230
12231 /*
12232 * Set MEM_CFG Microcode Default Value
12233 *
12234 * The microcode will set the MEM_CFG register using this value
12235 * after it is started below.
12236 *
12237 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12238 * are defined.
12239 *
12240 * ASC-38C0800 has 16KB internal memory.
12241 */
12242 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12243 BIOS_EN | RAM_SZ_16KB);
12244
12245 /*
12246 * Set SEL_MASK Microcode Default Value
12247 *
12248 * The microcode will set the SEL_MASK register using this value
12249 * after it is started below.
12250 */
12251 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12252 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12253
a9f4a59a 12254 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
12255
12256 /*
12257 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12258 */
12259
12260 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12261 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12262 return ADV_ERROR;
12263 }
12264 asc_dvc->carr_freelist = (ADV_CARR_T *)
12265 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12266
12267 /*
12268 * The first command issued will be placed in the stopper carrier.
12269 */
12270 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12271
12272 /*
12273 * Set RISC ICQ physical address start value.
12274 * carr_pa is LE, must be native before write
12275 */
12276 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12277
12278 /*
12279 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12280 */
12281 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12282 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12283 return ADV_ERROR;
12284 }
12285 asc_dvc->carr_freelist = (ADV_CARR_T *)
12286 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12287
12288 /*
12289 * The first command completed by the RISC will be placed in
12290 * the stopper.
12291 *
12292 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12293 * completed the RISC will set the ASC_RQ_STOPPER bit.
12294 */
12295 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12296
12297 /*
12298 * Set RISC IRQ physical address start value.
12299 *
12300 * carr_pa is LE, must be native before write *
12301 */
12302 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12303 asc_dvc->carr_pending_cnt = 0;
12304
12305 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12306 (ADV_INTR_ENABLE_HOST_INTR |
12307 ADV_INTR_ENABLE_GLOBAL_INTR));
12308
12309 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12310 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12311
12312 /* finally, finally, gentlemen, start your engine */
12313 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12314
12315 /*
12316 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12317 * Resets should be performed. The RISC has to be running
12318 * to issue a SCSI Bus Reset.
12319 */
12320 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
12321 /*
12322 * If the BIOS Signature is present in memory, restore the
12323 * BIOS Handshake Configuration Table and do not perform
12324 * a SCSI Bus Reset.
12325 */
12326 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
12327 0x55AA) {
12328 /*
12329 * Restore per TID negotiated values.
12330 */
12331 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12332 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12333 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
12334 tagqng_able);
12335 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12336 AdvWriteByteLram(iop_base,
12337 ASC_MC_NUMBER_OF_MAX_CMD + tid,
12338 max_cmd[tid]);
12339 }
12340 } else {
12341 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
12342 warn_code = ASC_WARN_BUSRESET_ERROR;
12343 }
12344 }
12345 }
12346
12347 return warn_code;
1da177e4
LT
12348}
12349
12350/*
27c868c2 12351 * Initialize the ASC-38C1600.
1da177e4 12352 *
27c868c2 12353 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
12354 *
12355 * For a non-fatal error return a warning code. If there are no warnings
12356 * then 0 is returned.
12357 *
12358 * Needed after initialization for error recovery.
12359 */
27c868c2 12360static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 12361{
27c868c2
MW
12362 AdvPortAddr iop_base;
12363 ushort warn_code;
27c868c2
MW
12364 int begin_addr;
12365 int end_addr;
12366 ushort code_sum;
12367 long word;
27c868c2
MW
12368 int i;
12369 ushort scsi_cfg1;
12370 uchar byte;
12371 uchar tid;
12372 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
12373 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
12374 uchar max_cmd[ASC_MAX_TID + 1];
12375
12376 /* If there is already an error, don't continue. */
12377 if (asc_dvc->err_code != 0) {
12378 return ADV_ERROR;
12379 }
1da177e4 12380
27c868c2
MW
12381 /*
12382 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
12383 */
12384 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
12385 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
12386 return ADV_ERROR;
12387 }
1da177e4 12388
27c868c2
MW
12389 warn_code = 0;
12390 iop_base = asc_dvc->iop_base;
12391
12392 /*
12393 * Save the RISC memory BIOS region before writing the microcode.
12394 * The BIOS may already be loaded and using its RISC LRAM region
12395 * so its region must be saved and restored.
12396 *
12397 * Note: This code makes the assumption, which is currently true,
12398 * that a chip reset does not clear RISC LRAM.
12399 */
12400 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12401 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12402 bios_mem[i]);
12403 }
1da177e4 12404
27c868c2
MW
12405 /*
12406 * Save current per TID negotiated values.
12407 */
12408 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12409 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12410 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
12411 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
12412 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
12413 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
12414 max_cmd[tid]);
12415 }
1da177e4 12416
27c868c2
MW
12417 /*
12418 * RAM BIST (Built-In Self Test)
12419 *
12420 * Address : I/O base + offset 0x38h register (byte).
12421 * Function: Bit 7-6(RW) : RAM mode
12422 * Normal Mode : 0x00
12423 * Pre-test Mode : 0x40
12424 * RAM Test Mode : 0x80
12425 * Bit 5 : unused
12426 * Bit 4(RO) : Done bit
12427 * Bit 3-0(RO) : Status
12428 * Host Error : 0x08
12429 * Int_RAM Error : 0x04
12430 * RISC Error : 0x02
12431 * SCSI Error : 0x01
12432 * No Error : 0x00
12433 *
12434 * Note: RAM BIST code should be put right here, before loading the
12435 * microcode and after saving the RISC memory BIOS region.
12436 */
12437
12438 /*
12439 * LRAM Pre-test
12440 *
12441 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
12442 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
12443 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
12444 * to NORMAL_MODE, return an error too.
12445 */
12446 for (i = 0; i < 2; i++) {
12447 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
b009bef6 12448 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
12449 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12450 if ((byte & RAM_TEST_DONE) == 0
12451 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 12452 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12453 return ADV_ERROR;
12454 }
12455
12456 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
b009bef6 12457 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
12458 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
12459 != NORMAL_VALUE) {
b9d96614 12460 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12461 return ADV_ERROR;
12462 }
12463 }
1da177e4 12464
27c868c2
MW
12465 /*
12466 * LRAM Test - It takes about 1.5 ms to run through the test.
12467 *
12468 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
12469 * If Done bit not set or Status not 0, save register byte, set the
12470 * err_code, and return an error.
12471 */
12472 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
b009bef6 12473 mdelay(10); /* Wait for 10ms before checking status. */
27c868c2
MW
12474
12475 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12476 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
12477 /* Get here if Done bit not set or Status not 0. */
12478 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 12479 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
12480 return ADV_ERROR;
12481 }
1da177e4 12482
27c868c2
MW
12483 /* We need to reset back to normal mode after LRAM test passes. */
12484 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12485
b9d96614
MW
12486 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
12487 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
12488 _adv_asc38C1600_chksum);
12489 if (asc_dvc->err_code)
27c868c2 12490 return ADV_ERROR;
1da177e4 12491
27c868c2
MW
12492 /*
12493 * Restore the RISC memory BIOS region.
12494 */
12495 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12496 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12497 bios_mem[i]);
12498 }
1da177e4 12499
27c868c2
MW
12500 /*
12501 * Calculate and write the microcode code checksum to the microcode
12502 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
12503 */
12504 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
12505 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
12506 code_sum = 0;
12507 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
12508 for (word = begin_addr; word < end_addr; word += 2) {
12509 code_sum += AdvReadWordAutoIncLram(iop_base);
12510 }
12511 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
12512
12513 /*
12514 * Read microcode version and date.
12515 */
12516 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
12517 asc_dvc->cfg->mcode_date);
12518 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
12519 asc_dvc->cfg->mcode_version);
12520
12521 /*
12522 * Set the chip type to indicate the ASC38C1600.
12523 */
12524 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
12525
12526 /*
12527 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
12528 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
12529 * cable detection and then we are able to read C_DET[3:0].
12530 *
12531 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
12532 * Microcode Default Value' section below.
12533 */
12534 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12535 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
12536 scsi_cfg1 | DIS_TERM_DRV);
12537
12538 /*
12539 * If the PCI Configuration Command Register "Parity Error Response
12540 * Control" Bit was clear (0), then set the microcode variable
12541 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
12542 * to ignore DMA parity errors.
12543 */
12544 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
12545 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12546 word |= CONTROL_FLAG_IGNORE_PERR;
12547 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12548 }
1da177e4 12549
27c868c2
MW
12550 /*
12551 * If the BIOS control flag AIPP (Asynchronous Information
12552 * Phase Protection) disable bit is not set, then set the firmware
12553 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
12554 * AIPP checking and encoding.
12555 */
12556 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
12557 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12558 word |= CONTROL_FLAG_ENABLE_AIPP;
12559 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12560 }
1da177e4 12561
27c868c2
MW
12562 /*
12563 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
12564 * and START_CTL_TH [3:2].
12565 */
12566 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
12567 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
12568
12569 /*
12570 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 12571 * queuing will be set in slave_configure() based on what a
27c868c2
MW
12572 * device reports it is capable of in Inquiry byte 7.
12573 *
12574 * If SCSI Bus Resets have been disabled, then directly set
12575 * SDTR and WDTR from the EEPROM configuration. This will allow
12576 * the BIOS and warm boot to work without a SCSI bus hang on
12577 * the Inquiry caused by host and target mismatched DTR values.
12578 * Without the SCSI Bus Reset, before an Inquiry a device can't
12579 * be assumed to be in Asynchronous, Narrow mode.
12580 */
12581 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
12582 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
12583 asc_dvc->wdtr_able);
12584 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
12585 asc_dvc->sdtr_able);
12586 }
1da177e4 12587
27c868c2
MW
12588 /*
12589 * Set microcode operating variables for DISC and SDTR_SPEED1,
12590 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
12591 * configuration values.
12592 *
12593 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
12594 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
12595 * without determining here whether the device supports SDTR.
12596 */
12597 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
12598 asc_dvc->cfg->disc_enable);
12599 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
12600 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
12601 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
12602 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
12603
12604 /*
12605 * Set SCSI_CFG0 Microcode Default Value.
12606 *
12607 * The microcode will set the SCSI_CFG0 register using this value
12608 * after it is started below.
12609 */
12610 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
12611 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
12612 asc_dvc->chip_scsi_id);
12613
12614 /*
12615 * Calculate SCSI_CFG1 Microcode Default Value.
12616 *
12617 * The microcode will set the SCSI_CFG1 register using this value
12618 * after it is started below.
12619 *
12620 * Each ASC-38C1600 function has only two cable detect bits.
12621 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
12622 */
12623 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12624
12625 /*
12626 * If the cable is reversed all of the SCSI_CTRL register signals
12627 * will be set. Check for and return an error if this condition is
12628 * found.
12629 */
12630 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
12631 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
12632 return ADV_ERROR;
12633 }
1da177e4 12634
27c868c2
MW
12635 /*
12636 * Each ASC-38C1600 function has two connectors. Only an HVD device
12637 * can not be connected to either connector. An LVD device or SE device
12638 * may be connected to either connecor. If an SE device is connected,
12639 * then at most Ultra speed (20 Mhz) can be used on both connectors.
12640 *
12641 * If an HVD device is attached, return an error.
12642 */
12643 if (scsi_cfg1 & HVD) {
12644 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
12645 return ADV_ERROR;
12646 }
1da177e4 12647
27c868c2
MW
12648 /*
12649 * Each function in the ASC-38C1600 uses only the SE cable detect and
12650 * termination because there are two connectors for each function. Each
12651 * function may use either LVD or SE mode. Corresponding the SE automatic
12652 * termination control EEPROM bits are used for each function. Each
12653 * function has its own EEPROM. If SE automatic control is enabled for
12654 * the function, then set the termination value based on a table listed
12655 * in a_condor.h.
12656 *
12657 * If manual termination is specified in the EEPROM for the function,
12658 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
12659 * ready to be 'ored' into SCSI_CFG1.
12660 */
12661 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
13ac2d9c 12662 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2
MW
12663 /* SE automatic termination control is enabled. */
12664 switch (scsi_cfg1 & C_DET_SE) {
12665 /* TERM_SE_HI: on, TERM_SE_LO: on */
12666 case 0x1:
12667 case 0x2:
12668 case 0x3:
12669 asc_dvc->cfg->termination |= TERM_SE;
12670 break;
12671
12672 case 0x0:
13ac2d9c 12673 if (PCI_FUNC(pdev->devfn) == 0) {
27c868c2
MW
12674 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
12675 } else {
12676 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
12677 asc_dvc->cfg->termination |= TERM_SE_HI;
12678 }
12679 break;
12680 }
12681 }
1da177e4 12682
27c868c2
MW
12683 /*
12684 * Clear any set TERM_SE bits.
12685 */
12686 scsi_cfg1 &= ~TERM_SE;
12687
12688 /*
12689 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
12690 */
12691 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
12692
12693 /*
12694 * Clear Big Endian and Terminator Polarity bits and set possibly
12695 * modified termination control bits in the Microcode SCSI_CFG1
12696 * Register Value.
12697 *
12698 * Big Endian bit is not used even on big endian machines.
12699 */
12700 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
12701
12702 /*
12703 * Set SCSI_CFG1 Microcode Default Value
12704 *
12705 * Set possibly modified termination control bits in the Microcode
12706 * SCSI_CFG1 Register Value.
12707 *
12708 * The microcode will set the SCSI_CFG1 register using this value
12709 * after it is started below.
12710 */
12711 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
12712
12713 /*
12714 * Set MEM_CFG Microcode Default Value
12715 *
12716 * The microcode will set the MEM_CFG register using this value
12717 * after it is started below.
12718 *
12719 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12720 * are defined.
12721 *
12722 * ASC-38C1600 has 32KB internal memory.
12723 *
12724 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
12725 * out a special 16K Adv Library and Microcode version. After the issue
12726 * resolved, we should turn back to the 32K support. Both a_condor.h and
12727 * mcode.sas files also need to be updated.
12728 *
12729 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12730 * BIOS_EN | RAM_SZ_32KB);
12731 */
12732 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12733 BIOS_EN | RAM_SZ_16KB);
12734
12735 /*
12736 * Set SEL_MASK Microcode Default Value
12737 *
12738 * The microcode will set the SEL_MASK register using this value
12739 * after it is started below.
12740 */
12741 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12742 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12743
a9f4a59a 12744 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
12745
12746 /*
12747 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12748 */
12749 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12750 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12751 return ADV_ERROR;
12752 }
12753 asc_dvc->carr_freelist = (ADV_CARR_T *)
12754 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12755
12756 /*
12757 * The first command issued will be placed in the stopper carrier.
12758 */
12759 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12760
12761 /*
12762 * Set RISC ICQ physical address start value. Initialize the
12763 * COMMA register to the same value otherwise the RISC will
12764 * prematurely detect a command is available.
12765 */
12766 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12767 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
12768 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
12769
12770 /*
12771 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12772 */
12773 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12774 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12775 return ADV_ERROR;
12776 }
12777 asc_dvc->carr_freelist = (ADV_CARR_T *)
12778 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12779
12780 /*
12781 * The first command completed by the RISC will be placed in
12782 * the stopper.
12783 *
12784 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12785 * completed the RISC will set the ASC_RQ_STOPPER bit.
12786 */
12787 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12788
12789 /*
12790 * Set RISC IRQ physical address start value.
12791 */
12792 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12793 asc_dvc->carr_pending_cnt = 0;
12794
12795 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12796 (ADV_INTR_ENABLE_HOST_INTR |
12797 ADV_INTR_ENABLE_GLOBAL_INTR));
12798 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12799 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12800
12801 /* finally, finally, gentlemen, start your engine */
12802 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12803
12804 /*
12805 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12806 * Resets should be performed. The RISC has to be running
12807 * to issue a SCSI Bus Reset.
12808 */
12809 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
12810 /*
12811 * If the BIOS Signature is present in memory, restore the
12812 * per TID microcode operating variables.
12813 */
12814 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
12815 0x55AA) {
12816 /*
12817 * Restore per TID negotiated values.
12818 */
12819 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12820 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12821 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
12822 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
12823 tagqng_able);
12824 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
12825 AdvWriteByteLram(iop_base,
12826 ASC_MC_NUMBER_OF_MAX_CMD + tid,
12827 max_cmd[tid]);
12828 }
12829 } else {
12830 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
12831 warn_code = ASC_WARN_BUSRESET_ERROR;
12832 }
12833 }
12834 }
1da177e4 12835
27c868c2
MW
12836 return warn_code;
12837}
1da177e4 12838
27c868c2
MW
12839/*
12840 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12841 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12842 * all of this is done.
12843 *
12844 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12845 *
12846 * For a non-fatal error return a warning code. If there are no warnings
12847 * then 0 is returned.
12848 *
12849 * Note: Chip is stopped on entry.
12850 */
78e77d8b 12851static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
12852{
12853 AdvPortAddr iop_base;
12854 ushort warn_code;
12855 ADVEEP_3550_CONFIG eep_config;
1da177e4 12856
27c868c2 12857 iop_base = asc_dvc->iop_base;
1da177e4 12858
27c868c2 12859 warn_code = 0;
1da177e4 12860
27c868c2
MW
12861 /*
12862 * Read the board's EEPROM configuration.
12863 *
12864 * Set default values if a bad checksum is found.
12865 */
12866 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12867 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 12868
27c868c2
MW
12869 /*
12870 * Set EEPROM default values.
12871 */
d68f4321
MW
12872 memcpy(&eep_config, &Default_3550_EEPROM_Config,
12873 sizeof(ADVEEP_3550_CONFIG));
1da177e4 12874
27c868c2 12875 /*
d68f4321
MW
12876 * Assume the 6 byte board serial number that was read from
12877 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
12878 */
12879 eep_config.serial_number_word3 =
12880 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 12881
27c868c2
MW
12882 eep_config.serial_number_word2 =
12883 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 12884
27c868c2
MW
12885 eep_config.serial_number_word1 =
12886 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 12887
27c868c2
MW
12888 AdvSet3550EEPConfig(iop_base, &eep_config);
12889 }
12890 /*
12891 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12892 * EEPROM configuration that was read.
12893 *
12894 * This is the mapping of EEPROM fields to Adv Library fields.
12895 */
12896 asc_dvc->wdtr_able = eep_config.wdtr_able;
12897 asc_dvc->sdtr_able = eep_config.sdtr_able;
12898 asc_dvc->ultra_able = eep_config.ultra_able;
12899 asc_dvc->tagqng_able = eep_config.tagqng_able;
12900 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12901 asc_dvc->max_host_qng = eep_config.max_host_qng;
12902 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12903 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12904 asc_dvc->start_motor = eep_config.start_motor;
12905 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12906 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12907 asc_dvc->no_scam = eep_config.scam_tolerant;
12908 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12909 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12910 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12911
12912 /*
12913 * Set the host maximum queuing (max. 253, min. 16) and the per device
12914 * maximum queuing (max. 63, min. 4).
12915 */
12916 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12917 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12918 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12919 /* If the value is zero, assume it is uninitialized. */
12920 if (eep_config.max_host_qng == 0) {
12921 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12922 } else {
12923 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12924 }
12925 }
1da177e4 12926
27c868c2
MW
12927 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12928 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12929 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12930 /* If the value is zero, assume it is uninitialized. */
12931 if (eep_config.max_dvc_qng == 0) {
12932 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12933 } else {
12934 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12935 }
12936 }
1da177e4 12937
27c868c2
MW
12938 /*
12939 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12940 * set 'max_dvc_qng' to 'max_host_qng'.
12941 */
12942 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12943 eep_config.max_dvc_qng = eep_config.max_host_qng;
12944 }
1da177e4 12945
27c868c2
MW
12946 /*
12947 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12948 * values based on possibly adjusted EEPROM values.
12949 */
12950 asc_dvc->max_host_qng = eep_config.max_host_qng;
12951 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12952
12953 /*
12954 * If the EEPROM 'termination' field is set to automatic (0), then set
12955 * the ADV_DVC_CFG 'termination' field to automatic also.
12956 *
12957 * If the termination is specified with a non-zero 'termination'
12958 * value check that a legal value is set and set the ADV_DVC_CFG
12959 * 'termination' field appropriately.
12960 */
12961 if (eep_config.termination == 0) {
12962 asc_dvc->cfg->termination = 0; /* auto termination */
12963 } else {
12964 /* Enable manual control with low off / high off. */
12965 if (eep_config.termination == 1) {
12966 asc_dvc->cfg->termination = TERM_CTL_SEL;
12967
12968 /* Enable manual control with low off / high on. */
12969 } else if (eep_config.termination == 2) {
12970 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
12971
12972 /* Enable manual control with low on / high on. */
12973 } else if (eep_config.termination == 3) {
12974 asc_dvc->cfg->termination =
12975 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
12976 } else {
12977 /*
12978 * The EEPROM 'termination' field contains a bad value. Use
12979 * automatic termination instead.
12980 */
12981 asc_dvc->cfg->termination = 0;
12982 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12983 }
12984 }
1da177e4 12985
27c868c2
MW
12986 return warn_code;
12987}
1da177e4 12988
27c868c2
MW
12989/*
12990 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12991 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12992 * all of this is done.
12993 *
12994 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12995 *
12996 * For a non-fatal error return a warning code. If there are no warnings
12997 * then 0 is returned.
12998 *
12999 * Note: Chip is stopped on entry.
13000 */
78e77d8b 13001static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
13002{
13003 AdvPortAddr iop_base;
13004 ushort warn_code;
13005 ADVEEP_38C0800_CONFIG eep_config;
27c868c2
MW
13006 uchar tid, termination;
13007 ushort sdtr_speed = 0;
13008
13009 iop_base = asc_dvc->iop_base;
13010
13011 warn_code = 0;
13012
13013 /*
13014 * Read the board's EEPROM configuration.
13015 *
13016 * Set default values if a bad checksum is found.
13017 */
13018 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
13019 eep_config.check_sum) {
13020 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13021
27c868c2
MW
13022 /*
13023 * Set EEPROM default values.
13024 */
d68f4321
MW
13025 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
13026 sizeof(ADVEEP_38C0800_CONFIG));
1da177e4 13027
27c868c2 13028 /*
d68f4321
MW
13029 * Assume the 6 byte board serial number that was read from
13030 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13031 */
13032 eep_config.serial_number_word3 =
13033 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 13034
27c868c2
MW
13035 eep_config.serial_number_word2 =
13036 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 13037
27c868c2
MW
13038 eep_config.serial_number_word1 =
13039 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13040
27c868c2
MW
13041 AdvSet38C0800EEPConfig(iop_base, &eep_config);
13042 }
13043 /*
13044 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
13045 * EEPROM configuration that was read.
13046 *
13047 * This is the mapping of EEPROM fields to Adv Library fields.
13048 */
13049 asc_dvc->wdtr_able = eep_config.wdtr_able;
13050 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13051 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13052 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13053 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13054 asc_dvc->tagqng_able = eep_config.tagqng_able;
13055 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13056 asc_dvc->max_host_qng = eep_config.max_host_qng;
13057 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13058 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13059 asc_dvc->start_motor = eep_config.start_motor;
13060 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13061 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13062 asc_dvc->no_scam = eep_config.scam_tolerant;
13063 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13064 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13065 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13066
13067 /*
13068 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13069 * are set, then set an 'sdtr_able' bit for it.
13070 */
13071 asc_dvc->sdtr_able = 0;
13072 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13073 if (tid == 0) {
13074 sdtr_speed = asc_dvc->sdtr_speed1;
13075 } else if (tid == 4) {
13076 sdtr_speed = asc_dvc->sdtr_speed2;
13077 } else if (tid == 8) {
13078 sdtr_speed = asc_dvc->sdtr_speed3;
13079 } else if (tid == 12) {
13080 sdtr_speed = asc_dvc->sdtr_speed4;
13081 }
13082 if (sdtr_speed & ADV_MAX_TID) {
13083 asc_dvc->sdtr_able |= (1 << tid);
13084 }
13085 sdtr_speed >>= 4;
13086 }
1da177e4 13087
27c868c2
MW
13088 /*
13089 * Set the host maximum queuing (max. 253, min. 16) and the per device
13090 * maximum queuing (max. 63, min. 4).
13091 */
13092 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13093 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13094 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13095 /* If the value is zero, assume it is uninitialized. */
13096 if (eep_config.max_host_qng == 0) {
13097 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13098 } else {
13099 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13100 }
13101 }
1da177e4 13102
27c868c2
MW
13103 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13104 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13105 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13106 /* If the value is zero, assume it is uninitialized. */
13107 if (eep_config.max_dvc_qng == 0) {
13108 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13109 } else {
13110 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13111 }
13112 }
1da177e4 13113
27c868c2
MW
13114 /*
13115 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13116 * set 'max_dvc_qng' to 'max_host_qng'.
13117 */
13118 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13119 eep_config.max_dvc_qng = eep_config.max_host_qng;
13120 }
1da177e4 13121
27c868c2
MW
13122 /*
13123 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13124 * values based on possibly adjusted EEPROM values.
13125 */
13126 asc_dvc->max_host_qng = eep_config.max_host_qng;
13127 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13128
13129 /*
13130 * If the EEPROM 'termination' field is set to automatic (0), then set
13131 * the ADV_DVC_CFG 'termination' field to automatic also.
13132 *
13133 * If the termination is specified with a non-zero 'termination'
13134 * value check that a legal value is set and set the ADV_DVC_CFG
13135 * 'termination' field appropriately.
13136 */
13137 if (eep_config.termination_se == 0) {
13138 termination = 0; /* auto termination for SE */
13139 } else {
13140 /* Enable manual control with low off / high off. */
13141 if (eep_config.termination_se == 1) {
13142 termination = 0;
13143
13144 /* Enable manual control with low off / high on. */
13145 } else if (eep_config.termination_se == 2) {
13146 termination = TERM_SE_HI;
13147
13148 /* Enable manual control with low on / high on. */
13149 } else if (eep_config.termination_se == 3) {
13150 termination = TERM_SE;
13151 } else {
13152 /*
13153 * The EEPROM 'termination_se' field contains a bad value.
13154 * Use automatic termination instead.
13155 */
13156 termination = 0;
13157 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13158 }
13159 }
1da177e4 13160
27c868c2
MW
13161 if (eep_config.termination_lvd == 0) {
13162 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13163 } else {
13164 /* Enable manual control with low off / high off. */
13165 if (eep_config.termination_lvd == 1) {
13166 asc_dvc->cfg->termination = termination;
13167
13168 /* Enable manual control with low off / high on. */
13169 } else if (eep_config.termination_lvd == 2) {
13170 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13171
13172 /* Enable manual control with low on / high on. */
13173 } else if (eep_config.termination_lvd == 3) {
13174 asc_dvc->cfg->termination = termination | TERM_LVD;
13175 } else {
13176 /*
13177 * The EEPROM 'termination_lvd' field contains a bad value.
13178 * Use automatic termination instead.
13179 */
13180 asc_dvc->cfg->termination = termination;
13181 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13182 }
13183 }
1da177e4 13184
27c868c2 13185 return warn_code;
1da177e4
LT
13186}
13187
13188/*
27c868c2
MW
13189 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13190 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13191 * all of this is done.
1da177e4
LT
13192 *
13193 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13194 *
13195 * For a non-fatal error return a warning code. If there are no warnings
13196 * then 0 is returned.
13197 *
27c868c2 13198 * Note: Chip is stopped on entry.
1da177e4 13199 */
78e77d8b 13200static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13201{
27c868c2
MW
13202 AdvPortAddr iop_base;
13203 ushort warn_code;
13204 ADVEEP_38C1600_CONFIG eep_config;
27c868c2
MW
13205 uchar tid, termination;
13206 ushort sdtr_speed = 0;
13207
13208 iop_base = asc_dvc->iop_base;
13209
13210 warn_code = 0;
13211
13212 /*
13213 * Read the board's EEPROM configuration.
13214 *
13215 * Set default values if a bad checksum is found.
13216 */
13217 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13218 eep_config.check_sum) {
13ac2d9c 13219 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2 13220 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13221
27c868c2
MW
13222 /*
13223 * Set EEPROM default values.
13224 */
d68f4321
MW
13225 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13226 sizeof(ADVEEP_38C1600_CONFIG));
27c868c2 13227
d68f4321
MW
13228 if (PCI_FUNC(pdev->devfn) != 0) {
13229 u8 ints;
13230 /*
13231 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13232 * and old Mac system booting problem. The Expansion
13233 * ROM must be disabled in Function 1 for these systems
13234 */
13235 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13236 /*
13237 * Clear the INTAB (bit 11) if the GPIO 0 input
13238 * indicates the Function 1 interrupt line is wired
13239 * to INTB.
13240 *
13241 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13242 * 1 - Function 1 interrupt line wired to INT A.
13243 * 0 - Function 1 interrupt line wired to INT B.
13244 *
13245 * Note: Function 0 is always wired to INTA.
13246 * Put all 5 GPIO bits in input mode and then read
13247 * their input values.
13248 */
13249 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13250 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13251 if ((ints & 0x01) == 0)
13252 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
27c868c2 13253 }
1da177e4 13254
27c868c2 13255 /*
d68f4321
MW
13256 * Assume the 6 byte board serial number that was read from
13257 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13258 */
13259 eep_config.serial_number_word3 =
d68f4321 13260 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
27c868c2 13261 eep_config.serial_number_word2 =
d68f4321 13262 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 13263 eep_config.serial_number_word1 =
d68f4321 13264 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13265
27c868c2
MW
13266 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13267 }
1da177e4 13268
27c868c2
MW
13269 /*
13270 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13271 * EEPROM configuration that was read.
13272 *
13273 * This is the mapping of EEPROM fields to Adv Library fields.
13274 */
13275 asc_dvc->wdtr_able = eep_config.wdtr_able;
13276 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13277 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13278 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13279 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13280 asc_dvc->ppr_able = 0;
13281 asc_dvc->tagqng_able = eep_config.tagqng_able;
13282 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13283 asc_dvc->max_host_qng = eep_config.max_host_qng;
13284 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13285 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13286 asc_dvc->start_motor = eep_config.start_motor;
13287 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13288 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13289 asc_dvc->no_scam = eep_config.scam_tolerant;
13290
13291 /*
13292 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13293 * are set, then set an 'sdtr_able' bit for it.
13294 */
13295 asc_dvc->sdtr_able = 0;
13296 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13297 if (tid == 0) {
13298 sdtr_speed = asc_dvc->sdtr_speed1;
13299 } else if (tid == 4) {
13300 sdtr_speed = asc_dvc->sdtr_speed2;
13301 } else if (tid == 8) {
13302 sdtr_speed = asc_dvc->sdtr_speed3;
13303 } else if (tid == 12) {
13304 sdtr_speed = asc_dvc->sdtr_speed4;
13305 }
13306 if (sdtr_speed & ASC_MAX_TID) {
13307 asc_dvc->sdtr_able |= (1 << tid);
13308 }
13309 sdtr_speed >>= 4;
13310 }
1da177e4 13311
27c868c2
MW
13312 /*
13313 * Set the host maximum queuing (max. 253, min. 16) and the per device
13314 * maximum queuing (max. 63, min. 4).
13315 */
13316 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13317 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13318 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13319 /* If the value is zero, assume it is uninitialized. */
13320 if (eep_config.max_host_qng == 0) {
13321 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13322 } else {
13323 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13324 }
13325 }
1da177e4 13326
27c868c2
MW
13327 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13328 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13329 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13330 /* If the value is zero, assume it is uninitialized. */
13331 if (eep_config.max_dvc_qng == 0) {
13332 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13333 } else {
13334 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13335 }
13336 }
1da177e4 13337
27c868c2
MW
13338 /*
13339 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13340 * set 'max_dvc_qng' to 'max_host_qng'.
13341 */
13342 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13343 eep_config.max_dvc_qng = eep_config.max_host_qng;
13344 }
1da177e4 13345
27c868c2
MW
13346 /*
13347 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13348 * values based on possibly adjusted EEPROM values.
13349 */
13350 asc_dvc->max_host_qng = eep_config.max_host_qng;
13351 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13352
13353 /*
13354 * If the EEPROM 'termination' field is set to automatic (0), then set
13355 * the ASC_DVC_CFG 'termination' field to automatic also.
13356 *
13357 * If the termination is specified with a non-zero 'termination'
13358 * value check that a legal value is set and set the ASC_DVC_CFG
13359 * 'termination' field appropriately.
13360 */
13361 if (eep_config.termination_se == 0) {
13362 termination = 0; /* auto termination for SE */
13363 } else {
13364 /* Enable manual control with low off / high off. */
13365 if (eep_config.termination_se == 1) {
13366 termination = 0;
13367
13368 /* Enable manual control with low off / high on. */
13369 } else if (eep_config.termination_se == 2) {
13370 termination = TERM_SE_HI;
13371
13372 /* Enable manual control with low on / high on. */
13373 } else if (eep_config.termination_se == 3) {
13374 termination = TERM_SE;
13375 } else {
13376 /*
13377 * The EEPROM 'termination_se' field contains a bad value.
13378 * Use automatic termination instead.
13379 */
13380 termination = 0;
13381 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13382 }
13383 }
1da177e4 13384
27c868c2
MW
13385 if (eep_config.termination_lvd == 0) {
13386 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13387 } else {
13388 /* Enable manual control with low off / high off. */
13389 if (eep_config.termination_lvd == 1) {
13390 asc_dvc->cfg->termination = termination;
13391
13392 /* Enable manual control with low off / high on. */
13393 } else if (eep_config.termination_lvd == 2) {
13394 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13395
13396 /* Enable manual control with low on / high on. */
13397 } else if (eep_config.termination_lvd == 3) {
13398 asc_dvc->cfg->termination = termination | TERM_LVD;
13399 } else {
13400 /*
13401 * The EEPROM 'termination_lvd' field contains a bad value.
13402 * Use automatic termination instead.
13403 */
13404 asc_dvc->cfg->termination = termination;
13405 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13406 }
13407 }
1da177e4 13408
27c868c2 13409 return warn_code;
1da177e4
LT
13410}
13411
13412/*
13413 * Read EEPROM configuration into the specified buffer.
13414 *
13415 * Return a checksum based on the EEPROM configuration read.
13416 */
78e77d8b 13417static ushort __devinit
1da177e4
LT
13418AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
13419{
27c868c2
MW
13420 ushort wval, chksum;
13421 ushort *wbuf;
13422 int eep_addr;
13423 ushort *charfields;
13424
13425 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
13426 wbuf = (ushort *)cfg_buf;
13427 chksum = 0;
13428
13429 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13430 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13431 wval = AdvReadEEPWord(iop_base, eep_addr);
13432 chksum += wval; /* Checksum is calculated from word values. */
13433 if (*charfields++) {
13434 *wbuf = le16_to_cpu(wval);
13435 } else {
13436 *wbuf = wval;
13437 }
13438 }
13439 /* Read checksum word. */
13440 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13441 wbuf++;
13442 charfields++;
13443
13444 /* Read rest of EEPROM not covered by the checksum. */
13445 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13446 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13447 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13448 if (*charfields++) {
13449 *wbuf = le16_to_cpu(*wbuf);
13450 }
13451 }
13452 return chksum;
1da177e4
LT
13453}
13454
13455/*
13456 * Read EEPROM configuration into the specified buffer.
13457 *
13458 * Return a checksum based on the EEPROM configuration read.
13459 */
78e77d8b 13460static ushort __devinit
27c868c2 13461AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 13462{
27c868c2
MW
13463 ushort wval, chksum;
13464 ushort *wbuf;
13465 int eep_addr;
13466 ushort *charfields;
13467
13468 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
13469 wbuf = (ushort *)cfg_buf;
13470 chksum = 0;
13471
13472 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13473 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13474 wval = AdvReadEEPWord(iop_base, eep_addr);
13475 chksum += wval; /* Checksum is calculated from word values. */
13476 if (*charfields++) {
13477 *wbuf = le16_to_cpu(wval);
13478 } else {
13479 *wbuf = wval;
13480 }
13481 }
13482 /* Read checksum word. */
13483 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13484 wbuf++;
13485 charfields++;
13486
13487 /* Read rest of EEPROM not covered by the checksum. */
13488 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13489 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13490 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13491 if (*charfields++) {
13492 *wbuf = le16_to_cpu(*wbuf);
13493 }
13494 }
13495 return chksum;
1da177e4
LT
13496}
13497
13498/*
13499 * Read EEPROM configuration into the specified buffer.
13500 *
13501 * Return a checksum based on the EEPROM configuration read.
13502 */
78e77d8b 13503static ushort __devinit
27c868c2 13504AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 13505{
27c868c2
MW
13506 ushort wval, chksum;
13507 ushort *wbuf;
13508 int eep_addr;
13509 ushort *charfields;
13510
13511 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
13512 wbuf = (ushort *)cfg_buf;
13513 chksum = 0;
13514
13515 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13516 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13517 wval = AdvReadEEPWord(iop_base, eep_addr);
13518 chksum += wval; /* Checksum is calculated from word values. */
13519 if (*charfields++) {
13520 *wbuf = le16_to_cpu(wval);
13521 } else {
13522 *wbuf = wval;
13523 }
13524 }
13525 /* Read checksum word. */
13526 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13527 wbuf++;
13528 charfields++;
13529
13530 /* Read rest of EEPROM not covered by the checksum. */
13531 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13532 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13533 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13534 if (*charfields++) {
13535 *wbuf = le16_to_cpu(*wbuf);
13536 }
13537 }
13538 return chksum;
1da177e4
LT
13539}
13540
13541/*
13542 * Read the EEPROM from specified location
13543 */
78e77d8b 13544static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 13545{
27c868c2
MW
13546 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13547 ASC_EEP_CMD_READ | eep_word_addr);
13548 AdvWaitEEPCmd(iop_base);
13549 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
13550}
13551
13552/*
13553 * Wait for EEPROM command to complete
13554 */
78e77d8b 13555static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 13556{
27c868c2
MW
13557 int eep_delay_ms;
13558
13559 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
13560 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
13561 ASC_EEP_CMD_DONE) {
13562 break;
13563 }
b009bef6 13564 mdelay(1);
27c868c2
MW
13565 }
13566 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
b009bef6
MW
13567 0)
13568 BUG();
27c868c2 13569 return;
1da177e4
LT
13570}
13571
13572/*
13573 * Write the EEPROM from 'cfg_buf'.
13574 */
78e77d8b 13575void __devinit
1da177e4
LT
13576AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
13577{
27c868c2
MW
13578 ushort *wbuf;
13579 ushort addr, chksum;
13580 ushort *charfields;
13581
13582 wbuf = (ushort *)cfg_buf;
13583 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
13584 chksum = 0;
13585
13586 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13587 AdvWaitEEPCmd(iop_base);
13588
13589 /*
13590 * Write EEPROM from word 0 to word 20.
13591 */
13592 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13593 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13594 ushort word;
13595
13596 if (*charfields++) {
13597 word = cpu_to_le16(*wbuf);
13598 } else {
13599 word = *wbuf;
13600 }
13601 chksum += *wbuf; /* Checksum is calculated from word values. */
13602 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13603 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13604 ASC_EEP_CMD_WRITE | addr);
13605 AdvWaitEEPCmd(iop_base);
b009bef6 13606 mdelay(ADV_EEP_DELAY_MS);
27c868c2 13607 }
1da177e4 13608
27c868c2
MW
13609 /*
13610 * Write EEPROM checksum at word 21.
13611 */
13612 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13613 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13614 AdvWaitEEPCmd(iop_base);
13615 wbuf++;
13616 charfields++;
13617
13618 /*
13619 * Write EEPROM OEM name at words 22 to 29.
13620 */
13621 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13622 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13623 ushort word;
13624
13625 if (*charfields++) {
13626 word = cpu_to_le16(*wbuf);
13627 } else {
13628 word = *wbuf;
13629 }
13630 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13631 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13632 ASC_EEP_CMD_WRITE | addr);
13633 AdvWaitEEPCmd(iop_base);
13634 }
13635 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13636 AdvWaitEEPCmd(iop_base);
13637 return;
1da177e4
LT
13638}
13639
13640/*
13641 * Write the EEPROM from 'cfg_buf'.
13642 */
78e77d8b 13643void __devinit
27c868c2 13644AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 13645{
27c868c2
MW
13646 ushort *wbuf;
13647 ushort *charfields;
13648 ushort addr, chksum;
13649
13650 wbuf = (ushort *)cfg_buf;
13651 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
13652 chksum = 0;
13653
13654 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13655 AdvWaitEEPCmd(iop_base);
13656
13657 /*
13658 * Write EEPROM from word 0 to word 20.
13659 */
13660 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13661 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13662 ushort word;
13663
13664 if (*charfields++) {
13665 word = cpu_to_le16(*wbuf);
13666 } else {
13667 word = *wbuf;
13668 }
13669 chksum += *wbuf; /* Checksum is calculated from word values. */
13670 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13671 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13672 ASC_EEP_CMD_WRITE | addr);
13673 AdvWaitEEPCmd(iop_base);
b009bef6 13674 mdelay(ADV_EEP_DELAY_MS);
27c868c2 13675 }
1da177e4 13676
27c868c2
MW
13677 /*
13678 * Write EEPROM checksum at word 21.
13679 */
13680 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13681 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13682 AdvWaitEEPCmd(iop_base);
13683 wbuf++;
13684 charfields++;
13685
13686 /*
13687 * Write EEPROM OEM name at words 22 to 29.
13688 */
13689 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13690 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13691 ushort word;
13692
13693 if (*charfields++) {
13694 word = cpu_to_le16(*wbuf);
13695 } else {
13696 word = *wbuf;
13697 }
13698 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13699 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13700 ASC_EEP_CMD_WRITE | addr);
13701 AdvWaitEEPCmd(iop_base);
13702 }
13703 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13704 AdvWaitEEPCmd(iop_base);
13705 return;
1da177e4
LT
13706}
13707
13708/*
13709 * Write the EEPROM from 'cfg_buf'.
13710 */
78e77d8b 13711void __devinit
27c868c2 13712AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 13713{
27c868c2
MW
13714 ushort *wbuf;
13715 ushort *charfields;
13716 ushort addr, chksum;
13717
13718 wbuf = (ushort *)cfg_buf;
13719 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
13720 chksum = 0;
13721
13722 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13723 AdvWaitEEPCmd(iop_base);
13724
13725 /*
13726 * Write EEPROM from word 0 to word 20.
13727 */
13728 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13729 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13730 ushort word;
13731
13732 if (*charfields++) {
13733 word = cpu_to_le16(*wbuf);
13734 } else {
13735 word = *wbuf;
13736 }
13737 chksum += *wbuf; /* Checksum is calculated from word values. */
13738 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13739 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13740 ASC_EEP_CMD_WRITE | addr);
13741 AdvWaitEEPCmd(iop_base);
b009bef6 13742 mdelay(ADV_EEP_DELAY_MS);
27c868c2 13743 }
1da177e4 13744
27c868c2
MW
13745 /*
13746 * Write EEPROM checksum at word 21.
13747 */
13748 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13749 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13750 AdvWaitEEPCmd(iop_base);
13751 wbuf++;
13752 charfields++;
13753
13754 /*
13755 * Write EEPROM OEM name at words 22 to 29.
13756 */
13757 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13758 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13759 ushort word;
13760
13761 if (*charfields++) {
13762 word = cpu_to_le16(*wbuf);
13763 } else {
13764 word = *wbuf;
13765 }
13766 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13767 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13768 ASC_EEP_CMD_WRITE | addr);
13769 AdvWaitEEPCmd(iop_base);
13770 }
13771 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13772 AdvWaitEEPCmd(iop_base);
13773 return;
1da177e4
LT
13774}
13775
13776/* a_advlib.c */
13777/*
13778 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
13779 *
13780 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
13781 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
13782 * RISC to notify it a new command is ready to be executed.
13783 *
13784 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
13785 * set to SCSI_MAX_RETRY.
13786 *
13787 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
13788 * for DMA addresses or math operations are byte swapped to little-endian
13789 * order.
13790 *
13791 * Return:
13792 * ADV_SUCCESS(1) - The request was successfully queued.
13793 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
13794 * request completes.
13795 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
13796 * host IC error.
13797 */
27c868c2 13798static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 13799{
27c868c2
MW
13800 AdvPortAddr iop_base;
13801 ADV_DCNT req_size;
13802 ADV_PADDR req_paddr;
13803 ADV_CARR_T *new_carrp;
13804
27c868c2
MW
13805 /*
13806 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
13807 */
13808 if (scsiq->target_id > ADV_MAX_TID) {
13809 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
13810 scsiq->done_status = QD_WITH_ERROR;
13811 return ADV_ERROR;
13812 }
1da177e4 13813
27c868c2 13814 iop_base = asc_dvc->iop_base;
1da177e4 13815
27c868c2
MW
13816 /*
13817 * Allocate a carrier ensuring at least one carrier always
13818 * remains on the freelist and initialize fields.
13819 */
13820 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
27c868c2
MW
13821 return ADV_BUSY;
13822 }
13823 asc_dvc->carr_freelist = (ADV_CARR_T *)
13824 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
13825 asc_dvc->carr_pending_cnt++;
13826
13827 /*
13828 * Set the carrier to be a stopper by setting 'next_vpa'
13829 * to the stopper value. The current stopper will be changed
13830 * below to point to the new stopper.
13831 */
13832 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13833
13834 /*
13835 * Clear the ADV_SCSI_REQ_Q done flag.
13836 */
13837 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
13838
13839 req_size = sizeof(ADV_SCSI_REQ_Q);
13840 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
13841 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
13842
b009bef6
MW
13843 BUG_ON(req_paddr & 31);
13844 BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
27c868c2
MW
13845
13846 /* Wait for assertion before making little-endian */
13847 req_paddr = cpu_to_le32(req_paddr);
13848
13849 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
13850 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
13851 scsiq->scsiq_rptr = req_paddr;
13852
13853 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
13854 /*
13855 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
13856 * order during initialization.
13857 */
13858 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
13859
13860 /*
13861 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
13862 * the microcode. The newly allocated stopper will become the new
13863 * stopper.
13864 */
13865 asc_dvc->icq_sp->areq_vpa = req_paddr;
13866
13867 /*
13868 * Set the 'next_vpa' pointer for the old stopper to be the
13869 * physical address of the new stopper. The RISC can only
13870 * follow physical addresses.
13871 */
13872 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
13873
13874 /*
13875 * Set the host adapter stopper pointer to point to the new carrier.
13876 */
13877 asc_dvc->icq_sp = new_carrp;
13878
13879 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
13880 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13881 /*
13882 * Tickle the RISC to tell it to read its Command Queue Head pointer.
13883 */
13884 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
13885 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
13886 /*
13887 * Clear the tickle value. In the ASC-3550 the RISC flag
13888 * command 'clr_tickle_a' does not work unless the host
13889 * value is cleared.
13890 */
13891 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
13892 ADV_TICKLE_NOP);
13893 }
13894 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13895 /*
13896 * Notify the RISC a carrier is ready by writing the physical
13897 * address of the new carrier stopper to the COMMA register.
13898 */
13899 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
13900 le32_to_cpu(new_carrp->carr_pa));
13901 }
1da177e4 13902
27c868c2 13903 return ADV_SUCCESS;
1da177e4
LT
13904}
13905
13906/*
13907 * Reset SCSI Bus and purge all outstanding requests.
13908 *
13909 * Return Value:
13910 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
13911 * ADV_FALSE(0) - Microcode command failed.
13912 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
13913 * may be hung which requires driver recovery.
13914 */
27c868c2 13915static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 13916{
27c868c2
MW
13917 int status;
13918
13919 /*
13920 * Send the SCSI Bus Reset idle start idle command which asserts
13921 * the SCSI Bus Reset signal.
13922 */
13923 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
13924 if (status != ADV_TRUE) {
13925 return status;
13926 }
1da177e4 13927
27c868c2
MW
13928 /*
13929 * Delay for the specified SCSI Bus Reset hold time.
13930 *
13931 * The hold time delay is done on the host because the RISC has no
13932 * microsecond accurate timer.
13933 */
b009bef6 13934 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
27c868c2
MW
13935
13936 /*
13937 * Send the SCSI Bus Reset end idle command which de-asserts
13938 * the SCSI Bus Reset signal and purges any pending requests.
13939 */
13940 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
13941 if (status != ADV_TRUE) {
13942 return status;
13943 }
13944
b009bef6 13945 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
1da177e4 13946
27c868c2 13947 return status;
1da177e4
LT
13948}
13949
13950/*
13951 * Reset chip and SCSI Bus.
13952 *
13953 * Return Value:
13954 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
13955 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
13956 */
27c868c2 13957static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 13958{
27c868c2
MW
13959 int status;
13960 ushort wdtr_able, sdtr_able, tagqng_able;
13961 ushort ppr_able = 0;
13962 uchar tid, max_cmd[ADV_MAX_TID + 1];
13963 AdvPortAddr iop_base;
13964 ushort bios_sig;
13965
13966 iop_base = asc_dvc->iop_base;
13967
13968 /*
13969 * Save current per TID negotiated values.
13970 */
13971 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13972 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13973 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13974 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
13975 }
13976 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13977 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13978 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13979 max_cmd[tid]);
13980 }
1da177e4 13981
27c868c2
MW
13982 /*
13983 * Force the AdvInitAsc3550/38C0800Driver() function to
13984 * perform a SCSI Bus Reset by clearing the BIOS signature word.
13985 * The initialization functions assumes a SCSI Bus Reset is not
13986 * needed if the BIOS signature word is present.
13987 */
13988 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
13989 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
13990
13991 /*
13992 * Stop chip and reset it.
13993 */
13994 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
13995 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
b009bef6 13996 mdelay(100);
27c868c2
MW
13997 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13998 ADV_CTRL_REG_CMD_WR_IO_REG);
13999
14000 /*
14001 * Reset Adv Library error code, if any, and try
14002 * re-initializing the chip.
14003 */
14004 asc_dvc->err_code = 0;
14005 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14006 status = AdvInitAsc38C1600Driver(asc_dvc);
14007 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14008 status = AdvInitAsc38C0800Driver(asc_dvc);
14009 } else {
14010 status = AdvInitAsc3550Driver(asc_dvc);
14011 }
1da177e4 14012
27c868c2
MW
14013 /* Translate initialization return value to status value. */
14014 if (status == 0) {
14015 status = ADV_TRUE;
14016 } else {
14017 status = ADV_FALSE;
14018 }
1da177e4 14019
27c868c2
MW
14020 /*
14021 * Restore the BIOS signature word.
14022 */
14023 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
14024
14025 /*
14026 * Restore per TID negotiated values.
14027 */
14028 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14029 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14030 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14031 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14032 }
14033 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14034 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14035 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14036 max_cmd[tid]);
14037 }
1da177e4 14038
27c868c2 14039 return status;
1da177e4
LT
14040}
14041
14042/*
14043 * Adv Library Interrupt Service Routine
14044 *
14045 * This function is called by a driver's interrupt service routine.
14046 * The function disables and re-enables interrupts.
14047 *
14048 * When a microcode idle command is completed, the ADV_DVC_VAR
14049 * 'idle_cmd_done' field is set to ADV_TRUE.
14050 *
14051 * Note: AdvISR() can be called when interrupts are disabled or even
14052 * when there is no hardware interrupt condition present. It will
14053 * always check for completed idle commands and microcode requests.
14054 * This is an important feature that shouldn't be changed because it
14055 * allows commands to be completed from polling mode loops.
14056 *
14057 * Return:
14058 * ADV_TRUE(1) - interrupt was pending
14059 * ADV_FALSE(0) - no interrupt was pending
14060 */
27c868c2 14061static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 14062{
27c868c2
MW
14063 AdvPortAddr iop_base;
14064 uchar int_stat;
14065 ushort target_bit;
14066 ADV_CARR_T *free_carrp;
14067 ADV_VADDR irq_next_vpa;
27c868c2 14068 ADV_SCSI_REQ_Q *scsiq;
1da177e4 14069
27c868c2
MW
14070 iop_base = asc_dvc->iop_base;
14071
14072 /* Reading the register clears the interrupt. */
14073 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
14074
14075 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
14076 ADV_INTR_STATUS_INTRC)) == 0) {
27c868c2
MW
14077 return ADV_FALSE;
14078 }
14079
14080 /*
14081 * Notify the driver of an asynchronous microcode condition by
895d6b4c 14082 * calling the adv_async_callback function. The function
27c868c2
MW
14083 * is passed the microcode ASC_MC_INTRB_CODE byte value.
14084 */
14085 if (int_stat & ADV_INTR_STATUS_INTRB) {
14086 uchar intrb_code;
14087
14088 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
14089
14090 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
14091 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14092 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
14093 asc_dvc->carr_pending_cnt != 0) {
14094 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
14095 ADV_TICKLE_A);
14096 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14097 AdvWriteByteRegister(iop_base,
14098 IOPB_TICKLE,
14099 ADV_TICKLE_NOP);
14100 }
14101 }
14102 }
14103
895d6b4c 14104 adv_async_callback(asc_dvc, intrb_code);
27c868c2
MW
14105 }
14106
14107 /*
14108 * Check if the IRQ stopper carrier contains a completed request.
14109 */
14110 while (((irq_next_vpa =
14111 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
14112 /*
14113 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
14114 * The RISC will have set 'areq_vpa' to a virtual address.
14115 *
14116 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
14117 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
14118 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
14119 * in AdvExeScsiQueue().
14120 */
14121 scsiq = (ADV_SCSI_REQ_Q *)
14122 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
14123
14124 /*
14125 * Request finished with good status and the queue was not
14126 * DMAed to host memory by the firmware. Set all status fields
14127 * to indicate good status.
14128 */
14129 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
14130 scsiq->done_status = QD_NO_ERROR;
14131 scsiq->host_status = scsiq->scsi_status = 0;
14132 scsiq->data_cnt = 0L;
14133 }
14134
14135 /*
14136 * Advance the stopper pointer to the next carrier
14137 * ignoring the lower four bits. Free the previous
14138 * stopper carrier.
14139 */
14140 free_carrp = asc_dvc->irq_sp;
14141 asc_dvc->irq_sp = (ADV_CARR_T *)
14142 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
14143
14144 free_carrp->next_vpa =
14145 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14146 asc_dvc->carr_freelist = free_carrp;
14147 asc_dvc->carr_pending_cnt--;
14148
27c868c2
MW
14149 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
14150
14151 /*
14152 * Clear request microcode control flag.
14153 */
14154 scsiq->cntl = 0;
14155
27c868c2
MW
14156 /*
14157 * Notify the driver of the completed request by passing
14158 * the ADV_SCSI_REQ_Q pointer to its callback function.
14159 */
14160 scsiq->a_flag |= ADV_SCSIQ_DONE;
895d6b4c 14161 adv_isr_callback(asc_dvc, scsiq);
27c868c2
MW
14162 /*
14163 * Note: After the driver callback function is called, 'scsiq'
14164 * can no longer be referenced.
14165 *
14166 * Fall through and continue processing other completed
14167 * requests...
14168 */
27c868c2 14169 }
27c868c2 14170 return ADV_TRUE;
1da177e4
LT
14171}
14172
14173/*
14174 * Send an idle command to the chip and wait for completion.
14175 *
14176 * Command completion is polled for once per microsecond.
14177 *
14178 * The function can be called from anywhere including an interrupt handler.
14179 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
14180 * functions to prevent reentrancy.
14181 *
14182 * Return Values:
14183 * ADV_TRUE - command completed successfully
14184 * ADV_FALSE - command failed
14185 * ADV_ERROR - command timed out
14186 */
27c868c2 14187static int
1da177e4 14188AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 14189 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 14190{
27c868c2
MW
14191 int result;
14192 ADV_DCNT i, j;
14193 AdvPortAddr iop_base;
14194
27c868c2
MW
14195 iop_base = asc_dvc->iop_base;
14196
14197 /*
14198 * Clear the idle command status which is set by the microcode
14199 * to a non-zero value to indicate when the command is completed.
14200 * The non-zero result is one of the IDLE_CMD_STATUS_* values
14201 * defined in a_advlib.h.
14202 */
14203 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
14204
14205 /*
14206 * Write the idle command value after the idle command parameter
14207 * has been written to avoid a race condition. If the order is not
14208 * followed, the microcode may process the idle command before the
14209 * parameters have been written to LRAM.
14210 */
14211 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
14212 cpu_to_le32(idle_cmd_parameter));
14213 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
14214
14215 /*
14216 * Tickle the RISC to tell it to process the idle command.
14217 */
14218 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
14219 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14220 /*
14221 * Clear the tickle value. In the ASC-3550 the RISC flag
14222 * command 'clr_tickle_b' does not work unless the host
14223 * value is cleared.
14224 */
14225 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
14226 }
1da177e4 14227
27c868c2
MW
14228 /* Wait for up to 100 millisecond for the idle command to timeout. */
14229 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
14230 /* Poll once each microsecond for command completion. */
14231 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
14232 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
14233 result);
b009bef6 14234 if (result != 0)
27c868c2 14235 return result;
b009bef6 14236 udelay(1);
27c868c2
MW
14237 }
14238 }
1da177e4 14239
b009bef6 14240 BUG(); /* The idle command should never timeout. */
27c868c2 14241 return ADV_ERROR;
1da177e4
LT
14242}
14243
b2c16f58
MW
14244static int __devinit
14245advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
14246{
14247 int req_cnt = 0;
14248 adv_req_t *reqp = NULL;
14249 int sg_cnt = 0;
14250 adv_sgblk_t *sgp;
14251 int warn_code, err_code;
14252
14253 /*
14254 * Allocate buffer carrier structures. The total size
14255 * is about 4 KB, so allocate all at once.
14256 */
14257 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
14258 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
14259
14260 if (!boardp->carrp)
14261 goto kmalloc_failed;
14262
14263 /*
14264 * Allocate up to 'max_host_qng' request structures for the Wide
14265 * board. The total size is about 16 KB, so allocate all at once.
14266 * If the allocation fails decrement and try again.
14267 */
14268 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
14269 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
14270
14271 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
14272 "bytes %lu\n", reqp, req_cnt,
14273 (ulong)sizeof(adv_req_t) * req_cnt);
14274
14275 if (reqp)
14276 break;
14277 }
14278
14279 if (!reqp)
14280 goto kmalloc_failed;
14281
14282 boardp->orig_reqp = reqp;
14283
14284 /*
14285 * Allocate up to ADV_TOT_SG_BLOCK request structures for
14286 * the Wide board. Each structure is about 136 bytes.
14287 */
14288 boardp->adv_sgblkp = NULL;
14289 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
14290 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
14291
14292 if (!sgp)
14293 break;
14294
14295 sgp->next_sgblkp = boardp->adv_sgblkp;
14296 boardp->adv_sgblkp = sgp;
14297
14298 }
14299
14300 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
14301 sg_cnt, sizeof(adv_sgblk_t),
14302 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
14303
14304 if (!boardp->adv_sgblkp)
14305 goto kmalloc_failed;
14306
14307 adv_dvc_varp->carrier_buf = boardp->carrp;
14308
14309 /*
14310 * Point 'adv_reqp' to the request structures and
14311 * link them together.
14312 */
14313 req_cnt--;
14314 reqp[req_cnt].next_reqp = NULL;
14315 for (; req_cnt > 0; req_cnt--) {
14316 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
14317 }
14318 boardp->adv_reqp = &reqp[0];
14319
14320 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
14321 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
14322 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
14323 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14324 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
14325 "\n");
14326 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
14327 } else {
14328 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
14329 "\n");
14330 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
14331 }
14332 err_code = adv_dvc_varp->err_code;
14333
14334 if (warn_code || err_code) {
14335 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
14336 " error 0x%x\n", boardp->id, warn_code, err_code);
14337 }
14338
14339 goto exit;
14340
14341 kmalloc_failed:
14342 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
14343 "failed\n", boardp->id);
14344 err_code = ADV_ERROR;
14345 exit:
14346 return err_code;
14347}
14348
14349static void advansys_wide_free_mem(asc_board_t *boardp)
14350{
14351 kfree(boardp->carrp);
14352 boardp->carrp = NULL;
14353 kfree(boardp->orig_reqp);
14354 boardp->orig_reqp = boardp->adv_reqp = NULL;
14355 while (boardp->adv_sgblkp) {
14356 adv_sgblk_t *sgp = boardp->adv_sgblkp;
14357 boardp->adv_sgblkp = sgp->next_sgblkp;
14358 kfree(sgp);
14359 }
14360}
14361
27c868c2
MW
14362static struct Scsi_Host *__devinit
14363advansys_board_found(int iop, struct device *dev, int bus_type)
14364{
14365 struct Scsi_Host *shost;
14366 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
14367 asc_board_t *boardp;
14368 ASC_DVC_VAR *asc_dvc_varp = NULL;
14369 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 14370 int share_irq;
27c868c2
MW
14371 int warn_code, err_code;
14372 int ret;
14373
14374 /*
27c868c2
MW
14375 * Register the adapter, get its configuration, and
14376 * initialize it.
14377 */
8dfb5379
MW
14378 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
14379 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
14380 if (!shost)
14381 return NULL;
14382
27c868c2
MW
14383 /* Initialize private per board data */
14384 boardp = ASC_BOARDP(shost);
14385 memset(boardp, 0, sizeof(asc_board_t));
78e77d8b 14386 boardp->id = asc_board_count++;
27c868c2 14387 spin_lock_init(&boardp->lock);
394dbf3f 14388 boardp->dev = dev;
27c868c2
MW
14389
14390 /*
14391 * Handle both narrow and wide boards.
14392 *
14393 * If a Wide board was detected, set the board structure
14394 * wide board flag. Set-up the board structure based on
14395 * the board type.
14396 */
14397#ifdef CONFIG_PCI
14398 if (bus_type == ASC_IS_PCI &&
14399 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14400 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14401 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
14402 boardp->flags |= ASC_IS_WIDE_BOARD;
14403 }
14404#endif /* CONFIG_PCI */
14405
14406 if (ASC_NARROW_BOARD(boardp)) {
14407 ASC_DBG(1, "advansys_board_found: narrow board\n");
14408 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
14409 asc_dvc_varp->bus_type = bus_type;
14410 asc_dvc_varp->drv_ptr = boardp;
14411 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
14412 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
14413 asc_dvc_varp->iop_base = iop;
27c868c2 14414 } else {
57ba5fe9 14415#ifdef CONFIG_PCI
27c868c2
MW
14416 ASC_DBG(1, "advansys_board_found: wide board\n");
14417 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
14418 adv_dvc_varp->drv_ptr = boardp;
14419 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
27c868c2
MW
14420 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
14421 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
14422 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
14423 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
14424 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
14425 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
14426 } else {
14427 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
14428 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
14429 }
27c868c2 14430
57ba5fe9
MW
14431 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
14432 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
14433 boardp->asc_n_io_port);
14434 if (!boardp->ioremap_addr) {
27c868c2
MW
14435 ASC_PRINT3
14436 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
57ba5fe9
MW
14437 boardp->id, pci_resource_start(pdev, 1),
14438 boardp->asc_n_io_port);
b2c16f58 14439 goto err_shost;
27c868c2 14440 }
57ba5fe9 14441 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
71f36115 14442 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
27c868c2 14443 adv_dvc_varp->iop_base);
27c868c2
MW
14444
14445 /*
14446 * Even though it isn't used to access wide boards, other
14447 * than for the debug line below, save I/O Port address so
14448 * that it can be reported.
14449 */
14450 boardp->ioport = iop;
14451
57ba5fe9
MW
14452 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
14453 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
14454 (ushort)inpw(iop));
14455#endif /* CONFIG_PCI */
27c868c2
MW
14456 }
14457
14458#ifdef CONFIG_PROC_FS
14459 /*
14460 * Allocate buffer for printing information from
14461 * /proc/scsi/advansys/[0...].
14462 */
b2c16f58
MW
14463 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
14464 if (!boardp->prtbuf) {
14465 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
14466 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
14467 goto err_unmap;
27c868c2
MW
14468 }
14469#endif /* CONFIG_PROC_FS */
14470
14471 if (ASC_NARROW_BOARD(boardp)) {
27c868c2
MW
14472 /*
14473 * Set the board bus type and PCI IRQ before
14474 * calling AscInitGetConfig().
14475 */
14476 switch (asc_dvc_varp->bus_type) {
14477#ifdef CONFIG_ISA
14478 case ASC_IS_ISA:
14479 shost->unchecked_isa_dma = TRUE;
074c8fe4 14480 share_irq = 0;
27c868c2
MW
14481 break;
14482 case ASC_IS_VL:
14483 shost->unchecked_isa_dma = FALSE;
074c8fe4 14484 share_irq = 0;
27c868c2
MW
14485 break;
14486 case ASC_IS_EISA:
14487 shost->unchecked_isa_dma = FALSE;
074c8fe4 14488 share_irq = IRQF_SHARED;
27c868c2
MW
14489 break;
14490#endif /* CONFIG_ISA */
14491#ifdef CONFIG_PCI
14492 case ASC_IS_PCI:
14493 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
27c868c2 14494 shost->unchecked_isa_dma = FALSE;
074c8fe4 14495 share_irq = IRQF_SHARED;
27c868c2
MW
14496 break;
14497#endif /* CONFIG_PCI */
14498 default:
14499 ASC_PRINT2
14500 ("advansys_board_found: board %d: unknown adapter type: %d\n",
14501 boardp->id, asc_dvc_varp->bus_type);
14502 shost->unchecked_isa_dma = TRUE;
074c8fe4 14503 share_irq = 0;
27c868c2
MW
14504 break;
14505 }
27c868c2 14506
27c868c2
MW
14507 /*
14508 * NOTE: AscInitGetConfig() may change the board's
14509 * bus_type value. The bus_type value should no
14510 * longer be used. If the bus_type field must be
14511 * referenced only use the bit-wise AND operator "&".
14512 */
14513 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
c2dce2fa 14514 err_code = AscInitGetConfig(boardp);
27c868c2 14515 } else {
c2dce2fa
MW
14516#ifdef CONFIG_PCI
14517 /*
14518 * For Wide boards set PCI information before calling
14519 * AdvInitGetConfig().
14520 */
14521 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
14522 shost->unchecked_isa_dma = FALSE;
14523 share_irq = IRQF_SHARED;
27c868c2 14524 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
394dbf3f 14525
c2dce2fa
MW
14526 err_code = AdvInitGetConfig(pdev, boardp);
14527#endif /* CONFIG_PCI */
27c868c2
MW
14528 }
14529
b2c16f58
MW
14530 if (err_code != 0)
14531 goto err_free_proc;
27c868c2
MW
14532
14533 /*
14534 * Save the EEPROM configuration so that it can be displayed
14535 * from /proc/scsi/advansys/[0...].
14536 */
14537 if (ASC_NARROW_BOARD(boardp)) {
14538
14539 ASCEEP_CONFIG *ep;
14540
14541 /*
14542 * Set the adapter's target id bit in the 'init_tidmask' field.
14543 */
14544 boardp->init_tidmask |=
14545 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
14546
14547 /*
14548 * Save EEPROM settings for the board.
14549 */
14550 ep = &boardp->eep_config.asc_eep;
14551
14552 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
14553 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
14554 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
14555 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
14556 ep->start_motor = asc_dvc_varp->start_motor;
14557 ep->cntl = asc_dvc_varp->dvc_cntl;
14558 ep->no_scam = asc_dvc_varp->no_scam;
14559 ep->max_total_qng = asc_dvc_varp->max_total_qng;
14560 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
14561 /* 'max_tag_qng' is set to the same value for every device. */
14562 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
14563 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
14564 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
14565 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
14566 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
14567 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
14568 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
14569
14570 /*
14571 * Modify board configuration.
14572 */
14573 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
c2dce2fa
MW
14574 err_code = AscInitSetConfig(pdev, boardp);
14575 if (err_code)
b2c16f58 14576 goto err_free_proc;
27c868c2
MW
14577
14578 /*
14579 * Finish initializing the 'Scsi_Host' structure.
14580 */
14581 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
14582 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
14583 shost->irq = asc_dvc_varp->irq_no;
14584 }
14585 } else {
14586 ADVEEP_3550_CONFIG *ep_3550;
14587 ADVEEP_38C0800_CONFIG *ep_38C0800;
14588 ADVEEP_38C1600_CONFIG *ep_38C1600;
14589
14590 /*
14591 * Save Wide EEP Configuration Information.
14592 */
14593 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
14594 ep_3550 = &boardp->eep_config.adv_3550_eep;
14595
14596 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
14597 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
14598 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14599 ep_3550->termination = adv_dvc_varp->cfg->termination;
14600 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
14601 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
14602 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
14603 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
14604 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
14605 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
14606 ep_3550->start_motor = adv_dvc_varp->start_motor;
14607 ep_3550->scsi_reset_delay =
14608 adv_dvc_varp->scsi_reset_wait;
14609 ep_3550->serial_number_word1 =
14610 adv_dvc_varp->cfg->serial1;
14611 ep_3550->serial_number_word2 =
14612 adv_dvc_varp->cfg->serial2;
14613 ep_3550->serial_number_word3 =
14614 adv_dvc_varp->cfg->serial3;
14615 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14616 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
14617
14618 ep_38C0800->adapter_scsi_id =
14619 adv_dvc_varp->chip_scsi_id;
14620 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
14621 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14622 ep_38C0800->termination_lvd =
14623 adv_dvc_varp->cfg->termination;
14624 ep_38C0800->disc_enable =
14625 adv_dvc_varp->cfg->disc_enable;
14626 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
14627 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
14628 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14629 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14630 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14631 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14632 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14633 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14634 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
14635 ep_38C0800->scsi_reset_delay =
14636 adv_dvc_varp->scsi_reset_wait;
14637 ep_38C0800->serial_number_word1 =
14638 adv_dvc_varp->cfg->serial1;
14639 ep_38C0800->serial_number_word2 =
14640 adv_dvc_varp->cfg->serial2;
14641 ep_38C0800->serial_number_word3 =
14642 adv_dvc_varp->cfg->serial3;
14643 } else {
14644 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
14645
14646 ep_38C1600->adapter_scsi_id =
14647 adv_dvc_varp->chip_scsi_id;
14648 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
14649 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14650 ep_38C1600->termination_lvd =
14651 adv_dvc_varp->cfg->termination;
14652 ep_38C1600->disc_enable =
14653 adv_dvc_varp->cfg->disc_enable;
14654 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
14655 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
14656 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14657 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14658 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14659 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14660 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14661 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14662 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
14663 ep_38C1600->scsi_reset_delay =
14664 adv_dvc_varp->scsi_reset_wait;
14665 ep_38C1600->serial_number_word1 =
14666 adv_dvc_varp->cfg->serial1;
14667 ep_38C1600->serial_number_word2 =
14668 adv_dvc_varp->cfg->serial2;
14669 ep_38C1600->serial_number_word3 =
14670 adv_dvc_varp->cfg->serial3;
14671 }
14672
14673 /*
14674 * Set the adapter's target id bit in the 'init_tidmask' field.
14675 */
14676 boardp->init_tidmask |=
14677 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
27c868c2
MW
14678 }
14679
14680 /*
14681 * Channels are numbered beginning with 0. For AdvanSys one host
14682 * structure supports one channel. Multi-channel boards have a
14683 * separate host structure for each channel.
14684 */
14685 shost->max_channel = 0;
14686 if (ASC_NARROW_BOARD(boardp)) {
14687 shost->max_id = ASC_MAX_TID + 1;
14688 shost->max_lun = ASC_MAX_LUN + 1;
f05ec594 14689 shost->max_cmd_len = ASC_MAX_CDB_LEN;
27c868c2
MW
14690
14691 shost->io_port = asc_dvc_varp->iop_base;
14692 boardp->asc_n_io_port = ASC_IOADR_GAP;
14693 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
14694
14695 /* Set maximum number of queues the adapter can handle. */
14696 shost->can_queue = asc_dvc_varp->max_total_qng;
14697 } else {
14698 shost->max_id = ADV_MAX_TID + 1;
14699 shost->max_lun = ADV_MAX_LUN + 1;
f05ec594 14700 shost->max_cmd_len = ADV_MAX_CDB_LEN;
27c868c2
MW
14701
14702 /*
14703 * Save the I/O Port address and length even though
14704 * I/O ports are not used to access Wide boards.
14705 * Instead the Wide boards are accessed with
14706 * PCI Memory Mapped I/O.
14707 */
14708 shost->io_port = iop;
27c868c2
MW
14709
14710 shost->this_id = adv_dvc_varp->chip_scsi_id;
14711
14712 /* Set maximum number of queues the adapter can handle. */
14713 shost->can_queue = adv_dvc_varp->max_host_qng;
14714 }
14715
27c868c2
MW
14716 /*
14717 * Following v1.3.89, 'cmd_per_lun' is no longer needed
14718 * and should be set to zero.
14719 *
14720 * But because of a bug introduced in v1.3.89 if the driver is
14721 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
14722 * SCSI function 'allocate_device' will panic. To allow the driver
14723 * to work as a module in these kernels set 'cmd_per_lun' to 1.
14724 *
14725 * Note: This is wrong. cmd_per_lun should be set to the depth
14726 * you want on untagged devices always.
14727 #ifdef MODULE
14728 */
14729 shost->cmd_per_lun = 1;
14730/* #else
14731 shost->cmd_per_lun = 0;
14732#endif */
14733
14734 /*
14735 * Set the maximum number of scatter-gather elements the
14736 * adapter can handle.
14737 */
14738 if (ASC_NARROW_BOARD(boardp)) {
14739 /*
14740 * Allow two commands with 'sg_tablesize' scatter-gather
14741 * elements to be executed simultaneously. This value is
14742 * the theoretical hardware limit. It may be decreased
14743 * below.
14744 */
14745 shost->sg_tablesize =
14746 (((asc_dvc_varp->max_total_qng - 2) / 2) *
14747 ASC_SG_LIST_PER_Q) + 1;
14748 } else {
14749 shost->sg_tablesize = ADV_MAX_SG_LIST;
14750 }
14751
14752 /*
14753 * The value of 'sg_tablesize' can not exceed the SCSI
14754 * mid-level driver definition of SG_ALL. SG_ALL also
14755 * must not be exceeded, because it is used to define the
14756 * size of the scatter-gather table in 'struct asc_sg_head'.
14757 */
14758 if (shost->sg_tablesize > SG_ALL) {
14759 shost->sg_tablesize = SG_ALL;
14760 }
14761
14762 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
14763
14764 /* BIOS start address. */
14765 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
14766 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
14767 asc_dvc_varp->bus_type);
27c868c2
MW
14768 } else {
14769 /*
14770 * Fill-in BIOS board variables. The Wide BIOS saves
14771 * information in LRAM that is used by the driver.
14772 */
14773 AdvReadWordLram(adv_dvc_varp->iop_base,
14774 BIOS_SIGNATURE, boardp->bios_signature);
14775 AdvReadWordLram(adv_dvc_varp->iop_base,
14776 BIOS_VERSION, boardp->bios_version);
14777 AdvReadWordLram(adv_dvc_varp->iop_base,
14778 BIOS_CODESEG, boardp->bios_codeseg);
14779 AdvReadWordLram(adv_dvc_varp->iop_base,
14780 BIOS_CODELEN, boardp->bios_codelen);
14781
14782 ASC_DBG2(1,
14783 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
14784 boardp->bios_signature, boardp->bios_version);
14785
14786 ASC_DBG2(1,
14787 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
14788 boardp->bios_codeseg, boardp->bios_codelen);
14789
14790 /*
14791 * If the BIOS saved a valid signature, then fill in
14792 * the BIOS code segment base address.
14793 */
14794 if (boardp->bios_signature == 0x55AA) {
14795 /*
14796 * Convert x86 realmode code segment to a linear
14797 * address by shifting left 4.
14798 */
14799 shost->base = ((ulong)boardp->bios_codeseg << 4);
14800 } else {
14801 shost->base = 0;
14802 }
14803 }
14804
14805 /*
14806 * Register Board Resources - I/O Port, DMA, IRQ
14807 */
14808
27c868c2
MW
14809 /* Register DMA Channel for Narrow boards. */
14810 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
14811#ifdef CONFIG_ISA
14812 if (ASC_NARROW_BOARD(boardp)) {
14813 /* Register DMA channel for ISA bus. */
14814 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
14815 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
b2c16f58
MW
14816 ret = request_dma(shost->dma_channel, "advansys");
14817 if (ret) {
27c868c2
MW
14818 ASC_PRINT3
14819 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
14820 boardp->id, shost->dma_channel, ret);
71f36115 14821 goto err_free_proc;
27c868c2
MW
14822 }
14823 AscEnableIsaDma(shost->dma_channel);
14824 }
14825 }
14826#endif /* CONFIG_ISA */
14827
14828 /* Register IRQ Number. */
14829 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
14830
14831 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
14832 "advansys", shost);
14833
14834 if (ret) {
27c868c2
MW
14835 if (ret == -EBUSY) {
14836 ASC_PRINT2
14837 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14838 boardp->id, shost->irq);
14839 } else if (ret == -EINVAL) {
14840 ASC_PRINT2
14841 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14842 boardp->id, shost->irq);
14843 } else {
14844 ASC_PRINT3
14845 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14846 boardp->id, shost->irq, ret);
14847 }
b2c16f58 14848 goto err_free_dma;
27c868c2
MW
14849 }
14850
14851 /*
14852 * Initialize board RISC chip and enable interrupts.
14853 */
14854 if (ASC_NARROW_BOARD(boardp)) {
14855 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
14856 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14857 err_code = asc_dvc_varp->err_code;
14858
14859 if (warn_code || err_code) {
14860 ASC_PRINT4
14861 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
14862 boardp->id,
14863 asc_dvc_varp->init_state, warn_code, err_code);
14864 }
14865 } else {
b2c16f58 14866 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
14867 }
14868
b2c16f58
MW
14869 if (err_code != 0)
14870 goto err_free_wide_mem;
14871
27c868c2
MW
14872 ASC_DBG_PRT_SCSI_HOST(2, shost);
14873
8dfb5379
MW
14874 ret = scsi_add_host(shost, dev);
14875 if (ret)
14876 goto err_free_wide_mem;
14877
14878 scsi_scan_host(shost);
27c868c2 14879 return shost;
b2c16f58
MW
14880
14881 err_free_wide_mem:
14882 advansys_wide_free_mem(boardp);
14883 free_irq(shost->irq, shost);
14884 err_free_dma:
14885 if (shost->dma_channel != NO_ISA_DMA)
14886 free_dma(shost->dma_channel);
b2c16f58
MW
14887 err_free_proc:
14888 kfree(boardp->prtbuf);
14889 err_unmap:
14890 if (boardp->ioremap_addr)
14891 iounmap(boardp->ioremap_addr);
14892 err_shost:
8dfb5379 14893 scsi_host_put(shost);
b2c16f58 14894 return NULL;
27c868c2
MW
14895}
14896
27c868c2
MW
14897/*
14898 * advansys_release()
14899 *
14900 * Release resources allocated for a single AdvanSys adapter.
14901 */
14902static int advansys_release(struct Scsi_Host *shost)
14903{
14904 asc_board_t *boardp;
14905
14906 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 14907 scsi_remove_host(shost);
27c868c2 14908 boardp = ASC_BOARDP(shost);
074c8fe4 14909 free_irq(shost->irq, shost);
27c868c2
MW
14910 if (shost->dma_channel != NO_ISA_DMA) {
14911 ASC_DBG(1, "advansys_release: free_dma()\n");
14912 free_dma(shost->dma_channel);
14913 }
27c868c2 14914 if (ASC_WIDE_BOARD(boardp)) {
27c868c2 14915 iounmap(boardp->ioremap_addr);
b2c16f58 14916 advansys_wide_free_mem(boardp);
27c868c2 14917 }
27c868c2 14918 kfree(boardp->prtbuf);
8dfb5379 14919 scsi_host_put(shost);
27c868c2
MW
14920 ASC_DBG(1, "advansys_release: end\n");
14921 return 0;
14922}
14923
c304ec94
MW
14924static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14925 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14926 0x0210, 0x0230, 0x0250, 0x0330
14927};
14928
14929static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14930{
14931 PortAddr iop_base = _asc_def_iop_base[id];
14932 struct Scsi_Host *shost;
14933
14934 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
14935 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
14936 iop_base);
c304ec94
MW
14937 return -ENODEV;
14938 }
14939 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
14940 if (!AscFindSignature(iop_base))
14941 goto nodev;
14942 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14943 goto nodev;
14944
14945 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
c304ec94
MW
14946 if (!shost)
14947 goto nodev;
14948
14949 dev_set_drvdata(dev, shost);
14950 return 0;
14951
14952 nodev:
71f36115 14953 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
14954 return -ENODEV;
14955}
14956
14957static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14958{
71f36115 14959 int ioport = _asc_def_iop_base[id];
c304ec94 14960 advansys_release(dev_get_drvdata(dev));
71f36115 14961 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
14962 return 0;
14963}
14964
14965static struct isa_driver advansys_isa_driver = {
14966 .probe = advansys_isa_probe,
14967 .remove = __devexit_p(advansys_isa_remove),
14968 .driver = {
14969 .owner = THIS_MODULE,
14970 .name = "advansys",
14971 },
14972};
14973
14974static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14975{
14976 PortAddr iop_base = _asc_def_iop_base[id];
14977 struct Scsi_Host *shost;
14978
14979 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
14980 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
14981 iop_base);
c304ec94
MW
14982 return -ENODEV;
14983 }
14984 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
14985 if (!AscFindSignature(iop_base))
14986 goto nodev;
14987 /*
14988 * I don't think this condition can actually happen, but the old
14989 * driver did it, and the chances of finding a VLB setup in 2007
14990 * to do testing with is slight to none.
14991 */
14992 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14993 goto nodev;
14994
14995 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
c304ec94
MW
14996 if (!shost)
14997 goto nodev;
14998
14999 dev_set_drvdata(dev, shost);
15000 return 0;
15001
15002 nodev:
71f36115 15003 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
15004 return -ENODEV;
15005}
15006
15007static struct isa_driver advansys_vlb_driver = {
15008 .probe = advansys_vlb_probe,
15009 .remove = __devexit_p(advansys_isa_remove),
15010 .driver = {
15011 .owner = THIS_MODULE,
b8e5152b 15012 .name = "advansys_vlb",
c304ec94
MW
15013 },
15014};
15015
b09e05a7
MW
15016static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
15017 { "ABP7401" },
15018 { "ABP7501" },
15019 { "" }
15020};
15021
15022MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
15023
15024/*
15025 * EISA is a little more tricky than PCI; each EISA device may have two
15026 * channels, and this driver is written to make each channel its own Scsi_Host
15027 */
15028struct eisa_scsi_data {
15029 struct Scsi_Host *host[2];
15030};
15031
15032static int __devinit advansys_eisa_probe(struct device *dev)
15033{
15034 int i, ioport;
15035 int err;
15036 struct eisa_device *edev = to_eisa_device(dev);
15037 struct eisa_scsi_data *data;
15038
15039 err = -ENOMEM;
15040 data = kzalloc(sizeof(*data), GFP_KERNEL);
15041 if (!data)
15042 goto fail;
15043 ioport = edev->base_addr + 0xc30;
15044
15045 err = -ENODEV;
15046 for (i = 0; i < 2; i++, ioport += 0x20) {
71f36115
MW
15047 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
15048 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
15049 ioport + ASC_IOADR_GAP - 1);
15050 continue;
15051 }
15052 if (!AscFindSignature(ioport)) {
15053 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 15054 continue;
71f36115
MW
15055 }
15056
b09e05a7
MW
15057 /*
15058 * I don't know why we need to do this for EISA chips, but
15059 * not for any others. It looks to be equivalent to
15060 * AscGetChipCfgMsw, but I may have overlooked something,
15061 * so I'm not converting it until I get an EISA board to
15062 * test with.
15063 */
15064 inw(ioport + 4);
15065 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
71f36115 15066 if (data->host[i]) {
b09e05a7 15067 err = 0;
71f36115
MW
15068 } else {
15069 release_region(ioport, ASC_IOADR_GAP);
15070 }
b09e05a7
MW
15071 }
15072
15073 if (err) {
15074 kfree(data);
15075 } else {
15076 dev_set_drvdata(dev, data);
15077 }
15078
15079 fail:
15080 return err;
15081}
15082
15083static __devexit int advansys_eisa_remove(struct device *dev)
15084{
15085 int i;
15086 struct eisa_scsi_data *data = dev_get_drvdata(dev);
15087
15088 for (i = 0; i < 2; i++) {
71f36115 15089 int ioport;
b09e05a7
MW
15090 struct Scsi_Host *shost = data->host[i];
15091 if (!shost)
15092 continue;
71f36115 15093 ioport = shost->io_port;
b09e05a7 15094 advansys_release(shost);
71f36115 15095 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
15096 }
15097
15098 kfree(data);
15099 return 0;
15100}
15101
15102static struct eisa_driver advansys_eisa_driver = {
15103 .id_table = advansys_eisa_table,
15104 .driver = {
15105 .name = "advansys",
15106 .probe = advansys_eisa_probe,
15107 .remove = __devexit_p(advansys_eisa_remove),
15108 }
15109};
15110
2672ea86
DJ
15111/* PCI Devices supported by this driver */
15112static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
15113 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
15114 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15115 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
15116 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15117 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
15118 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15119 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
15120 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15121 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
15122 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15123 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
15124 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15125 {}
2672ea86 15126};
27c868c2 15127
2672ea86 15128MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b 15129
9649af39
MW
15130static void __devinit advansys_set_latency(struct pci_dev *pdev)
15131{
15132 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
15133 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
15134 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
15135 } else {
15136 u8 latency;
15137 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
15138 if (latency < 0x20)
15139 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
15140 }
15141}
15142
78e77d8b
MW
15143static int __devinit
15144advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
15145{
15146 int err, ioport;
15147 struct Scsi_Host *shost;
15148
15149 err = pci_enable_device(pdev);
15150 if (err)
15151 goto fail;
71f36115
MW
15152 err = pci_request_regions(pdev, "advansys");
15153 if (err)
15154 goto disable_device;
9649af39
MW
15155 pci_set_master(pdev);
15156 advansys_set_latency(pdev);
78e77d8b
MW
15157
15158 if (pci_resource_len(pdev, 0) == 0)
15159 goto nodev;
15160
15161 ioport = pci_resource_start(pdev, 0);
15162 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
15163
15164 if (!shost)
15165 goto nodev;
15166
15167 pci_set_drvdata(pdev, shost);
15168 return 0;
15169
15170 nodev:
15171 err = -ENODEV;
71f36115
MW
15172 pci_release_regions(pdev);
15173 disable_device:
78e77d8b
MW
15174 pci_disable_device(pdev);
15175 fail:
15176 return err;
15177}
15178
15179static void __devexit advansys_pci_remove(struct pci_dev *pdev)
15180{
15181 advansys_release(pci_get_drvdata(pdev));
71f36115 15182 pci_release_regions(pdev);
78e77d8b
MW
15183 pci_disable_device(pdev);
15184}
15185
15186static struct pci_driver advansys_pci_driver = {
15187 .name = "advansys",
15188 .id_table = advansys_pci_tbl,
15189 .probe = advansys_pci_probe,
15190 .remove = __devexit_p(advansys_pci_remove),
15191};
8c6af9e1 15192
8dfb5379
MW
15193static int __init advansys_init(void)
15194{
c304ec94 15195 int error;
b09e05a7 15196
c304ec94
MW
15197 error = isa_register_driver(&advansys_isa_driver,
15198 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
15199 if (error)
15200 goto fail;
8dfb5379 15201
c304ec94
MW
15202 error = isa_register_driver(&advansys_vlb_driver,
15203 ASC_IOADR_TABLE_MAX_IX);
15204 if (error)
15205 goto unregister_isa;
15206
15207 error = eisa_driver_register(&advansys_eisa_driver);
15208 if (error)
15209 goto unregister_vlb;
15210
b09e05a7
MW
15211 error = pci_register_driver(&advansys_pci_driver);
15212 if (error)
15213 goto unregister_eisa;
15214
8dfb5379 15215 return 0;
78e77d8b 15216
b09e05a7
MW
15217 unregister_eisa:
15218 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15219 unregister_vlb:
15220 isa_unregister_driver(&advansys_vlb_driver);
15221 unregister_isa:
15222 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 15223 fail:
78e77d8b 15224 return error;
8dfb5379
MW
15225}
15226
15227static void __exit advansys_exit(void)
15228{
78e77d8b 15229 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 15230 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15231 isa_unregister_driver(&advansys_vlb_driver);
15232 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
15233}
15234
15235module_init(advansys_init);
15236module_exit(advansys_exit);
15237
8c6af9e1 15238MODULE_LICENSE("GPL");