]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/scsi/advansys.c
[SCSI] advansys: Remove a check for an impossible condition
[mirror_ubuntu-artful-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 assertions. */
74#define ADVANSYS_ASSERT
75
76/* Enable driver /proc statistics. */
77#define ADVANSYS_STATS
78
79/* Enable driver tracing. */
80/* #define ADVANSYS_DEBUG */
81
1da177e4
LT
82/*
83 * --- Asc Library Constants and Macros
84 */
85
86#define ASC_LIB_VERSION_MAJOR 1
87#define ASC_LIB_VERSION_MINOR 24
88#define ASC_LIB_SERIAL_NUMBER 123
89
90/*
91 * Portable Data Types
92 *
93 * Any instance where a 32-bit long or pointer type is assumed
94 * for precision or HW defined structures, the following define
95 * types must be used. In Linux the char, short, and int types
96 * are all consistent at 8, 16, and 32 bits respectively. Pointers
97 * and long types are 64 bits on Alpha and UltraSPARC.
98 */
27c868c2
MW
99#define ASC_PADDR __u32 /* Physical/Bus address data type. */
100#define ASC_VADDR __u32 /* Virtual address data type. */
101#define ASC_DCNT __u32 /* Unsigned Data count type. */
102#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
103
104/*
105 * These macros are used to convert a virtual address to a
106 * 32-bit value. This currently can be used on Linux Alpha
107 * which uses 64-bit virtual address but a 32-bit bus address.
108 * This is likely to break in the future, but doing this now
109 * will give us time to change the HW and FW to handle 64-bit
110 * addresses.
111 */
112#define ASC_VADDR_TO_U32 virt_to_bus
113#define ASC_U32_TO_VADDR bus_to_virt
114
115typedef unsigned char uchar;
116
117#ifndef TRUE
118#define TRUE (1)
119#endif
120#ifndef FALSE
121#define FALSE (0)
122#endif
123
124#define EOF (-1)
125#define ERR (-1)
126#define UW_ERR (uint)(0xFFFF)
127#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
1da177e4
LT
128
129#define ASC_DVCLIB_CALL_DONE (1)
130#define ASC_DVCLIB_CALL_FAILED (0)
131#define ASC_DVCLIB_CALL_ERROR (-1)
132
2672ea86
DJ
133#define PCI_VENDOR_ID_ASP 0x10cd
134#define PCI_DEVICE_ID_ASP_1200A 0x1100
135#define PCI_DEVICE_ID_ASP_ABP940 0x1200
136#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
137#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
138#define PCI_DEVICE_ID_38C0800_REV1 0x2500
139#define PCI_DEVICE_ID_38C1600_REV1 0x2700
140
1da177e4
LT
141/*
142 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
143 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
144 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
145 * SRB structure.
146 */
147#define CC_VERY_LONG_SG_LIST 0
148#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
149
27c868c2 150#define PortAddr unsigned short /* port address size */
1da177e4
LT
151#define inp(port) inb(port)
152#define outp(port, byte) outb((byte), (port))
153
154#define inpw(port) inw(port)
155#define outpw(port, word) outw((word), (port))
156
157#define ASC_MAX_SG_QUEUE 7
158#define ASC_MAX_SG_LIST 255
159
160#define ASC_CS_TYPE unsigned short
161
162#define ASC_IS_ISA (0x0001)
163#define ASC_IS_ISAPNP (0x0081)
164#define ASC_IS_EISA (0x0002)
165#define ASC_IS_PCI (0x0004)
166#define ASC_IS_PCI_ULTRA (0x0104)
167#define ASC_IS_PCMCIA (0x0008)
168#define ASC_IS_MCA (0x0020)
169#define ASC_IS_VL (0x0040)
170#define ASC_ISA_PNP_PORT_ADDR (0x279)
171#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
172#define ASC_IS_WIDESCSI_16 (0x0100)
173#define ASC_IS_WIDESCSI_32 (0x0200)
174#define ASC_IS_BIG_ENDIAN (0x8000)
175#define ASC_CHIP_MIN_VER_VL (0x01)
176#define ASC_CHIP_MAX_VER_VL (0x07)
177#define ASC_CHIP_MIN_VER_PCI (0x09)
178#define ASC_CHIP_MAX_VER_PCI (0x0F)
179#define ASC_CHIP_VER_PCI_BIT (0x08)
180#define ASC_CHIP_MIN_VER_ISA (0x11)
181#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
182#define ASC_CHIP_MAX_VER_ISA (0x27)
183#define ASC_CHIP_VER_ISA_BIT (0x30)
184#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
185#define ASC_CHIP_VER_ASYN_BUG (0x21)
186#define ASC_CHIP_VER_PCI 0x08
187#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
188#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
189#define ASC_CHIP_MIN_VER_EISA (0x41)
190#define ASC_CHIP_MAX_VER_EISA (0x47)
191#define ASC_CHIP_VER_EISA_BIT (0x40)
192#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
193#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
194#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
195#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
196#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
197#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
198#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
199#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
200#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
201#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
202#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
203
204#define ASC_SCSI_ID_BITS 3
205#define ASC_SCSI_TIX_TYPE uchar
206#define ASC_ALL_DEVICE_BIT_SET 0xFF
207#define ASC_SCSI_BIT_ID_TYPE uchar
208#define ASC_MAX_TID 7
209#define ASC_MAX_LUN 7
210#define ASC_SCSI_WIDTH_BIT_SET 0xFF
211#define ASC_MAX_SENSE_LEN 32
212#define ASC_MIN_SENSE_LEN 14
1da177e4
LT
213#define ASC_SCSI_RESET_HOLD_TIME_US 60
214
f05ec594
MW
215/*
216 * Narrow boards only support 12-byte commands, while wide boards
217 * extend to 16-byte commands.
218 */
219#define ASC_MAX_CDB_LEN 12
220#define ADV_MAX_CDB_LEN 16
221
1da177e4
LT
222/*
223 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
224 * and CmdDt (Command Support Data) field bit definitions.
225 */
226#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
227#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
228#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
229#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
230
231#define ASC_SCSIDIR_NOCHK 0x00
232#define ASC_SCSIDIR_T2H 0x08
233#define ASC_SCSIDIR_H2T 0x10
234#define ASC_SCSIDIR_NODATA 0x18
235#define SCSI_ASC_NOMEDIA 0x3A
236#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
237#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
238#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
239#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1da177e4 240#define MS_SDTR_LEN 0x03
1da177e4 241#define MS_WDTR_LEN 0x02
1da177e4
LT
242
243#define ASC_SG_LIST_PER_Q 7
244#define QS_FREE 0x00
245#define QS_READY 0x01
246#define QS_DISC1 0x02
247#define QS_DISC2 0x04
248#define QS_BUSY 0x08
249#define QS_ABORTED 0x40
250#define QS_DONE 0x80
251#define QC_NO_CALLBACK 0x01
252#define QC_SG_SWAP_QUEUE 0x02
253#define QC_SG_HEAD 0x04
254#define QC_DATA_IN 0x08
255#define QC_DATA_OUT 0x10
256#define QC_URGENT 0x20
257#define QC_MSG_OUT 0x40
258#define QC_REQ_SENSE 0x80
259#define QCSG_SG_XFER_LIST 0x02
260#define QCSG_SG_XFER_MORE 0x04
261#define QCSG_SG_XFER_END 0x08
262#define QD_IN_PROGRESS 0x00
263#define QD_NO_ERROR 0x01
264#define QD_ABORTED_BY_HOST 0x02
265#define QD_WITH_ERROR 0x04
266#define QD_INVALID_REQUEST 0x80
267#define QD_INVALID_HOST_NUM 0x81
268#define QD_INVALID_DEVICE 0x82
269#define QD_ERR_INTERNAL 0xFF
270#define QHSTA_NO_ERROR 0x00
271#define QHSTA_M_SEL_TIMEOUT 0x11
272#define QHSTA_M_DATA_OVER_RUN 0x12
273#define QHSTA_M_DATA_UNDER_RUN 0x12
274#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
275#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
276#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
277#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
278#define QHSTA_D_HOST_ABORT_FAILED 0x23
279#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
280#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
281#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
282#define QHSTA_M_WTM_TIMEOUT 0x41
283#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
284#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
285#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
286#define QHSTA_M_TARGET_STATUS_BUSY 0x45
287#define QHSTA_M_BAD_TAG_CODE 0x46
288#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
289#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
290#define QHSTA_D_LRAM_CMP_ERROR 0x81
291#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
292#define ASC_FLAG_SCSIQ_REQ 0x01
293#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
294#define ASC_FLAG_BIOS_ASYNC_IO 0x04
295#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
296#define ASC_FLAG_WIN16 0x10
297#define ASC_FLAG_WIN32 0x20
298#define ASC_FLAG_ISA_OVER_16MB 0x40
299#define ASC_FLAG_DOS_VM_CALLBACK 0x80
300#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
301#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
302#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
303#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
304#define ASC_SCSIQ_CPY_BEG 4
305#define ASC_SCSIQ_SGHD_CPY_BEG 2
306#define ASC_SCSIQ_B_FWD 0
307#define ASC_SCSIQ_B_BWD 1
308#define ASC_SCSIQ_B_STATUS 2
309#define ASC_SCSIQ_B_QNO 3
310#define ASC_SCSIQ_B_CNTL 4
311#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
312#define ASC_SCSIQ_D_DATA_ADDR 8
313#define ASC_SCSIQ_D_DATA_CNT 12
314#define ASC_SCSIQ_B_SENSE_LEN 20
315#define ASC_SCSIQ_DONE_INFO_BEG 22
316#define ASC_SCSIQ_D_SRBPTR 22
317#define ASC_SCSIQ_B_TARGET_IX 26
318#define ASC_SCSIQ_B_CDB_LEN 28
319#define ASC_SCSIQ_B_TAG_CODE 29
320#define ASC_SCSIQ_W_VM_ID 30
321#define ASC_SCSIQ_DONE_STATUS 32
322#define ASC_SCSIQ_HOST_STATUS 33
323#define ASC_SCSIQ_SCSI_STATUS 34
324#define ASC_SCSIQ_CDB_BEG 36
325#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
326#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
327#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
328#define ASC_SCSIQ_B_SG_WK_QP 49
329#define ASC_SCSIQ_B_SG_WK_IX 50
330#define ASC_SCSIQ_W_ALT_DC1 52
331#define ASC_SCSIQ_B_LIST_CNT 6
332#define ASC_SCSIQ_B_CUR_LIST_CNT 7
333#define ASC_SGQ_B_SG_CNTL 4
334#define ASC_SGQ_B_SG_HEAD_QP 5
335#define ASC_SGQ_B_SG_LIST_CNT 6
336#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
337#define ASC_SGQ_LIST_BEG 8
338#define ASC_DEF_SCSI1_QNG 4
339#define ASC_MAX_SCSI1_QNG 4
340#define ASC_DEF_SCSI2_QNG 16
341#define ASC_MAX_SCSI2_QNG 32
342#define ASC_TAG_CODE_MASK 0x23
343#define ASC_STOP_REQ_RISC_STOP 0x01
344#define ASC_STOP_ACK_RISC_STOP 0x03
345#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
346#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
347#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
348#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
349#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
350#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
351#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
352#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
353#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
354#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
355
356typedef struct asc_scsiq_1 {
27c868c2
MW
357 uchar status;
358 uchar q_no;
359 uchar cntl;
360 uchar sg_queue_cnt;
361 uchar target_id;
362 uchar target_lun;
363 ASC_PADDR data_addr;
364 ASC_DCNT data_cnt;
365 ASC_PADDR sense_addr;
366 uchar sense_len;
367 uchar extra_bytes;
1da177e4
LT
368} ASC_SCSIQ_1;
369
370typedef struct asc_scsiq_2 {
27c868c2
MW
371 ASC_VADDR srb_ptr;
372 uchar target_ix;
373 uchar flag;
374 uchar cdb_len;
375 uchar tag_code;
376 ushort vm_id;
1da177e4
LT
377} ASC_SCSIQ_2;
378
379typedef struct asc_scsiq_3 {
27c868c2
MW
380 uchar done_stat;
381 uchar host_stat;
382 uchar scsi_stat;
383 uchar scsi_msg;
1da177e4
LT
384} ASC_SCSIQ_3;
385
386typedef struct asc_scsiq_4 {
27c868c2
MW
387 uchar cdb[ASC_MAX_CDB_LEN];
388 uchar y_first_sg_list_qp;
389 uchar y_working_sg_qp;
390 uchar y_working_sg_ix;
391 uchar y_res;
392 ushort x_req_count;
393 ushort x_reconnect_rtn;
394 ASC_PADDR x_saved_data_addr;
395 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
396} ASC_SCSIQ_4;
397
398typedef struct asc_q_done_info {
27c868c2
MW
399 ASC_SCSIQ_2 d2;
400 ASC_SCSIQ_3 d3;
401 uchar q_status;
402 uchar q_no;
403 uchar cntl;
404 uchar sense_len;
405 uchar extra_bytes;
406 uchar res;
407 ASC_DCNT remain_bytes;
1da177e4
LT
408} ASC_QDONE_INFO;
409
410typedef struct asc_sg_list {
27c868c2
MW
411 ASC_PADDR addr;
412 ASC_DCNT bytes;
1da177e4
LT
413} ASC_SG_LIST;
414
415typedef struct asc_sg_head {
27c868c2
MW
416 ushort entry_cnt;
417 ushort queue_cnt;
418 ushort entry_to_copy;
419 ushort res;
420 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
421} ASC_SG_HEAD;
422
423#define ASC_MIN_SG_LIST 2
424
425typedef struct asc_min_sg_head {
27c868c2
MW
426 ushort entry_cnt;
427 ushort queue_cnt;
428 ushort entry_to_copy;
429 ushort res;
430 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1da177e4
LT
431} ASC_MIN_SG_HEAD;
432
433#define QCX_SORT (0x0001)
434#define QCX_COALEASE (0x0002)
435
436typedef struct asc_scsi_q {
27c868c2
MW
437 ASC_SCSIQ_1 q1;
438 ASC_SCSIQ_2 q2;
439 uchar *cdbptr;
440 ASC_SG_HEAD *sg_head;
441 ushort remain_sg_entry_cnt;
442 ushort next_sg_index;
1da177e4
LT
443} ASC_SCSI_Q;
444
445typedef struct asc_scsi_req_q {
27c868c2
MW
446 ASC_SCSIQ_1 r1;
447 ASC_SCSIQ_2 r2;
448 uchar *cdbptr;
449 ASC_SG_HEAD *sg_head;
450 uchar *sense_ptr;
451 ASC_SCSIQ_3 r3;
452 uchar cdb[ASC_MAX_CDB_LEN];
453 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
454} ASC_SCSI_REQ_Q;
455
456typedef struct asc_scsi_bios_req_q {
27c868c2
MW
457 ASC_SCSIQ_1 r1;
458 ASC_SCSIQ_2 r2;
459 uchar *cdbptr;
460 ASC_SG_HEAD *sg_head;
461 uchar *sense_ptr;
462 ASC_SCSIQ_3 r3;
463 uchar cdb[ASC_MAX_CDB_LEN];
464 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
465} ASC_SCSI_BIOS_REQ_Q;
466
467typedef struct asc_risc_q {
27c868c2
MW
468 uchar fwd;
469 uchar bwd;
470 ASC_SCSIQ_1 i1;
471 ASC_SCSIQ_2 i2;
472 ASC_SCSIQ_3 i3;
473 ASC_SCSIQ_4 i4;
1da177e4
LT
474} ASC_RISC_Q;
475
476typedef struct asc_sg_list_q {
27c868c2
MW
477 uchar seq_no;
478 uchar q_no;
479 uchar cntl;
480 uchar sg_head_qp;
481 uchar sg_list_cnt;
482 uchar sg_cur_list_cnt;
1da177e4
LT
483} ASC_SG_LIST_Q;
484
485typedef struct asc_risc_sg_list_q {
27c868c2
MW
486 uchar fwd;
487 uchar bwd;
488 ASC_SG_LIST_Q sg;
489 ASC_SG_LIST sg_list[7];
1da177e4
LT
490} ASC_RISC_SG_LIST_Q;
491
492#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
493#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
494#define ASCQ_ERR_NO_ERROR 0
495#define ASCQ_ERR_IO_NOT_FOUND 1
496#define ASCQ_ERR_LOCAL_MEM 2
497#define ASCQ_ERR_CHKSUM 3
498#define ASCQ_ERR_START_CHIP 4
499#define ASCQ_ERR_INT_TARGET_ID 5
500#define ASCQ_ERR_INT_LOCAL_MEM 6
501#define ASCQ_ERR_HALT_RISC 7
502#define ASCQ_ERR_GET_ASPI_ENTRY 8
503#define ASCQ_ERR_CLOSE_ASPI 9
504#define ASCQ_ERR_HOST_INQUIRY 0x0A
505#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
506#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
507#define ASCQ_ERR_Q_STATUS 0x0D
508#define ASCQ_ERR_WR_SCSIQ 0x0E
509#define ASCQ_ERR_PC_ADDR 0x0F
510#define ASCQ_ERR_SYN_OFFSET 0x10
511#define ASCQ_ERR_SYN_XFER_TIME 0x11
512#define ASCQ_ERR_LOCK_DMA 0x12
513#define ASCQ_ERR_UNLOCK_DMA 0x13
514#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
515#define ASCQ_ERR_MICRO_CODE_HALT 0x15
516#define ASCQ_ERR_SET_LRAM_ADDR 0x16
517#define ASCQ_ERR_CUR_QNG 0x17
518#define ASCQ_ERR_SG_Q_LINKS 0x18
519#define ASCQ_ERR_SCSIQ_PTR 0x19
520#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
521#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
522#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1da177e4
LT
523
524/*
525 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
526 */
527#define ASC_WARN_NO_ERROR 0x0000
528#define ASC_WARN_IO_PORT_ROTATE 0x0001
529#define ASC_WARN_EEPROM_CHKSUM 0x0002
530#define ASC_WARN_IRQ_MODIFIED 0x0004
531#define ASC_WARN_AUTO_CONFIG 0x0008
532#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
533#define ASC_WARN_EEPROM_RECOVER 0x0020
534#define ASC_WARN_CFG_MSW_RECOVER 0x0040
535#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
536
537/*
538 * Error code values are set in ASC_DVC_VAR 'err_code'.
539 */
540#define ASC_IERR_WRITE_EEPROM 0x0001
541#define ASC_IERR_MCODE_CHKSUM 0x0002
542#define ASC_IERR_SET_PC_ADDR 0x0004
543#define ASC_IERR_START_STOP_CHIP 0x0008
544#define ASC_IERR_IRQ_NO 0x0010
545#define ASC_IERR_SET_IRQ_NO 0x0020
546#define ASC_IERR_CHIP_VERSION 0x0040
547#define ASC_IERR_SET_SCSI_ID 0x0080
548#define ASC_IERR_GET_PHY_ADDR 0x0100
549#define ASC_IERR_BAD_SIGNATURE 0x0200
550#define ASC_IERR_NO_BUS_TYPE 0x0400
551#define ASC_IERR_SCAM 0x0800
552#define ASC_IERR_SET_SDTR 0x1000
553#define ASC_IERR_RW_LRAM 0x8000
554
555#define ASC_DEF_IRQ_NO 10
556#define ASC_MAX_IRQ_NO 15
557#define ASC_MIN_IRQ_NO 10
558#define ASC_MIN_REMAIN_Q (0x02)
559#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
560#define ASC_MIN_TAG_Q_PER_DVC (0x04)
561#define ASC_DEF_TAG_Q_PER_DVC (0x04)
562#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
563#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
564#define ASC_MAX_TOTAL_QNG 240
565#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
566#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
567#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
568#define ASC_MAX_INRAM_TAG_QNG 16
569#define ASC_IOADR_TABLE_MAX_IX 11
570#define ASC_IOADR_GAP 0x10
1da177e4
LT
571#define ASC_LIB_SCSIQ_WK_SP 256
572#define ASC_MAX_SYN_XFER_NO 16
573#define ASC_SYN_MAX_OFFSET 0x0F
574#define ASC_DEF_SDTR_OFFSET 0x0F
575#define ASC_DEF_SDTR_INDEX 0x00
576#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
577#define SYN_XFER_NS_0 25
578#define SYN_XFER_NS_1 30
579#define SYN_XFER_NS_2 35
580#define SYN_XFER_NS_3 40
581#define SYN_XFER_NS_4 50
582#define SYN_XFER_NS_5 60
583#define SYN_XFER_NS_6 70
584#define SYN_XFER_NS_7 85
585#define SYN_ULTRA_XFER_NS_0 12
586#define SYN_ULTRA_XFER_NS_1 19
587#define SYN_ULTRA_XFER_NS_2 25
588#define SYN_ULTRA_XFER_NS_3 32
589#define SYN_ULTRA_XFER_NS_4 38
590#define SYN_ULTRA_XFER_NS_5 44
591#define SYN_ULTRA_XFER_NS_6 50
592#define SYN_ULTRA_XFER_NS_7 57
593#define SYN_ULTRA_XFER_NS_8 63
594#define SYN_ULTRA_XFER_NS_9 69
595#define SYN_ULTRA_XFER_NS_10 75
596#define SYN_ULTRA_XFER_NS_11 82
597#define SYN_ULTRA_XFER_NS_12 88
598#define SYN_ULTRA_XFER_NS_13 94
599#define SYN_ULTRA_XFER_NS_14 100
600#define SYN_ULTRA_XFER_NS_15 107
601
602typedef struct ext_msg {
27c868c2
MW
603 uchar msg_type;
604 uchar msg_len;
605 uchar msg_req;
606 union {
607 struct {
608 uchar sdtr_xfer_period;
609 uchar sdtr_req_ack_offset;
610 } sdtr;
611 struct {
612 uchar wdtr_width;
613 } wdtr;
614 struct {
615 uchar mdp_b3;
616 uchar mdp_b2;
617 uchar mdp_b1;
618 uchar mdp_b0;
619 } mdp;
620 } u_ext_msg;
621 uchar res;
1da177e4
LT
622} EXT_MSG;
623
624#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
625#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
626#define wdtr_width u_ext_msg.wdtr.wdtr_width
627#define mdp_b3 u_ext_msg.mdp_b3
628#define mdp_b2 u_ext_msg.mdp_b2
629#define mdp_b1 u_ext_msg.mdp_b1
630#define mdp_b0 u_ext_msg.mdp_b0
631
632typedef struct asc_dvc_cfg {
27c868c2
MW
633 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
634 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
635 ASC_SCSI_BIT_ID_TYPE disc_enable;
636 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
637 uchar chip_scsi_id;
638 uchar isa_dma_speed;
639 uchar isa_dma_channel;
640 uchar chip_version;
641 ushort lib_serial_no;
642 ushort lib_version;
643 ushort mcode_date;
644 ushort mcode_version;
645 uchar max_tag_qng[ASC_MAX_TID + 1];
646 uchar *overrun_buf;
647 uchar sdtr_period_offset[ASC_MAX_TID + 1];
27c868c2 648 uchar adapter_info[6];
1da177e4
LT
649} ASC_DVC_CFG;
650
651#define ASC_DEF_DVC_CNTL 0xFFFF
652#define ASC_DEF_CHIP_SCSI_ID 7
653#define ASC_DEF_ISA_DMA_SPEED 4
654#define ASC_INIT_STATE_NULL 0x0000
655#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
656#define ASC_INIT_STATE_END_GET_CFG 0x0002
657#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
658#define ASC_INIT_STATE_END_SET_CFG 0x0008
659#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
660#define ASC_INIT_STATE_END_LOAD_MC 0x0020
661#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
662#define ASC_INIT_STATE_END_INQUIRY 0x0080
663#define ASC_INIT_RESET_SCSI_DONE 0x0100
664#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
665#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
666#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
667#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
668#define ASC_MIN_TAGGED_CMD 7
669#define ASC_MAX_SCSI_RESET_WAIT 30
670
27c868c2 671struct asc_dvc_var; /* Forward Declaration. */
1da177e4 672
1da177e4 673typedef struct asc_dvc_var {
27c868c2
MW
674 PortAddr iop_base;
675 ushort err_code;
676 ushort dvc_cntl;
677 ushort bug_fix_cntl;
678 ushort bus_type;
27c868c2
MW
679 ASC_SCSI_BIT_ID_TYPE init_sdtr;
680 ASC_SCSI_BIT_ID_TYPE sdtr_done;
681 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
682 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
683 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
684 ASC_SCSI_BIT_ID_TYPE start_motor;
685 uchar scsi_reset_wait;
686 uchar chip_no;
687 char is_in_int;
688 uchar max_total_qng;
689 uchar cur_total_qng;
690 uchar in_critical_cnt;
691 uchar irq_no;
692 uchar last_q_shortage;
693 ushort init_state;
694 uchar cur_dvc_qng[ASC_MAX_TID + 1];
695 uchar max_dvc_qng[ASC_MAX_TID + 1];
696 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
697 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
698 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
699 ASC_DVC_CFG *cfg;
700 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
701 char redo_scam;
702 ushort res2;
703 uchar dos_int13_table[ASC_MAX_TID + 1];
704 ASC_DCNT max_dma_count;
705 ASC_SCSI_BIT_ID_TYPE no_scam;
706 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
707 uchar max_sdtr_index;
708 uchar host_init_sdtr_index;
709 struct asc_board *drv_ptr;
710 ASC_DCNT uc_break;
1da177e4
LT
711} ASC_DVC_VAR;
712
713typedef struct asc_dvc_inq_info {
27c868c2 714 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
715} ASC_DVC_INQ_INFO;
716
717typedef struct asc_cap_info {
27c868c2
MW
718 ASC_DCNT lba;
719 ASC_DCNT blk_size;
1da177e4
LT
720} ASC_CAP_INFO;
721
722typedef struct asc_cap_info_array {
27c868c2 723 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
724} ASC_CAP_INFO_ARRAY;
725
726#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
727#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
728#define ASC_CNTL_INITIATOR (ushort)0x0001
729#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
730#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
731#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
732#define ASC_CNTL_NO_SCAM (ushort)0x0010
733#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
734#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
735#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
736#define ASC_CNTL_RESET_SCSI (ushort)0x0200
737#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
738#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
739#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
740#define ASC_CNTL_BURST_MODE (ushort)0x2000
741#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
742#define ASC_EEP_DVC_CFG_BEG_VL 2
743#define ASC_EEP_MAX_DVC_ADDR_VL 15
744#define ASC_EEP_DVC_CFG_BEG 32
745#define ASC_EEP_MAX_DVC_ADDR 45
746#define ASC_EEP_DEFINED_WORDS 10
747#define ASC_EEP_MAX_ADDR 63
748#define ASC_EEP_RES_WORDS 0
749#define ASC_EEP_MAX_RETRY 20
750#define ASC_MAX_INIT_BUSY_RETRY 8
751#define ASC_EEP_ISA_PNP_WSIZE 16
752
753/*
754 * These macros keep the chip SCSI id and ISA DMA speed
755 * bitfields in board order. C bitfields aren't portable
756 * between big and little-endian platforms so they are
757 * not used.
758 */
759
760#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
761#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
762#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
763 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
764#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
765 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
766
767typedef struct asceep_config {
27c868c2
MW
768 ushort cfg_lsw;
769 ushort cfg_msw;
770 uchar init_sdtr;
771 uchar disc_enable;
772 uchar use_cmd_qng;
773 uchar start_motor;
774 uchar max_total_qng;
775 uchar max_tag_qng;
776 uchar bios_scan;
777 uchar power_up_wait;
778 uchar no_scam;
779 uchar id_speed; /* low order 4 bits is chip scsi id */
780 /* high order 4 bits is isa dma speed */
781 uchar dos_int13_table[ASC_MAX_TID + 1];
782 uchar adapter_info[6];
783 ushort cntl;
784 ushort chksum;
1da177e4
LT
785} ASCEEP_CONFIG;
786
787#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
788#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
789#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
790
791#define ASC_EEP_CMD_READ 0x80
792#define ASC_EEP_CMD_WRITE 0x40
793#define ASC_EEP_CMD_WRITE_ABLE 0x30
794#define ASC_EEP_CMD_WRITE_DISABLE 0x00
795#define ASC_OVERRUN_BSIZE 0x00000048UL
796#define ASC_CTRL_BREAK_ONCE 0x0001
797#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
798#define ASCV_MSGOUT_BEG 0x0000
799#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
800#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
801#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
802#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
803#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
804#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
805#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
806#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
807#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
808#define ASCV_BREAK_ADDR (ushort)0x0028
809#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
810#define ASCV_BREAK_CONTROL (ushort)0x002C
811#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
812
813#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
814#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
815#define ASCV_MCODE_SIZE_W (ushort)0x0034
816#define ASCV_STOP_CODE_B (ushort)0x0036
817#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
818#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
819#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
820#define ASCV_HALTCODE_W (ushort)0x0040
821#define ASCV_CHKSUM_W (ushort)0x0042
822#define ASCV_MC_DATE_W (ushort)0x0044
823#define ASCV_MC_VER_W (ushort)0x0046
824#define ASCV_NEXTRDY_B (ushort)0x0048
825#define ASCV_DONENEXT_B (ushort)0x0049
826#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
827#define ASCV_SCSIBUSY_B (ushort)0x004B
828#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
829#define ASCV_CURCDB_B (ushort)0x004D
830#define ASCV_RCLUN_B (ushort)0x004E
831#define ASCV_BUSY_QHEAD_B (ushort)0x004F
832#define ASCV_DISC1_QHEAD_B (ushort)0x0050
833#define ASCV_DISC_ENABLE_B (ushort)0x0052
834#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
835#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
836#define ASCV_MCODE_CNTL_B (ushort)0x0056
837#define ASCV_NULL_TARGET_B (ushort)0x0057
838#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
839#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
840#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
841#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
842#define ASCV_HOST_FLAG_B (ushort)0x005D
843#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
844#define ASCV_VER_SERIAL_B (ushort)0x0065
845#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
846#define ASCV_WTM_FLAG_B (ushort)0x0068
847#define ASCV_RISC_FLAG_B (ushort)0x006A
848#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
849#define ASC_HOST_FLAG_IN_ISR 0x01
850#define ASC_HOST_FLAG_ACK_INT 0x02
851#define ASC_RISC_FLAG_GEN_INT 0x01
852#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
853#define IOP_CTRL (0x0F)
854#define IOP_STATUS (0x0E)
855#define IOP_INT_ACK IOP_STATUS
856#define IOP_REG_IFC (0x0D)
857#define IOP_SYN_OFFSET (0x0B)
858#define IOP_EXTRA_CONTROL (0x0D)
859#define IOP_REG_PC (0x0C)
860#define IOP_RAM_ADDR (0x0A)
861#define IOP_RAM_DATA (0x08)
862#define IOP_EEP_DATA (0x06)
863#define IOP_EEP_CMD (0x07)
864#define IOP_VERSION (0x03)
865#define IOP_CONFIG_HIGH (0x04)
866#define IOP_CONFIG_LOW (0x02)
867#define IOP_SIG_BYTE (0x01)
868#define IOP_SIG_WORD (0x00)
869#define IOP_REG_DC1 (0x0E)
870#define IOP_REG_DC0 (0x0C)
871#define IOP_REG_SB (0x0B)
872#define IOP_REG_DA1 (0x0A)
873#define IOP_REG_DA0 (0x08)
874#define IOP_REG_SC (0x09)
875#define IOP_DMA_SPEED (0x07)
876#define IOP_REG_FLAG (0x07)
877#define IOP_FIFO_H (0x06)
878#define IOP_FIFO_L (0x04)
879#define IOP_REG_ID (0x05)
880#define IOP_REG_QP (0x03)
881#define IOP_REG_IH (0x02)
882#define IOP_REG_IX (0x01)
883#define IOP_REG_AX (0x00)
884#define IFC_REG_LOCK (0x00)
885#define IFC_REG_UNLOCK (0x09)
886#define IFC_WR_EN_FILTER (0x10)
887#define IFC_RD_NO_EEPROM (0x10)
888#define IFC_SLEW_RATE (0x20)
889#define IFC_ACT_NEG (0x40)
890#define IFC_INP_FILTER (0x80)
891#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
892#define SC_SEL (uchar)(0x80)
893#define SC_BSY (uchar)(0x40)
894#define SC_ACK (uchar)(0x20)
895#define SC_REQ (uchar)(0x10)
896#define SC_ATN (uchar)(0x08)
897#define SC_IO (uchar)(0x04)
898#define SC_CD (uchar)(0x02)
899#define SC_MSG (uchar)(0x01)
900#define SEC_SCSI_CTL (uchar)(0x80)
901#define SEC_ACTIVE_NEGATE (uchar)(0x40)
902#define SEC_SLEW_RATE (uchar)(0x20)
903#define SEC_ENABLE_FILTER (uchar)(0x10)
904#define ASC_HALT_EXTMSG_IN (ushort)0x8000
905#define ASC_HALT_CHK_CONDITION (ushort)0x8100
906#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
907#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
908#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
909#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
910#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
911#define ASC_MAX_QNO 0xF8
912#define ASC_DATA_SEC_BEG (ushort)0x0080
913#define ASC_DATA_SEC_END (ushort)0x0080
914#define ASC_CODE_SEC_BEG (ushort)0x0080
915#define ASC_CODE_SEC_END (ushort)0x0080
916#define ASC_QADR_BEG (0x4000)
917#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
918#define ASC_QADR_END (ushort)0x7FFF
919#define ASC_QLAST_ADR (ushort)0x7FC0
920#define ASC_QBLK_SIZE 0x40
921#define ASC_BIOS_DATA_QBEG 0xF8
922#define ASC_MIN_ACTIVE_QNO 0x01
923#define ASC_QLINK_END 0xFF
924#define ASC_EEPROM_WORDS 0x10
925#define ASC_MAX_MGS_LEN 0x10
926#define ASC_BIOS_ADDR_DEF 0xDC00
927#define ASC_BIOS_SIZE 0x3800
928#define ASC_BIOS_RAM_OFF 0x3800
929#define ASC_BIOS_RAM_SIZE 0x800
930#define ASC_BIOS_MIN_ADDR 0xC000
931#define ASC_BIOS_MAX_ADDR 0xEC00
932#define ASC_BIOS_BANK_SIZE 0x0400
933#define ASC_MCODE_START_ADDR 0x0080
934#define ASC_CFG0_HOST_INT_ON 0x0020
935#define ASC_CFG0_BIOS_ON 0x0040
936#define ASC_CFG0_VERA_BURST_ON 0x0080
937#define ASC_CFG0_SCSI_PARITY_ON 0x0800
938#define ASC_CFG1_SCSI_TARGET_ON 0x0080
939#define ASC_CFG1_LRAM_8BITS_ON 0x0800
940#define ASC_CFG_MSW_CLR_MASK 0x3080
941#define CSW_TEST1 (ASC_CS_TYPE)0x8000
942#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
943#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
944#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
945#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
946#define CSW_TEST2 (ASC_CS_TYPE)0x0400
947#define CSW_TEST3 (ASC_CS_TYPE)0x0200
948#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
949#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
950#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
951#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
952#define CSW_HALTED (ASC_CS_TYPE)0x0010
953#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
954#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
955#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
956#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
957#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
958#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
959#define CIW_TEST1 (ASC_CS_TYPE)0x0200
960#define CIW_TEST2 (ASC_CS_TYPE)0x0400
961#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
962#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
963#define CC_CHIP_RESET (uchar)0x80
964#define CC_SCSI_RESET (uchar)0x40
965#define CC_HALT (uchar)0x20
966#define CC_SINGLE_STEP (uchar)0x10
967#define CC_DMA_ABLE (uchar)0x08
968#define CC_TEST (uchar)0x04
969#define CC_BANK_ONE (uchar)0x02
970#define CC_DIAG (uchar)0x01
971#define ASC_1000_ID0W 0x04C1
972#define ASC_1000_ID0W_FIX 0x00C1
973#define ASC_1000_ID1B 0x25
1da177e4
LT
974#define ASC_EISA_REV_IOP_MASK (0x0C83)
975#define ASC_EISA_PID_IOP_MASK (0x0C80)
976#define ASC_EISA_CFG_IOP_MASK (0x0C86)
977#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1da177e4
LT
978#define INS_HALTINT (ushort)0x6281
979#define INS_HALT (ushort)0x6280
980#define INS_SINT (ushort)0x6200
981#define INS_RFLAG_WTM (ushort)0x7380
982#define ASC_MC_SAVE_CODE_WSIZE 0x500
983#define ASC_MC_SAVE_DATA_WSIZE 0x40
984
985typedef struct asc_mc_saved {
27c868c2
MW
986 ushort data[ASC_MC_SAVE_DATA_WSIZE];
987 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
988} ASC_MC_SAVED;
989
990#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
991#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
992#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
993#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
994#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
995#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
996#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
997#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
998#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
999#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1000#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1001#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1002#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1003#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1004#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1005#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1006#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1007#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1008#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1009#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1010#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1011#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1012#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1013#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1014#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1015#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1016#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1017#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1018#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1019#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1020#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1021#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1022#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1023#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1024#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1025#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1026#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1027#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1028#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1029#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1030#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1031#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1032#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1033#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1034#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1035#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1036#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1037#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1038#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1039#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1040#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1041#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1042#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1043#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1044#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1045#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1046#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1047#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1048#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1049#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1050#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1051#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1052#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1053#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1054#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1055#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1056#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1057#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1058
27c868c2
MW
1059static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1060static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1061static void AscWaitEEPRead(void);
1062static void AscWaitEEPWrite(void);
1063static ushort AscReadEEPWord(PortAddr, uchar);
1064static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1065static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1066static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1067static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1068static int AscStartChip(PortAddr);
1069static int AscStopChip(PortAddr);
1070static void AscSetChipIH(PortAddr, ushort);
1071static int AscIsChipHalted(PortAddr);
1072static void AscAckInterrupt(PortAddr);
1073static void AscDisableInterrupt(PortAddr);
1074static void AscEnableInterrupt(PortAddr);
1075static void AscSetBank(PortAddr, uchar);
1076static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 1077#ifdef CONFIG_ISA
27c868c2 1078static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 1079#endif /* CONFIG_ISA */
27c868c2
MW
1080static uchar AscReadLramByte(PortAddr, ushort);
1081static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 1082#if CC_VERY_LONG_SG_LIST
27c868c2 1083static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 1084#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
1085static void AscWriteLramWord(PortAddr, ushort, ushort);
1086static void AscWriteLramByte(PortAddr, ushort, uchar);
1087static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1088static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1089static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1090static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1091static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1092static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1093static ushort AscInitFromEEP(ASC_DVC_VAR *);
27c868c2
MW
1094static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1095static int AscTestExternalLram(ASC_DVC_VAR *);
1096static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1097static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1098static void AscSetChipSDTR(PortAddr, uchar, uchar);
1099static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1100static uchar AscAllocFreeQueue(PortAddr, uchar);
1101static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1102static int AscHostReqRiscHalt(PortAddr);
1103static int AscStopQueueExe(PortAddr);
1104static int AscSendScsiQueue(ASC_DVC_VAR *,
1105 ASC_SCSI_Q *scsiq, uchar n_q_required);
1106static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1107static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1108static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1109static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1110static ushort AscInitLram(ASC_DVC_VAR *);
1111static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1112static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1113static int AscIsrChipHalted(ASC_DVC_VAR *);
1114static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1115 ASC_QDONE_INFO *, ASC_DCNT);
1116static int AscIsrQDone(ASC_DVC_VAR *);
1da177e4 1117#ifdef CONFIG_ISA
27c868c2 1118static ushort AscGetEisaChipCfg(PortAddr);
1da177e4 1119#endif /* CONFIG_ISA */
27c868c2 1120static uchar AscGetChipScsiCtrl(PortAddr);
27c868c2 1121static uchar AscGetChipVersion(PortAddr, ushort);
27c868c2 1122static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
27c868c2 1123static void AscToggleIRQAct(PortAddr);
27c868c2
MW
1124static inline ulong DvcEnterCritical(void);
1125static inline void DvcLeaveCritical(ulong);
27c868c2
MW
1126static void DvcSleepMilliSecond(ASC_DCNT);
1127static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1128static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1129static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
27c868c2 1130static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
47d853cc 1131static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
27c868c2
MW
1132static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1133static int AscISR(ASC_DVC_VAR *);
1134static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1135static int AscSgListToQueue(int);
1da177e4 1136#ifdef CONFIG_ISA
27c868c2 1137static void AscEnableIsaDma(uchar);
1da177e4 1138#endif /* CONFIG_ISA */
27c868c2 1139static const char *advansys_info(struct Scsi_Host *shost);
1da177e4
LT
1140
1141/*
1142 * --- Adv Library Constants and Macros
1143 */
1144
1145#define ADV_LIB_VERSION_MAJOR 5
1146#define ADV_LIB_VERSION_MINOR 14
1147
1148/*
1149 * Define Adv Library required special types.
1150 */
1151
1152/*
1153 * Portable Data Types
1154 *
1155 * Any instance where a 32-bit long or pointer type is assumed
1156 * for precision or HW defined structures, the following define
1157 * types must be used. In Linux the char, short, and int types
1158 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1159 * and long types are 64 bits on Alpha and UltraSPARC.
1160 */
27c868c2
MW
1161#define ADV_PADDR __u32 /* Physical address data type. */
1162#define ADV_VADDR __u32 /* Virtual address data type. */
1163#define ADV_DCNT __u32 /* Unsigned Data count type. */
1164#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
1165
1166/*
1167 * These macros are used to convert a virtual address to a
1168 * 32-bit value. This currently can be used on Linux Alpha
1169 * which uses 64-bit virtual address but a 32-bit bus address.
1170 * This is likely to break in the future, but doing this now
1171 * will give us time to change the HW and FW to handle 64-bit
1172 * addresses.
1173 */
1174#define ADV_VADDR_TO_U32 virt_to_bus
1175#define ADV_U32_TO_VADDR bus_to_virt
1176
27c868c2 1177#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
1178
1179/*
1180 * Define Adv Library required memory access macros.
1181 */
1182#define ADV_MEM_READB(addr) readb(addr)
1183#define ADV_MEM_READW(addr) readw(addr)
1184#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1185#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1186#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1187
1188#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1189
1da177e4
LT
1190/*
1191 * Define total number of simultaneous maximum element scatter-gather
1192 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1193 * maximum number of outstanding commands per wide host adapter. Each
1194 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1195 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1196 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1197 * structures or 255 scatter-gather elements.
1198 *
1199 */
1200#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1201
1202/*
1203 * Define Adv Library required maximum number of scatter-gather
1204 * elements per request.
1205 */
1206#define ADV_MAX_SG_LIST 255
1207
1208/* Number of SG blocks needed. */
1209#define ADV_NUM_SG_BLOCK \
1210 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1211
1212/* Total contiguous memory needed for SG blocks. */
1213#define ADV_SG_TOTAL_MEM_SIZE \
1214 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1215
1216#define ADV_PAGE_SIZE PAGE_SIZE
1217
1218#define ADV_NUM_PAGE_CROSSING \
1219 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1220
1da177e4
LT
1221#define ADV_EEP_DVC_CFG_BEGIN (0x00)
1222#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 1223#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
1224#define ADV_EEP_MAX_WORD_ADDR (0x1E)
1225
1226#define ADV_EEP_DELAY_MS 100
1227
27c868c2
MW
1228#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1229#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
1230/*
1231 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1232 * For later ICs Bit 13 controls whether the CIS (Card Information
1233 * Service Section) is loaded from EEPROM.
1234 */
27c868c2
MW
1235#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1236#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
1237/*
1238 * ASC38C1600 Bit 11
1239 *
1240 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1241 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1242 * Function 0 will specify INT B.
1243 *
1244 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1245 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1246 * Function 1 will specify INT A.
1247 */
27c868c2
MW
1248#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1249
1250typedef struct adveep_3550_config {
1251 /* Word Offset, Description */
1252
1253 ushort cfg_lsw; /* 00 power up initialization */
1254 /* bit 13 set - Term Polarity Control */
1255 /* bit 14 set - BIOS Enable */
1256 /* bit 15 set - Big Endian Mode */
1257 ushort cfg_msw; /* 01 unused */
1258 ushort disc_enable; /* 02 disconnect enable */
1259 ushort wdtr_able; /* 03 Wide DTR able */
1260 ushort sdtr_able; /* 04 Synchronous DTR able */
1261 ushort start_motor; /* 05 send start up motor */
1262 ushort tagqng_able; /* 06 tag queuing able */
1263 ushort bios_scan; /* 07 BIOS device control */
1264 ushort scam_tolerant; /* 08 no scam */
1265
1266 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1267 uchar bios_boot_delay; /* power up wait */
1268
1269 uchar scsi_reset_delay; /* 10 reset delay */
1270 uchar bios_id_lun; /* first boot device scsi id & lun */
1271 /* high nibble is lun */
1272 /* low nibble is scsi id */
1273
1274 uchar termination; /* 11 0 - automatic */
1275 /* 1 - low off / high off */
1276 /* 2 - low off / high on */
1277 /* 3 - low on / high on */
1278 /* There is no low on / high off */
1279
1280 uchar reserved1; /* reserved byte (not used) */
1281
1282 ushort bios_ctrl; /* 12 BIOS control bits */
1283 /* bit 0 BIOS don't act as initiator. */
1284 /* bit 1 BIOS > 1 GB support */
1285 /* bit 2 BIOS > 2 Disk Support */
1286 /* bit 3 BIOS don't support removables */
1287 /* bit 4 BIOS support bootable CD */
1288 /* bit 5 BIOS scan enabled */
1289 /* bit 6 BIOS support multiple LUNs */
1290 /* bit 7 BIOS display of message */
1291 /* bit 8 SCAM disabled */
1292 /* bit 9 Reset SCSI bus during init. */
1293 /* bit 10 */
1294 /* bit 11 No verbose initialization. */
1295 /* bit 12 SCSI parity enabled */
1296 /* bit 13 */
1297 /* bit 14 */
1298 /* bit 15 */
1299 ushort ultra_able; /* 13 ULTRA speed able */
1300 ushort reserved2; /* 14 reserved */
1301 uchar max_host_qng; /* 15 maximum host queuing */
1302 uchar max_dvc_qng; /* maximum per device queuing */
1303 ushort dvc_cntl; /* 16 control bit for driver */
1304 ushort bug_fix; /* 17 control bit for bug fix */
1305 ushort serial_number_word1; /* 18 Board serial number word 1 */
1306 ushort serial_number_word2; /* 19 Board serial number word 2 */
1307 ushort serial_number_word3; /* 20 Board serial number word 3 */
1308 ushort check_sum; /* 21 EEP check sum */
1309 uchar oem_name[16]; /* 22 OEM name */
1310 ushort dvc_err_code; /* 30 last device driver error code */
1311 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1312 ushort adv_err_addr; /* 32 last uc error address */
1313 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1314 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1315 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1316 ushort num_of_err; /* 36 number of error */
1da177e4
LT
1317} ADVEEP_3550_CONFIG;
1318
27c868c2
MW
1319typedef struct adveep_38C0800_config {
1320 /* Word Offset, Description */
1321
1322 ushort cfg_lsw; /* 00 power up initialization */
1323 /* bit 13 set - Load CIS */
1324 /* bit 14 set - BIOS Enable */
1325 /* bit 15 set - Big Endian Mode */
1326 ushort cfg_msw; /* 01 unused */
1327 ushort disc_enable; /* 02 disconnect enable */
1328 ushort wdtr_able; /* 03 Wide DTR able */
1329 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1330 ushort start_motor; /* 05 send start up motor */
1331 ushort tagqng_able; /* 06 tag queuing able */
1332 ushort bios_scan; /* 07 BIOS device control */
1333 ushort scam_tolerant; /* 08 no scam */
1334
1335 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1336 uchar bios_boot_delay; /* power up wait */
1337
1338 uchar scsi_reset_delay; /* 10 reset delay */
1339 uchar bios_id_lun; /* first boot device scsi id & lun */
1340 /* high nibble is lun */
1341 /* low nibble is scsi id */
1342
1343 uchar termination_se; /* 11 0 - automatic */
1344 /* 1 - low off / high off */
1345 /* 2 - low off / high on */
1346 /* 3 - low on / high on */
1347 /* There is no low on / high off */
1348
1349 uchar termination_lvd; /* 11 0 - automatic */
1350 /* 1 - low off / high off */
1351 /* 2 - low off / high on */
1352 /* 3 - low on / high on */
1353 /* There is no low on / high off */
1354
1355 ushort bios_ctrl; /* 12 BIOS control bits */
1356 /* bit 0 BIOS don't act as initiator. */
1357 /* bit 1 BIOS > 1 GB support */
1358 /* bit 2 BIOS > 2 Disk Support */
1359 /* bit 3 BIOS don't support removables */
1360 /* bit 4 BIOS support bootable CD */
1361 /* bit 5 BIOS scan enabled */
1362 /* bit 6 BIOS support multiple LUNs */
1363 /* bit 7 BIOS display of message */
1364 /* bit 8 SCAM disabled */
1365 /* bit 9 Reset SCSI bus during init. */
1366 /* bit 10 */
1367 /* bit 11 No verbose initialization. */
1368 /* bit 12 SCSI parity enabled */
1369 /* bit 13 */
1370 /* bit 14 */
1371 /* bit 15 */
1372 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1373 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1374 uchar max_host_qng; /* 15 maximum host queueing */
1375 uchar max_dvc_qng; /* maximum per device queuing */
1376 ushort dvc_cntl; /* 16 control bit for driver */
1377 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1378 ushort serial_number_word1; /* 18 Board serial number word 1 */
1379 ushort serial_number_word2; /* 19 Board serial number word 2 */
1380 ushort serial_number_word3; /* 20 Board serial number word 3 */
1381 ushort check_sum; /* 21 EEP check sum */
1382 uchar oem_name[16]; /* 22 OEM name */
1383 ushort dvc_err_code; /* 30 last device driver error code */
1384 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1385 ushort adv_err_addr; /* 32 last uc error address */
1386 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1387 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1388 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1389 ushort reserved36; /* 36 reserved */
1390 ushort reserved37; /* 37 reserved */
1391 ushort reserved38; /* 38 reserved */
1392 ushort reserved39; /* 39 reserved */
1393 ushort reserved40; /* 40 reserved */
1394 ushort reserved41; /* 41 reserved */
1395 ushort reserved42; /* 42 reserved */
1396 ushort reserved43; /* 43 reserved */
1397 ushort reserved44; /* 44 reserved */
1398 ushort reserved45; /* 45 reserved */
1399 ushort reserved46; /* 46 reserved */
1400 ushort reserved47; /* 47 reserved */
1401 ushort reserved48; /* 48 reserved */
1402 ushort reserved49; /* 49 reserved */
1403 ushort reserved50; /* 50 reserved */
1404 ushort reserved51; /* 51 reserved */
1405 ushort reserved52; /* 52 reserved */
1406 ushort reserved53; /* 53 reserved */
1407 ushort reserved54; /* 54 reserved */
1408 ushort reserved55; /* 55 reserved */
1409 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1410 ushort cisprt_msw; /* 57 CIS PTR MSW */
1411 ushort subsysvid; /* 58 SubSystem Vendor ID */
1412 ushort subsysid; /* 59 SubSystem ID */
1413 ushort reserved60; /* 60 reserved */
1414 ushort reserved61; /* 61 reserved */
1415 ushort reserved62; /* 62 reserved */
1416 ushort reserved63; /* 63 reserved */
1da177e4
LT
1417} ADVEEP_38C0800_CONFIG;
1418
27c868c2
MW
1419typedef struct adveep_38C1600_config {
1420 /* Word Offset, Description */
1421
1422 ushort cfg_lsw; /* 00 power up initialization */
1423 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1424 /* clear - Func. 0 INTA, Func. 1 INTB */
1425 /* bit 13 set - Load CIS */
1426 /* bit 14 set - BIOS Enable */
1427 /* bit 15 set - Big Endian Mode */
1428 ushort cfg_msw; /* 01 unused */
1429 ushort disc_enable; /* 02 disconnect enable */
1430 ushort wdtr_able; /* 03 Wide DTR able */
1431 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1432 ushort start_motor; /* 05 send start up motor */
1433 ushort tagqng_able; /* 06 tag queuing able */
1434 ushort bios_scan; /* 07 BIOS device control */
1435 ushort scam_tolerant; /* 08 no scam */
1436
1437 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1438 uchar bios_boot_delay; /* power up wait */
1439
1440 uchar scsi_reset_delay; /* 10 reset delay */
1441 uchar bios_id_lun; /* first boot device scsi id & lun */
1442 /* high nibble is lun */
1443 /* low nibble is scsi id */
1444
1445 uchar termination_se; /* 11 0 - automatic */
1446 /* 1 - low off / high off */
1447 /* 2 - low off / high on */
1448 /* 3 - low on / high on */
1449 /* There is no low on / high off */
1450
1451 uchar termination_lvd; /* 11 0 - automatic */
1452 /* 1 - low off / high off */
1453 /* 2 - low off / high on */
1454 /* 3 - low on / high on */
1455 /* There is no low on / high off */
1456
1457 ushort bios_ctrl; /* 12 BIOS control bits */
1458 /* bit 0 BIOS don't act as initiator. */
1459 /* bit 1 BIOS > 1 GB support */
1460 /* bit 2 BIOS > 2 Disk Support */
1461 /* bit 3 BIOS don't support removables */
1462 /* bit 4 BIOS support bootable CD */
1463 /* bit 5 BIOS scan enabled */
1464 /* bit 6 BIOS support multiple LUNs */
1465 /* bit 7 BIOS display of message */
1466 /* bit 8 SCAM disabled */
1467 /* bit 9 Reset SCSI bus during init. */
1468 /* bit 10 Basic Integrity Checking disabled */
1469 /* bit 11 No verbose initialization. */
1470 /* bit 12 SCSI parity enabled */
1471 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1472 /* bit 14 */
1473 /* bit 15 */
1474 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1475 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1476 uchar max_host_qng; /* 15 maximum host queueing */
1477 uchar max_dvc_qng; /* maximum per device queuing */
1478 ushort dvc_cntl; /* 16 control bit for driver */
1479 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1480 ushort serial_number_word1; /* 18 Board serial number word 1 */
1481 ushort serial_number_word2; /* 19 Board serial number word 2 */
1482 ushort serial_number_word3; /* 20 Board serial number word 3 */
1483 ushort check_sum; /* 21 EEP check sum */
1484 uchar oem_name[16]; /* 22 OEM name */
1485 ushort dvc_err_code; /* 30 last device driver error code */
1486 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1487 ushort adv_err_addr; /* 32 last uc error address */
1488 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1489 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1490 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1491 ushort reserved36; /* 36 reserved */
1492 ushort reserved37; /* 37 reserved */
1493 ushort reserved38; /* 38 reserved */
1494 ushort reserved39; /* 39 reserved */
1495 ushort reserved40; /* 40 reserved */
1496 ushort reserved41; /* 41 reserved */
1497 ushort reserved42; /* 42 reserved */
1498 ushort reserved43; /* 43 reserved */
1499 ushort reserved44; /* 44 reserved */
1500 ushort reserved45; /* 45 reserved */
1501 ushort reserved46; /* 46 reserved */
1502 ushort reserved47; /* 47 reserved */
1503 ushort reserved48; /* 48 reserved */
1504 ushort reserved49; /* 49 reserved */
1505 ushort reserved50; /* 50 reserved */
1506 ushort reserved51; /* 51 reserved */
1507 ushort reserved52; /* 52 reserved */
1508 ushort reserved53; /* 53 reserved */
1509 ushort reserved54; /* 54 reserved */
1510 ushort reserved55; /* 55 reserved */
1511 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1512 ushort cisprt_msw; /* 57 CIS PTR MSW */
1513 ushort subsysvid; /* 58 SubSystem Vendor ID */
1514 ushort subsysid; /* 59 SubSystem ID */
1515 ushort reserved60; /* 60 reserved */
1516 ushort reserved61; /* 61 reserved */
1517 ushort reserved62; /* 62 reserved */
1518 ushort reserved63; /* 63 reserved */
1da177e4
LT
1519} ADVEEP_38C1600_CONFIG;
1520
1521/*
1522 * EEPROM Commands
1523 */
1524#define ASC_EEP_CMD_DONE 0x0200
1525#define ASC_EEP_CMD_DONE_ERR 0x0001
1526
1527/* cfg_word */
1528#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
1529
1530/* bios_ctrl */
1531#define BIOS_CTRL_BIOS 0x0001
1532#define BIOS_CTRL_EXTENDED_XLAT 0x0002
1533#define BIOS_CTRL_GT_2_DISK 0x0004
1534#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1535#define BIOS_CTRL_BOOTABLE_CD 0x0010
1536#define BIOS_CTRL_MULTIPLE_LUN 0x0040
1537#define BIOS_CTRL_DISPLAY_MSG 0x0080
1538#define BIOS_CTRL_NO_SCAM 0x0100
1539#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1540#define BIOS_CTRL_INIT_VERBOSE 0x0800
1541#define BIOS_CTRL_SCSI_PARITY 0x1000
1542#define BIOS_CTRL_AIPP_DIS 0x2000
1543
27c868c2 1544#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1da177e4 1545
27c868c2 1546#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1547
1548/*
1549 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1550 * a special 16K Adv Library and Microcode version. After the issue is
1551 * resolved, should restore 32K support.
1552 *
1553 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1554 */
27c868c2 1555#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1556
1557/*
1558 * Byte I/O register address from base of 'iop_base'.
1559 */
1560#define IOPB_INTR_STATUS_REG 0x00
1561#define IOPB_CHIP_ID_1 0x01
1562#define IOPB_INTR_ENABLES 0x02
1563#define IOPB_CHIP_TYPE_REV 0x03
1564#define IOPB_RES_ADDR_4 0x04
1565#define IOPB_RES_ADDR_5 0x05
1566#define IOPB_RAM_DATA 0x06
1567#define IOPB_RES_ADDR_7 0x07
1568#define IOPB_FLAG_REG 0x08
1569#define IOPB_RES_ADDR_9 0x09
1570#define IOPB_RISC_CSR 0x0A
1571#define IOPB_RES_ADDR_B 0x0B
1572#define IOPB_RES_ADDR_C 0x0C
1573#define IOPB_RES_ADDR_D 0x0D
1574#define IOPB_SOFT_OVER_WR 0x0E
1575#define IOPB_RES_ADDR_F 0x0F
1576#define IOPB_MEM_CFG 0x10
1577#define IOPB_RES_ADDR_11 0x11
1578#define IOPB_GPIO_DATA 0x12
1579#define IOPB_RES_ADDR_13 0x13
1580#define IOPB_FLASH_PAGE 0x14
1581#define IOPB_RES_ADDR_15 0x15
1582#define IOPB_GPIO_CNTL 0x16
1583#define IOPB_RES_ADDR_17 0x17
1584#define IOPB_FLASH_DATA 0x18
1585#define IOPB_RES_ADDR_19 0x19
1586#define IOPB_RES_ADDR_1A 0x1A
1587#define IOPB_RES_ADDR_1B 0x1B
1588#define IOPB_RES_ADDR_1C 0x1C
1589#define IOPB_RES_ADDR_1D 0x1D
1590#define IOPB_RES_ADDR_1E 0x1E
1591#define IOPB_RES_ADDR_1F 0x1F
1592#define IOPB_DMA_CFG0 0x20
1593#define IOPB_DMA_CFG1 0x21
1594#define IOPB_TICKLE 0x22
1595#define IOPB_DMA_REG_WR 0x23
1596#define IOPB_SDMA_STATUS 0x24
1597#define IOPB_SCSI_BYTE_CNT 0x25
1598#define IOPB_HOST_BYTE_CNT 0x26
1599#define IOPB_BYTE_LEFT_TO_XFER 0x27
1600#define IOPB_BYTE_TO_XFER_0 0x28
1601#define IOPB_BYTE_TO_XFER_1 0x29
1602#define IOPB_BYTE_TO_XFER_2 0x2A
1603#define IOPB_BYTE_TO_XFER_3 0x2B
1604#define IOPB_ACC_GRP 0x2C
1605#define IOPB_RES_ADDR_2D 0x2D
1606#define IOPB_DEV_ID 0x2E
1607#define IOPB_RES_ADDR_2F 0x2F
1608#define IOPB_SCSI_DATA 0x30
1609#define IOPB_RES_ADDR_31 0x31
1610#define IOPB_RES_ADDR_32 0x32
1611#define IOPB_SCSI_DATA_HSHK 0x33
1612#define IOPB_SCSI_CTRL 0x34
1613#define IOPB_RES_ADDR_35 0x35
1614#define IOPB_RES_ADDR_36 0x36
1615#define IOPB_RES_ADDR_37 0x37
1616#define IOPB_RAM_BIST 0x38
1617#define IOPB_PLL_TEST 0x39
1618#define IOPB_PCI_INT_CFG 0x3A
1619#define IOPB_RES_ADDR_3B 0x3B
1620#define IOPB_RFIFO_CNT 0x3C
1621#define IOPB_RES_ADDR_3D 0x3D
1622#define IOPB_RES_ADDR_3E 0x3E
1623#define IOPB_RES_ADDR_3F 0x3F
1624
1625/*
1626 * Word I/O register address from base of 'iop_base'.
1627 */
27c868c2
MW
1628#define IOPW_CHIP_ID_0 0x00 /* CID0 */
1629#define IOPW_CTRL_REG 0x02 /* CC */
1630#define IOPW_RAM_ADDR 0x04 /* LA */
1631#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 1632#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
1633#define IOPW_RISC_CSR 0x0A /* CSR */
1634#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1635#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 1636#define IOPW_RES_ADDR_10 0x10
27c868c2 1637#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 1638#define IOPW_RES_ADDR_14 0x14
27c868c2 1639#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 1640#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
1641#define IOPW_EE_CMD 0x1A /* EC */
1642#define IOPW_EE_DATA 0x1C /* ED */
1643#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 1644#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
1645#define IOPW_Q_BASE 0x22 /* QB */
1646#define IOPW_QP 0x24 /* QP */
1647#define IOPW_IX 0x26 /* IX */
1648#define IOPW_SP 0x28 /* SP */
1649#define IOPW_PC 0x2A /* PC */
1da177e4
LT
1650#define IOPW_RES_ADDR_2C 0x2C
1651#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
1652#define IOPW_SCSI_DATA 0x30 /* SD */
1653#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1654#define IOPW_SCSI_CTRL 0x34 /* SC */
1655#define IOPW_HSHK_CFG 0x36 /* HCFG */
1656#define IOPW_SXFR_STATUS 0x36 /* SXS */
1657#define IOPW_SXFR_CNTL 0x38 /* SXL */
1658#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 1659#define IOPW_RES_ADDR_3C 0x3C
27c868c2 1660#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
1661
1662/*
1663 * Doubleword I/O register address from base of 'iop_base'.
1664 */
1665#define IOPDW_RES_ADDR_0 0x00
1666#define IOPDW_RAM_DATA 0x04
1667#define IOPDW_RES_ADDR_8 0x08
1668#define IOPDW_RES_ADDR_C 0x0C
1669#define IOPDW_RES_ADDR_10 0x10
1670#define IOPDW_COMMA 0x14
1671#define IOPDW_COMMB 0x18
1672#define IOPDW_RES_ADDR_1C 0x1C
1673#define IOPDW_SDMA_ADDR0 0x20
1674#define IOPDW_SDMA_ADDR1 0x24
1675#define IOPDW_SDMA_COUNT 0x28
1676#define IOPDW_SDMA_ERROR 0x2C
1677#define IOPDW_RDMA_ADDR0 0x30
1678#define IOPDW_RDMA_ADDR1 0x34
1679#define IOPDW_RDMA_COUNT 0x38
1680#define IOPDW_RDMA_ERROR 0x3C
1681
1682#define ADV_CHIP_ID_BYTE 0x25
1683#define ADV_CHIP_ID_WORD 0x04C1
1684
1685#define ADV_SC_SCSI_BUS_RESET 0x2000
1686
1687#define ADV_INTR_ENABLE_HOST_INTR 0x01
1688#define ADV_INTR_ENABLE_SEL_INTR 0x02
1689#define ADV_INTR_ENABLE_DPR_INTR 0x04
1690#define ADV_INTR_ENABLE_RTA_INTR 0x08
1691#define ADV_INTR_ENABLE_RMA_INTR 0x10
1692#define ADV_INTR_ENABLE_RST_INTR 0x20
1693#define ADV_INTR_ENABLE_DPE_INTR 0x40
1694#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1695
1696#define ADV_INTR_STATUS_INTRA 0x01
1697#define ADV_INTR_STATUS_INTRB 0x02
1698#define ADV_INTR_STATUS_INTRC 0x04
1699
1700#define ADV_RISC_CSR_STOP (0x0000)
1701#define ADV_RISC_TEST_COND (0x2000)
1702#define ADV_RISC_CSR_RUN (0x4000)
1703#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1704
1705#define ADV_CTRL_REG_HOST_INTR 0x0100
1706#define ADV_CTRL_REG_SEL_INTR 0x0200
1707#define ADV_CTRL_REG_DPR_INTR 0x0400
1708#define ADV_CTRL_REG_RTA_INTR 0x0800
1709#define ADV_CTRL_REG_RMA_INTR 0x1000
1710#define ADV_CTRL_REG_RES_BIT14 0x2000
1711#define ADV_CTRL_REG_DPE_INTR 0x4000
1712#define ADV_CTRL_REG_POWER_DONE 0x8000
1713#define ADV_CTRL_REG_ANY_INTR 0xFF00
1714
1715#define ADV_CTRL_REG_CMD_RESET 0x00C6
1716#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1717#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1718#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1719#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1720
1721#define ADV_TICKLE_NOP 0x00
1722#define ADV_TICKLE_A 0x01
1723#define ADV_TICKLE_B 0x02
1724#define ADV_TICKLE_C 0x03
1725
1726#define ADV_SCSI_CTRL_RSTOUT 0x2000
1727
1728#define AdvIsIntPending(port) \
1729 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1730
1731/*
1732 * SCSI_CFG0 Register bit definitions
1733 */
27c868c2
MW
1734#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1735#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1736#define EVEN_PARITY 0x1000 /* Select Even Parity */
1737#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1738#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1739#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1740#define SCAM_EN 0x0080 /* Enable SCAM selection */
1741#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1742#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1743#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1744#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
1745
1746/*
1747 * SCSI_CFG1 Register bit definitions
1748 */
27c868c2
MW
1749#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1750#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1751#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1752#define FILTER_SEL 0x0C00 /* Filter Period Selection */
1753#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1754#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1755#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1756#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1757#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1758#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1759#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1760#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1761#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1762#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1763#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
1764
1765/*
1766 * Addendum for ASC-38C0800 Chip
1767 *
1768 * The ASC-38C1600 Chip uses the same definitions except that the
1769 * bus mode override bits [12:10] have been moved to byte register
1770 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1771 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1772 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1773 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1774 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1775 */
27c868c2
MW
1776#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1777#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1778#define HVD 0x1000 /* HVD Device Detect */
1779#define LVD 0x0800 /* LVD Device Detect */
1780#define SE 0x0400 /* SE Device Detect */
1781#define TERM_LVD 0x00C0 /* LVD Termination Bits */
1782#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1783#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1784#define TERM_SE 0x0030 /* SE Termination Bits */
1785#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1786#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1787#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1788#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1789#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1790#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1791#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1792#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
1793
1794#define CABLE_ILLEGAL_A 0x7
1795 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1796
1797#define CABLE_ILLEGAL_B 0xB
1798 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1799
1800/*
1801 * MEM_CFG Register bit definitions
1802 */
27c868c2
MW
1803#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1804#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1805#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1806#define RAM_SZ_2KB 0x00 /* 2 KB */
1807#define RAM_SZ_4KB 0x04 /* 4 KB */
1808#define RAM_SZ_8KB 0x08 /* 8 KB */
1809#define RAM_SZ_16KB 0x0C /* 16 KB */
1810#define RAM_SZ_32KB 0x10 /* 32 KB */
1811#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
1812
1813/*
1814 * DMA_CFG0 Register bit definitions
1815 *
1816 * This register is only accessible to the host.
1817 */
27c868c2
MW
1818#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1819#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1820#define FIFO_THRESH_16B 0x00 /* 16 bytes */
1821#define FIFO_THRESH_32B 0x20 /* 32 bytes */
1822#define FIFO_THRESH_48B 0x30 /* 48 bytes */
1823#define FIFO_THRESH_64B 0x40 /* 64 bytes */
1824#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1825#define FIFO_THRESH_96B 0x60 /* 96 bytes */
1826#define FIFO_THRESH_112B 0x70 /* 112 bytes */
1827#define START_CTL 0x0C /* DMA start conditions */
1828#define START_CTL_TH 0x00 /* Wait threshold level (default) */
1829#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1830#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1831#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1832#define READ_CMD 0x03 /* Memory Read Method */
1833#define READ_CMD_MR 0x00 /* Memory Read */
1834#define READ_CMD_MRL 0x02 /* Memory Read Long */
1835#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
1836
1837/*
1838 * ASC-38C0800 RAM BIST Register bit definitions
1839 */
1840#define RAM_TEST_MODE 0x80
1841#define PRE_TEST_MODE 0x40
1842#define NORMAL_MODE 0x00
1843#define RAM_TEST_DONE 0x10
1844#define RAM_TEST_STATUS 0x0F
1845#define RAM_TEST_HOST_ERROR 0x08
1846#define RAM_TEST_INTRAM_ERROR 0x04
1847#define RAM_TEST_RISC_ERROR 0x02
1848#define RAM_TEST_SCSI_ERROR 0x01
1849#define RAM_TEST_SUCCESS 0x00
1850#define PRE_TEST_VALUE 0x05
1851#define NORMAL_VALUE 0x00
1852
1853/*
1854 * ASC38C1600 Definitions
1855 *
1856 * IOPB_PCI_INT_CFG Bit Field Definitions
1857 */
1858
27c868c2 1859#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
1860
1861/*
1862 * Bit 1 can be set to change the interrupt for the Function to operate in
1863 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1864 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1865 * mode, otherwise the operating mode is undefined.
1866 */
1867#define TOTEMPOLE 0x02
1868
1869/*
1870 * Bit 0 can be used to change the Int Pin for the Function. The value is
1871 * 0 by default for both Functions with Function 0 using INT A and Function
1872 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1873 * INT A is used.
1874 *
1875 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1876 * value specified in the PCI Configuration Space.
1877 */
1878#define INTAB 0x01
1879
1880/* a_advlib.h */
1881
1882/*
1883 * Adv Library Status Definitions
1884 */
1885#define ADV_TRUE 1
1886#define ADV_FALSE 0
1887#define ADV_NOERROR 1
1888#define ADV_SUCCESS 1
1889#define ADV_BUSY 0
1890#define ADV_ERROR (-1)
1891
1da177e4
LT
1892/*
1893 * ADV_DVC_VAR 'warn_code' values
1894 */
27c868c2
MW
1895#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1896#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1897#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
1898#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
1899#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 1900
27c868c2
MW
1901#define ADV_MAX_TID 15 /* max. target identifier */
1902#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
1903
1904/*
1905 * Error code values are set in ADV_DVC_VAR 'err_code'.
1906 */
27c868c2
MW
1907#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
1908#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
1909#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
1910#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
1911#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
1912#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
1913#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
1914#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
1915#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
1916#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
1917#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
1918#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
1919#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
1920#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
1921
1922/*
1923 * Fixed locations of microcode operating variables.
1924 */
27c868c2
MW
1925#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1926#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1927#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1928#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1929#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1930#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1931#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1932#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1933#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1934#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1935#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1936#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1937#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
1938#define ASC_MC_CHIP_TYPE 0x009A
1939#define ASC_MC_INTRB_CODE 0x009B
1940#define ASC_MC_WDTR_ABLE 0x009C
1941#define ASC_MC_SDTR_ABLE 0x009E
1942#define ASC_MC_TAGQNG_ABLE 0x00A0
1943#define ASC_MC_DISC_ENABLE 0x00A2
1944#define ASC_MC_IDLE_CMD_STATUS 0x00A4
1945#define ASC_MC_IDLE_CMD 0x00A6
1946#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1947#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1948#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1949#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1950#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1951#define ASC_MC_SDTR_DONE 0x00B6
1952#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1953#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1954#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 1955#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 1956#define ASC_MC_WDTR_DONE 0x0124
27c868c2 1957#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
1958#define ASC_MC_ICQ 0x0160
1959#define ASC_MC_IRQ 0x0164
1960#define ASC_MC_PPR_ABLE 0x017A
1961
1962/*
1963 * BIOS LRAM variable absolute offsets.
1964 */
1965#define BIOS_CODESEG 0x54
1966#define BIOS_CODELEN 0x56
1967#define BIOS_SIGNATURE 0x58
1968#define BIOS_VERSION 0x5A
1969
1970/*
1971 * Microcode Control Flags
1972 *
1973 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1974 * and handled by the microcode.
1975 */
27c868c2
MW
1976#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1977#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
1978
1979/*
1980 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1981 */
1982#define HSHK_CFG_WIDE_XFR 0x8000
1983#define HSHK_CFG_RATE 0x0F00
1984#define HSHK_CFG_OFFSET 0x001F
1985
27c868c2
MW
1986#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1987#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1988#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1989#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1990
1991#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1992#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1993#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1994#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1995#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1996
1997#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1998#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1999#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2000#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2001#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
2002/*
2003 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2004 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2005 */
27c868c2
MW
2006#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2007#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
2008
2009/*
2010 * All fields here are accessed by the board microcode and need to be
2011 * little-endian.
2012 */
27c868c2
MW
2013typedef struct adv_carr_t {
2014 ADV_VADDR carr_va; /* Carrier Virtual Address */
2015 ADV_PADDR carr_pa; /* Carrier Physical Address */
2016 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2017 /*
2018 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2019 *
2020 * next_vpa [3:1] Reserved Bits
2021 * next_vpa [0] Done Flag set in Response Queue.
2022 */
2023 ADV_VADDR next_vpa;
1da177e4
LT
2024} ADV_CARR_T;
2025
2026/*
2027 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2028 */
2029#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2030
2031#define ASC_RQ_DONE 0x00000001
2032#define ASC_RQ_GOOD 0x00000002
2033#define ASC_CQ_STOPPER 0x00000000
2034
2035#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2036
2037#define ADV_CARRIER_NUM_PAGE_CROSSING \
2038 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2039 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2040
2041#define ADV_CARRIER_BUFSIZE \
2042 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2043
2044/*
2045 * ASC_SCSI_REQ_Q 'a_flag' definitions
2046 *
2047 * The Adv Library should limit use to the lower nibble (4 bits) of
2048 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2049 */
27c868c2
MW
2050#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2051#define ADV_SCSIQ_DONE 0x02 /* request done */
2052#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 2053
27c868c2
MW
2054#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2055#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2056#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
2057
2058/*
2059 * Adapter temporary configuration structure
2060 *
2061 * This structure can be discarded after initialization. Don't add
2062 * fields here needed after initialization.
2063 *
2064 * Field naming convention:
2065 *
2066 * *_enable indicates the field enables or disables a feature. The
2067 * value of the field is never reset.
2068 */
2069typedef struct adv_dvc_cfg {
27c868c2
MW
2070 ushort disc_enable; /* enable disconnection */
2071 uchar chip_version; /* chip version */
2072 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2073 ushort lib_version; /* Adv Library version number */
2074 ushort control_flag; /* Microcode Control Flag */
2075 ushort mcode_date; /* Microcode date */
2076 ushort mcode_version; /* Microcode version */
27c868c2
MW
2077 ushort serial1; /* EEPROM serial number word 1 */
2078 ushort serial2; /* EEPROM serial number word 2 */
2079 ushort serial3; /* EEPROM serial number word 3 */
1da177e4
LT
2080} ADV_DVC_CFG;
2081
2082struct adv_dvc_var;
2083struct adv_scsi_req_q;
2084
1da177e4
LT
2085/*
2086 * Adapter operation variable structure.
2087 *
2088 * One structure is required per host adapter.
2089 *
2090 * Field naming convention:
2091 *
2092 * *_able indicates both whether a feature should be enabled or disabled
2093 * and whether a device isi capable of the feature. At initialization
2094 * this field may be set, but later if a device is found to be incapable
2095 * of the feature, the field is cleared.
2096 */
2097typedef struct adv_dvc_var {
27c868c2
MW
2098 AdvPortAddr iop_base; /* I/O port address */
2099 ushort err_code; /* fatal error code */
2100 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
27c868c2
MW
2101 ushort wdtr_able; /* try WDTR for a device */
2102 ushort sdtr_able; /* try SDTR for a device */
2103 ushort ultra_able; /* try SDTR Ultra speed for a device */
2104 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2105 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2106 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2107 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2108 ushort tagqng_able; /* try tagged queuing with a device */
2109 ushort ppr_able; /* PPR message capable per TID bitmask. */
2110 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2111 ushort start_motor; /* start motor command allowed */
2112 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2113 uchar chip_no; /* should be assigned by caller */
2114 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2115 uchar irq_no; /* IRQ number */
2116 ushort no_scam; /* scam_tolerant of EEPROM */
2117 struct asc_board *drv_ptr; /* driver pointer to private structure */
2118 uchar chip_scsi_id; /* chip SCSI target ID */
2119 uchar chip_type;
2120 uchar bist_err_code;
2121 ADV_CARR_T *carrier_buf;
2122 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2123 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2124 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2125 ushort carr_pending_cnt; /* Count of pending carriers. */
2126 /*
2127 * Note: The following fields will not be used after initialization. The
2128 * driver may discard the buffer after initialization is done.
2129 */
2130 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
2131} ADV_DVC_VAR;
2132
2133#define NO_OF_SG_PER_BLOCK 15
2134
2135typedef struct asc_sg_block {
27c868c2
MW
2136 uchar reserved1;
2137 uchar reserved2;
2138 uchar reserved3;
2139 uchar sg_cnt; /* Valid entries in block. */
2140 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2141 struct {
2142 ADV_PADDR sg_addr; /* SG element address. */
2143 ADV_DCNT sg_count; /* SG element count. */
2144 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
2145} ADV_SG_BLOCK;
2146
2147/*
2148 * ADV_SCSI_REQ_Q - microcode request structure
2149 *
2150 * All fields in this structure up to byte 60 are used by the microcode.
2151 * The microcode makes assumptions about the size and ordering of fields
2152 * in this structure. Do not change the structure definition here without
2153 * coordinating the change with the microcode.
2154 *
2155 * All fields accessed by microcode must be maintained in little_endian
2156 * order.
2157 */
2158typedef struct adv_scsi_req_q {
27c868c2
MW
2159 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2160 uchar target_cmd;
2161 uchar target_id; /* Device target identifier. */
2162 uchar target_lun; /* Device target logical unit number. */
2163 ADV_PADDR data_addr; /* Data buffer physical address. */
2164 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2165 ADV_PADDR sense_addr;
2166 ADV_PADDR carr_pa;
2167 uchar mflag;
2168 uchar sense_len;
2169 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2170 uchar scsi_cntl;
2171 uchar done_status; /* Completion status. */
2172 uchar scsi_status; /* SCSI status byte. */
2173 uchar host_status; /* Ucode host status. */
2174 uchar sg_working_ix;
2175 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2176 ADV_PADDR sg_real_addr; /* SG list physical address. */
2177 ADV_PADDR scsiq_rptr;
2178 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2179 ADV_VADDR scsiq_ptr;
2180 ADV_VADDR carr_va;
2181 /*
2182 * End of microcode structure - 60 bytes. The rest of the structure
2183 * is used by the Adv Library and ignored by the microcode.
2184 */
2185 ADV_VADDR srb_ptr;
2186 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2187 char *vdata_addr; /* Data buffer virtual address. */
2188 uchar a_flag;
2189 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
2190} ADV_SCSI_REQ_Q;
2191
2192/*
2193 * Microcode idle loop commands
2194 */
2195#define IDLE_CMD_COMPLETED 0
2196#define IDLE_CMD_STOP_CHIP 0x0001
2197#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2198#define IDLE_CMD_SEND_INT 0x0004
2199#define IDLE_CMD_ABORT 0x0008
2200#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
2201#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2202#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
2203#define IDLE_CMD_SCSIREQ 0x0080
2204
2205#define IDLE_CMD_STATUS_SUCCESS 0x0001
2206#define IDLE_CMD_STATUS_FAILURE 0x0002
2207
2208/*
2209 * AdvSendIdleCmd() flag definitions.
2210 */
2211#define ADV_NOWAIT 0x01
2212
2213/*
2214 * Wait loop time out values.
2215 */
27c868c2
MW
2216#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
2217#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2218#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2219#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
2220#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 2221
27c868c2
MW
2222#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2223#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2224#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2225#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 2226
27c868c2 2227#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4
LT
2228
2229/*
2230 * Device drivers must define the following functions.
2231 */
27c868c2
MW
2232static inline ulong DvcEnterCritical(void);
2233static inline void DvcLeaveCritical(ulong);
2234static void DvcSleepMilliSecond(ADV_DCNT);
27c868c2
MW
2235static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2236 uchar *, ASC_SDCNT *, int);
2237static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
1da177e4
LT
2238
2239/*
2240 * Adv Library functions available to drivers.
2241 */
27c868c2
MW
2242static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2243static int AdvISR(ADV_DVC_VAR *);
27c868c2
MW
2244static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2245static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
2246static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
2247static int AdvResetChipAndSB(ADV_DVC_VAR *);
2248static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
2249
2250/*
2251 * Internal Adv Library functions.
2252 */
27c868c2 2253static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
27c868c2
MW
2254static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
2255static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
2256static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
2257static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2258static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2259static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2260static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2261static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2262static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2263static void AdvWaitEEPCmd(AdvPortAddr);
2264static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4 2265
1da177e4
LT
2266/* Read byte from a register. */
2267#define AdvReadByteRegister(iop_base, reg_off) \
2268 (ADV_MEM_READB((iop_base) + (reg_off)))
2269
2270/* Write byte to a register. */
2271#define AdvWriteByteRegister(iop_base, reg_off, byte) \
2272 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2273
2274/* Read word (2 bytes) from a register. */
2275#define AdvReadWordRegister(iop_base, reg_off) \
2276 (ADV_MEM_READW((iop_base) + (reg_off)))
2277
2278/* Write word (2 bytes) to a register. */
2279#define AdvWriteWordRegister(iop_base, reg_off, word) \
2280 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2281
2282/* Write dword (4 bytes) to a register. */
2283#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2284 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2285
2286/* Read byte from LRAM. */
2287#define AdvReadByteLram(iop_base, addr, byte) \
2288do { \
2289 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2290 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2291} while (0)
2292
2293/* Write byte to LRAM. */
2294#define AdvWriteByteLram(iop_base, addr, byte) \
2295 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2296 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2297
2298/* Read word (2 bytes) from LRAM. */
2299#define AdvReadWordLram(iop_base, addr, word) \
2300do { \
2301 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2302 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2303} while (0)
2304
2305/* Write word (2 bytes) to LRAM. */
2306#define AdvWriteWordLram(iop_base, addr, word) \
2307 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2308 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2309
2310/* Write little-endian double word (4 bytes) to LRAM */
2311/* Because of unspecified C language ordering don't use auto-increment. */
2312#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2313 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2314 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2315 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2316 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2317 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2318 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2319
2320/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2321#define AdvReadWordAutoIncLram(iop_base) \
2322 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2323
2324/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2325#define AdvWriteWordAutoIncLram(iop_base, word) \
2326 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2327
1da177e4
LT
2328/*
2329 * Define macro to check for Condor signature.
2330 *
2331 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2332 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2333 */
2334#define AdvFindSignature(iop_base) \
2335 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2336 ADV_CHIP_ID_BYTE) && \
2337 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2338 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2339
2340/*
2341 * Define macro to Return the version number of the chip at 'iop_base'.
2342 *
2343 * The second parameter 'bus_type' is currently unused.
2344 */
2345#define AdvGetChipVersion(iop_base, bus_type) \
2346 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2347
2348/*
2349 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2350 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2351 *
2352 * If the request has not yet been sent to the device it will simply be
2353 * aborted from RISC memory. If the request is disconnected it will be
2354 * aborted on reselection by sending an Abort Message to the target ID.
2355 *
2356 * Return value:
2357 * ADV_TRUE(1) - Queue was successfully aborted.
2358 * ADV_FALSE(0) - Queue was not found on the active queue list.
2359 */
2360#define AdvAbortQueue(asc_dvc, scsiq) \
2361 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2362 (ADV_DCNT) (scsiq))
2363
2364/*
2365 * Send a Bus Device Reset Message to the specified target ID.
2366 *
2367 * All outstanding commands will be purged if sending the
2368 * Bus Device Reset Message is successful.
2369 *
2370 * Return Value:
2371 * ADV_TRUE(1) - All requests on the target are purged.
2372 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2373 * are not purged.
2374 */
2375#define AdvResetDevice(asc_dvc, target_id) \
2376 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2377 (ADV_DCNT) (target_id))
2378
2379/*
2380 * SCSI Wide Type definition.
2381 */
2382#define ADV_SCSI_BIT_ID_TYPE ushort
2383
2384/*
2385 * AdvInitScsiTarget() 'cntl_flag' options.
2386 */
2387#define ADV_SCAN_LUN 0x01
2388#define ADV_CAPINFO_NOLUN 0x02
2389
2390/*
2391 * Convert target id to target id bit mask.
2392 */
2393#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2394
2395/*
2396 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2397 */
2398
27c868c2 2399#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
2400#define QD_NO_ERROR 0x01
2401#define QD_ABORTED_BY_HOST 0x02
2402#define QD_WITH_ERROR 0x04
2403
2404#define QHSTA_NO_ERROR 0x00
2405#define QHSTA_M_SEL_TIMEOUT 0x11
2406#define QHSTA_M_DATA_OVER_RUN 0x12
2407#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2408#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
2409#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2410#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2411#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2412#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2413#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2414#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2415#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 2416/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
2417#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2418#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2419#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2420#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2421#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2422#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2423#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2424#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
2425#define QHSTA_M_WTM_TIMEOUT 0x41
2426#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2427#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2428#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
2429#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2430#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2431#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4 2432
1da177e4
LT
2433/*
2434 * DvcGetPhyAddr() flag arguments
2435 */
27c868c2
MW
2436#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2437#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2438#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2439#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2440#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2441#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
2442
2443/* Return the address that is aligned at the next doubleword >= to 'addr'. */
2444#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2445#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2446#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2447
2448/*
2449 * Total contiguous memory needed for driver SG blocks.
2450 *
2451 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2452 * number of scatter-gather elements the driver supports in a
2453 * single request.
2454 */
2455
2456#define ADV_SG_LIST_MAX_BYTE_SIZE \
2457 (sizeof(ADV_SG_BLOCK) * \
2458 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2459
1da177e4
LT
2460/*
2461 * --- Driver Constants and Macros
2462 */
2463
1da177e4
LT
2464/* Reference Scsi_Host hostdata */
2465#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2466
2467/* asc_board_t flags */
2468#define ASC_HOST_IN_RESET 0x01
27c868c2 2469#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
2470#define ASC_SELECT_QUEUE_DEPTHS 0x08
2471
2472#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2473#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
2474
27c868c2 2475#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 2476
27c868c2 2477#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
2478
2479#ifdef CONFIG_PROC_FS
2480/* /proc/scsi/advansys/[0...] related definitions */
2481#define ASC_PRTBUF_SIZE 2048
2482#define ASC_PRTLINE_SIZE 160
2483
2484#define ASC_PRT_NEXT() \
2485 if (cp) { \
2486 totlen += len; \
2487 leftlen -= len; \
2488 if (leftlen == 0) { \
2489 return totlen; \
2490 } \
2491 cp += len; \
2492 }
2493#endif /* CONFIG_PROC_FS */
2494
2495/* Asc Library return codes */
2496#define ASC_TRUE 1
2497#define ASC_FALSE 0
2498#define ASC_NOERROR 1
2499#define ASC_BUSY 0
2500#define ASC_ERROR (-1)
2501
2502/* struct scsi_cmnd function return codes */
2503#define STATUS_BYTE(byte) (byte)
2504#define MSG_BYTE(byte) ((byte) << 8)
2505#define HOST_BYTE(byte) ((byte) << 16)
2506#define DRIVER_BYTE(byte) ((byte) << 24)
2507
1da177e4 2508#ifndef ADVANSYS_STATS
27c868c2
MW
2509#define ASC_STATS(shost, counter)
2510#define ASC_STATS_ADD(shost, counter, count)
1da177e4 2511#else /* ADVANSYS_STATS */
27c868c2
MW
2512#define ASC_STATS(shost, counter) \
2513 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 2514
27c868c2
MW
2515#define ASC_STATS_ADD(shost, counter, count) \
2516 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
2517#endif /* ADVANSYS_STATS */
2518
2519#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2520
2521/* If the result wraps when calculating tenths, return 0. */
2522#define ASC_TENTHS(num, den) \
2523 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2524 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2525
2526/*
2527 * Display a message to the console.
2528 */
2529#define ASC_PRINT(s) \
2530 { \
2531 printk("advansys: "); \
2532 printk(s); \
2533 }
2534
2535#define ASC_PRINT1(s, a1) \
2536 { \
2537 printk("advansys: "); \
2538 printk((s), (a1)); \
2539 }
2540
2541#define ASC_PRINT2(s, a1, a2) \
2542 { \
2543 printk("advansys: "); \
2544 printk((s), (a1), (a2)); \
2545 }
2546
2547#define ASC_PRINT3(s, a1, a2, a3) \
2548 { \
2549 printk("advansys: "); \
2550 printk((s), (a1), (a2), (a3)); \
2551 }
2552
2553#define ASC_PRINT4(s, a1, a2, a3, a4) \
2554 { \
2555 printk("advansys: "); \
2556 printk((s), (a1), (a2), (a3), (a4)); \
2557 }
2558
1da177e4
LT
2559#ifndef ADVANSYS_DEBUG
2560
2561#define ASC_DBG(lvl, s)
2562#define ASC_DBG1(lvl, s, a1)
2563#define ASC_DBG2(lvl, s, a1, a2)
2564#define ASC_DBG3(lvl, s, a1, a2, a3)
2565#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2566#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2567#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2568#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2569#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2570#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2571#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2572#define ASC_DBG_PRT_HEX(lvl, name, start, length)
2573#define ASC_DBG_PRT_CDB(lvl, cdb, len)
2574#define ASC_DBG_PRT_SENSE(lvl, sense, len)
2575#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2576
2577#else /* ADVANSYS_DEBUG */
2578
2579/*
2580 * Debugging Message Levels:
2581 * 0: Errors Only
2582 * 1: High-Level Tracing
2583 * 2-N: Verbose Tracing
2584 */
2585
2586#define ASC_DBG(lvl, s) \
2587 { \
2588 if (asc_dbglvl >= (lvl)) { \
2589 printk(s); \
2590 } \
2591 }
2592
2593#define ASC_DBG1(lvl, s, a1) \
2594 { \
2595 if (asc_dbglvl >= (lvl)) { \
2596 printk((s), (a1)); \
2597 } \
2598 }
2599
2600#define ASC_DBG2(lvl, s, a1, a2) \
2601 { \
2602 if (asc_dbglvl >= (lvl)) { \
2603 printk((s), (a1), (a2)); \
2604 } \
2605 }
2606
2607#define ASC_DBG3(lvl, s, a1, a2, a3) \
2608 { \
2609 if (asc_dbglvl >= (lvl)) { \
2610 printk((s), (a1), (a2), (a3)); \
2611 } \
2612 }
2613
2614#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2615 { \
2616 if (asc_dbglvl >= (lvl)) { \
2617 printk((s), (a1), (a2), (a3), (a4)); \
2618 } \
2619 }
2620
2621#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2622 { \
2623 if (asc_dbglvl >= (lvl)) { \
2624 asc_prt_scsi_host(s); \
2625 } \
2626 }
2627
2628#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2629 { \
2630 if (asc_dbglvl >= (lvl)) { \
2631 asc_prt_scsi_cmnd(s); \
2632 } \
2633 }
2634
2635#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2636 { \
2637 if (asc_dbglvl >= (lvl)) { \
2638 asc_prt_asc_scsi_q(scsiqp); \
2639 } \
2640 }
2641
2642#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2643 { \
2644 if (asc_dbglvl >= (lvl)) { \
2645 asc_prt_asc_qdone_info(qdone); \
2646 } \
2647 }
2648
2649#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2650 { \
2651 if (asc_dbglvl >= (lvl)) { \
2652 asc_prt_adv_scsi_req_q(scsiqp); \
2653 } \
2654 }
2655
2656#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2657 { \
2658 if (asc_dbglvl >= (lvl)) { \
2659 asc_prt_hex((name), (start), (length)); \
2660 } \
2661 }
2662
2663#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2664 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2665
2666#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2667 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2668
2669#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2670 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2671#endif /* ADVANSYS_DEBUG */
2672
2673#ifndef ADVANSYS_ASSERT
2674#define ASC_ASSERT(a)
2675#else /* ADVANSYS_ASSERT */
2676
2677#define ASC_ASSERT(a) \
2678 { \
2679 if (!(a)) { \
2680 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
2681 __FILE__, __LINE__); \
2682 } \
2683 }
2684
2685#endif /* ADVANSYS_ASSERT */
2686
1da177e4
LT
2687/*
2688 * --- Driver Structures
2689 */
2690
2691#ifdef ADVANSYS_STATS
2692
2693/* Per board statistics structure */
2694struct asc_stats {
27c868c2
MW
2695 /* Driver Entrypoint Statistics */
2696 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2697 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2698 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2699 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2700 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2701 ADV_DCNT done; /* # calls to request's scsi_done function */
2702 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2703 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2704 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2705 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2706 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2707 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2708 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2709 ADV_DCNT exe_unknown; /* # unknown returns. */
2710 /* Data Transfer Statistics */
2711 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2712 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2713 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2714 ADV_DCNT sg_elem; /* # scatter-gather elements */
2715 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
2716};
2717#endif /* ADVANSYS_STATS */
2718
1da177e4
LT
2719/*
2720 * Adv Library Request Structures
2721 *
2722 * The following two structures are used to process Wide Board requests.
2723 *
2724 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2725 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2726 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2727 * Mid-Level SCSI request structure.
2728 *
2729 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2730 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2731 * up to 255 scatter-gather elements may be used per request or
2732 * ADV_SCSI_REQ_Q.
2733 *
2734 * Both structures must be 32 byte aligned.
2735 */
2736typedef struct adv_sgblk {
27c868c2
MW
2737 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2738 uchar align[32]; /* Sgblock structure padding. */
2739 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
2740} adv_sgblk_t;
2741
2742typedef struct adv_req {
27c868c2
MW
2743 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2744 uchar align[32]; /* Request structure padding. */
2745 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2746 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2747 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
2748} adv_req_t;
2749
2750/*
2751 * Structure allocated for each board.
2752 *
8dfb5379 2753 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
2754 * of the 'Scsi_Host' structure starting at the 'hostdata'
2755 * field. It is guaranteed to be allocated from DMA-able memory.
2756 */
2757typedef struct asc_board {
394dbf3f 2758 struct device *dev;
27c868c2
MW
2759 int id; /* Board Id */
2760 uint flags; /* Board flags */
2761 union {
2762 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2763 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2764 } dvc_var;
2765 union {
2766 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2767 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2768 } dvc_cfg;
2769 ushort asc_n_io_port; /* Number I/O ports. */
27c868c2
MW
2770 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2771 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
2772 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2773 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2774 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2775 union {
2776 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2777 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2778 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2779 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2780 } eep_config;
2781 ulong last_reset; /* Saved last reset time */
2782 spinlock_t lock; /* Board spinlock */
27c868c2
MW
2783 /* /proc/scsi/advansys/[0...] */
2784 char *prtbuf; /* /proc print buffer */
1da177e4 2785#ifdef ADVANSYS_STATS
27c868c2
MW
2786 struct asc_stats asc_stats; /* Board statistics */
2787#endif /* ADVANSYS_STATS */
2788 /*
2789 * The following fields are used only for Narrow Boards.
2790 */
27c868c2
MW
2791 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2792 /*
2793 * The following fields are used only for Wide Boards.
2794 */
2795 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2796 ushort ioport; /* I/O Port address. */
b2c16f58 2797 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
2798 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2799 adv_req_t *adv_reqp; /* Request structures. */
2800 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2801 ushort bios_signature; /* BIOS Signature. */
2802 ushort bios_version; /* BIOS Version. */
2803 ushort bios_codeseg; /* BIOS Code Segment. */
2804 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
2805} asc_board_t;
2806
13ac2d9c
MW
2807#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2808 dvc_var.adv_dvc_var)
2809#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2810
1da177e4 2811/* Number of boards detected in system. */
78e77d8b
MW
2812static int asc_board_count;
2813
1da177e4 2814/* Overrun buffer used by all narrow boards. */
27c868c2 2815static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
2816
2817/*
2818 * Global structures required to issue a command.
2819 */
27c868c2
MW
2820static ASC_SCSI_Q asc_scsi_q = { {0} };
2821static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4 2822
1da177e4 2823#ifdef ADVANSYS_DEBUG
27c868c2 2824static int asc_dbglvl = 3;
1da177e4
LT
2825#endif /* ADVANSYS_DEBUG */
2826
1da177e4
LT
2827/*
2828 * --- Driver Function Prototypes
1da177e4
LT
2829 */
2830
27c868c2 2831static int advansys_slave_configure(struct scsi_device *);
27c868c2
MW
2832static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
2833static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
2834static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
2835static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
1da177e4 2836#ifdef CONFIG_PROC_FS
27c868c2
MW
2837static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
2838static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
2839static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
2840static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
2841static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
2842static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
2843static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
2844static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
2845static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
2846static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
2847#endif /* CONFIG_PROC_FS */
2848
1da177e4
LT
2849/* Statistics function prototypes. */
2850#ifdef ADVANSYS_STATS
2851#ifdef CONFIG_PROC_FS
27c868c2 2852static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
1da177e4
LT
2853#endif /* CONFIG_PROC_FS */
2854#endif /* ADVANSYS_STATS */
2855
2856/* Debug function prototypes. */
2857#ifdef ADVANSYS_DEBUG
27c868c2
MW
2858static void asc_prt_scsi_host(struct Scsi_Host *);
2859static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
2860static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
2861static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
2862static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
2863static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
2864static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
2865static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
2866static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
2867static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
2868static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
2869#endif /* ADVANSYS_DEBUG */
2870
1da177e4
LT
2871#ifdef CONFIG_PROC_FS
2872/*
c304ec94 2873 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
2874 *
2875 * *buffer: I/O buffer
2876 * **start: if inout == FALSE pointer into buffer where user read should start
2877 * offset: current offset into a /proc/scsi/advansys/[0...] file
2878 * length: length of buffer
2879 * hostno: Scsi_Host host_no
2880 * inout: TRUE - user is writing; FALSE - user is reading
2881 *
2882 * Return the number of bytes read from or written to a
2883 * /proc/scsi/advansys/[0...] file.
2884 *
2885 * Note: This function uses the per board buffer 'prtbuf' which is
2886 * allocated when the board is initialized in advansys_detect(). The
2887 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
2888 * used to write to the buffer. The way asc_proc_copy() is written
2889 * if 'prtbuf' is too small it will not be overwritten. Instead the
2890 * user just won't get all the available statistics.
2891 */
70c8d897 2892static int
1da177e4 2893advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 2894 off_t offset, int length, int inout)
1da177e4 2895{
27c868c2 2896 asc_board_t *boardp;
27c868c2
MW
2897 char *cp;
2898 int cplen;
2899 int cnt;
2900 int totcnt;
2901 int leftlen;
2902 char *curbuf;
2903 off_t advoffset;
1da177e4 2904
27c868c2 2905 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 2906
27c868c2
MW
2907 /*
2908 * User write not supported.
2909 */
2910 if (inout == TRUE) {
2911 return (-ENOSYS);
2912 }
1da177e4 2913
27c868c2
MW
2914 /*
2915 * User read of /proc/scsi/advansys/[0...] file.
2916 */
1da177e4 2917
2a437959 2918 boardp = ASC_BOARDP(shost);
27c868c2
MW
2919
2920 /* Copy read data starting at the beginning of the buffer. */
2921 *start = buffer;
2922 curbuf = buffer;
2923 advoffset = 0;
2924 totcnt = 0;
2925 leftlen = length;
2926
2927 /*
2928 * Get board configuration information.
2929 *
2930 * advansys_info() returns the board string from its own static buffer.
2931 */
2a437959 2932 cp = (char *)advansys_info(shost);
27c868c2
MW
2933 strcat(cp, "\n");
2934 cplen = strlen(cp);
2935 /* Copy board information. */
2936 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2937 totcnt += cnt;
2938 leftlen -= cnt;
2939 if (leftlen == 0) {
2940 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2941 return totcnt;
2942 }
2943 advoffset += cplen;
2944 curbuf += cnt;
2945
2946 /*
2947 * Display Wide Board BIOS Information.
2948 */
2949 if (ASC_WIDE_BOARD(boardp)) {
2950 cp = boardp->prtbuf;
2a437959 2951 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2952 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
ecec1947 2953 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
27c868c2
MW
2954 cplen);
2955 totcnt += cnt;
2956 leftlen -= cnt;
2957 if (leftlen == 0) {
2958 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2959 return totcnt;
2960 }
2961 advoffset += cplen;
2962 curbuf += cnt;
2963 }
1da177e4 2964
27c868c2
MW
2965 /*
2966 * Display driver information for each device attached to the board.
2967 */
2968 cp = boardp->prtbuf;
2a437959 2969 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
2970 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
2971 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2972 totcnt += cnt;
2973 leftlen -= cnt;
2974 if (leftlen == 0) {
2975 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2976 return totcnt;
2977 }
2978 advoffset += cplen;
2979 curbuf += cnt;
2980
2981 /*
2982 * Display EEPROM configuration for the board.
2983 */
2984 cp = boardp->prtbuf;
2985 if (ASC_NARROW_BOARD(boardp)) {
2a437959 2986 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2987 } else {
2a437959 2988 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
2989 }
2990 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
2991 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2992 totcnt += cnt;
2993 leftlen -= cnt;
2994 if (leftlen == 0) {
2995 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2996 return totcnt;
2997 }
2998 advoffset += cplen;
2999 curbuf += cnt;
3000
3001 /*
3002 * Display driver configuration and information for the board.
3003 */
3004 cp = boardp->prtbuf;
2a437959 3005 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3006 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3007 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3008 totcnt += cnt;
3009 leftlen -= cnt;
3010 if (leftlen == 0) {
3011 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3012 return totcnt;
3013 }
3014 advoffset += cplen;
3015 curbuf += cnt;
1da177e4
LT
3016
3017#ifdef ADVANSYS_STATS
27c868c2
MW
3018 /*
3019 * Display driver statistics for the board.
3020 */
3021 cp = boardp->prtbuf;
2a437959 3022 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3023 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3024 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3025 totcnt += cnt;
3026 leftlen -= cnt;
3027 if (leftlen == 0) {
3028 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3029 return totcnt;
3030 }
3031 advoffset += cplen;
3032 curbuf += cnt;
1da177e4
LT
3033#endif /* ADVANSYS_STATS */
3034
27c868c2
MW
3035 /*
3036 * Display Asc Library dynamic configuration information
3037 * for the board.
3038 */
3039 cp = boardp->prtbuf;
3040 if (ASC_NARROW_BOARD(boardp)) {
2a437959 3041 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3042 } else {
2a437959 3043 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3044 }
3045 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3046 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3047 totcnt += cnt;
3048 leftlen -= cnt;
3049 if (leftlen == 0) {
3050 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3051 return totcnt;
3052 }
3053 advoffset += cplen;
3054 curbuf += cnt;
1da177e4 3055
27c868c2 3056 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 3057
27c868c2 3058 return totcnt;
1da177e4 3059}
1da177e4 3060#endif /* CONFIG_PROC_FS */
1da177e4
LT
3061
3062/*
3063 * advansys_info()
3064 *
3065 * Return suitable for printing on the console with the argument
3066 * adapter's configuration information.
3067 *
3068 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3069 * otherwise the static 'info' array will be overrun.
3070 */
27c868c2 3071static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 3072{
27c868c2
MW
3073 static char info[ASC_INFO_SIZE];
3074 asc_board_t *boardp;
3075 ASC_DVC_VAR *asc_dvc_varp;
3076 ADV_DVC_VAR *adv_dvc_varp;
3077 char *busname;
27c868c2
MW
3078 char *widename = NULL;
3079
3080 boardp = ASC_BOARDP(shost);
3081 if (ASC_NARROW_BOARD(boardp)) {
3082 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3083 ASC_DBG(1, "advansys_info: begin\n");
3084 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3085 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3086 ASC_IS_ISAPNP) {
3087 busname = "ISA PnP";
3088 } else {
3089 busname = "ISA";
3090 }
27c868c2
MW
3091 sprintf(info,
3092 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3093 ASC_VERSION, busname,
3094 (ulong)shost->io_port,
4a2d31c8
MW
3095 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3096 shost->irq, shost->dma_channel);
27c868c2
MW
3097 } else {
3098 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3099 busname = "VL";
3100 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3101 busname = "EISA";
3102 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3103 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3104 == ASC_IS_PCI_ULTRA) {
3105 busname = "PCI Ultra";
3106 } else {
3107 busname = "PCI";
3108 }
3109 } else {
3110 busname = "?";
ecec1947
MW
3111 ASC_PRINT2("advansys_info: board %d: unknown "
3112 "bus type %d\n", boardp->id,
3113 asc_dvc_varp->bus_type);
27c868c2 3114 }
27c868c2
MW
3115 sprintf(info,
3116 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
ecec1947 3117 ASC_VERSION, busname, (ulong)shost->io_port,
4a2d31c8
MW
3118 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3119 shost->irq);
27c868c2
MW
3120 }
3121 } else {
3122 /*
3123 * Wide Adapter Information
3124 *
3125 * Memory-mapped I/O is used instead of I/O space to access
3126 * the adapter, but display the I/O Port range. The Memory
3127 * I/O address is displayed through the driver /proc file.
3128 */
3129 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3130 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
27c868c2
MW
3131 widename = "Ultra-Wide";
3132 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
27c868c2
MW
3133 widename = "Ultra2-Wide";
3134 } else {
27c868c2
MW
3135 widename = "Ultra3-Wide";
3136 }
3137 sprintf(info,
3138 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3139 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4a2d31c8 3140 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
27c868c2
MW
3141 }
3142 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
3143 ASC_DBG(1, "advansys_info: end\n");
3144 return info;
1da177e4
LT
3145}
3146
6ed1ef07
MW
3147static void asc_scsi_done(struct scsi_cmnd *scp)
3148{
3149 struct asc_board *boardp = ASC_BOARDP(scp->device->host);
3150
3151 if (scp->use_sg)
3152 dma_unmap_sg(boardp->dev,
3153 (struct scatterlist *)scp->request_buffer,
3154 scp->use_sg, scp->sc_data_direction);
3155 else if (scp->request_bufflen)
3156 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
3157 scp->request_bufflen, scp->sc_data_direction);
3158
3159 ASC_STATS(scp->device->host, done);
3160
3161 scp->scsi_done(scp);
3162}
3163
1da177e4
LT
3164/*
3165 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
3166 *
3167 * This function always returns 0. Command return status is saved
3168 * in the 'scp' result field.
3169 */
70c8d897 3170static int
b2a7a4ba 3171advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
1da177e4 3172{
b2a7a4ba
MW
3173 struct Scsi_Host *shost = scp->device->host;
3174 asc_board_t *boardp = ASC_BOARDP(shost);
3175 unsigned long flags;
b6622925 3176 int asc_res, result = 0;
1da177e4 3177
27c868c2 3178 ASC_STATS(shost, queuecommand);
b2a7a4ba 3179 scp->scsi_done = done;
1da177e4 3180
b2a7a4ba
MW
3181 /*
3182 * host_lock taken by mid-level prior to call, but need
3183 * to protect against own ISR
3184 */
27c868c2 3185 spin_lock_irqsave(&boardp->lock, flags);
b6622925 3186 asc_res = asc_execute_scsi_cmnd(scp);
b2a7a4ba
MW
3187 spin_unlock_irqrestore(&boardp->lock, flags);
3188
b6622925 3189 switch (asc_res) {
27c868c2
MW
3190 case ASC_NOERROR:
3191 break;
3192 case ASC_BUSY:
b6622925 3193 result = SCSI_MLQUEUE_HOST_BUSY;
27c868c2
MW
3194 break;
3195 case ASC_ERROR:
3196 default:
6ed1ef07 3197 asc_scsi_done(scp);
27c868c2
MW
3198 break;
3199 }
1da177e4 3200
b6622925 3201 return result;
1da177e4
LT
3202}
3203
3204/*
3205 * advansys_reset()
3206 *
3207 * Reset the bus associated with the command 'scp'.
3208 *
3209 * This function runs its own thread. Interrupts must be blocked but
3210 * sleeping is allowed and no locking other than for host structures is
3211 * required. Returns SUCCESS or FAILED.
3212 */
27c868c2 3213static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 3214{
27c868c2
MW
3215 struct Scsi_Host *shost;
3216 asc_board_t *boardp;
3217 ASC_DVC_VAR *asc_dvc_varp;
3218 ADV_DVC_VAR *adv_dvc_varp;
3219 ulong flags;
27c868c2
MW
3220 int status;
3221 int ret = SUCCESS;
3222
3223 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
3224
3225#ifdef ADVANSYS_STATS
27c868c2
MW
3226 if (scp->device->host != NULL) {
3227 ASC_STATS(scp->device->host, reset);
3228 }
1da177e4
LT
3229#endif /* ADVANSYS_STATS */
3230
27c868c2
MW
3231 if ((shost = scp->device->host) == NULL) {
3232 scp->result = HOST_BYTE(DID_ERROR);
3233 return FAILED;
3234 }
1da177e4 3235
27c868c2 3236 boardp = ASC_BOARDP(shost);
1da177e4 3237
27c868c2
MW
3238 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
3239 boardp->id);
3240 /*
3241 * Check for re-entrancy.
3242 */
1da177e4 3243 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
3244 if (boardp->flags & ASC_HOST_IN_RESET) {
3245 spin_unlock_irqrestore(&boardp->lock, flags);
3246 return FAILED;
3247 }
3248 boardp->flags |= ASC_HOST_IN_RESET;
3249 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3250
27c868c2
MW
3251 if (ASC_NARROW_BOARD(boardp)) {
3252 /*
3253 * Narrow Board
3254 */
3255 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 3256
27c868c2
MW
3257 /*
3258 * Reset the chip and SCSI bus.
3259 */
3260 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
3261 status = AscInitAsc1000Driver(asc_dvc_varp);
3262
3263 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
3264 if (asc_dvc_varp->err_code) {
ecec1947
MW
3265 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3266 "error: 0x%x\n", boardp->id,
3267 asc_dvc_varp->err_code);
27c868c2
MW
3268 ret = FAILED;
3269 } else if (status) {
ecec1947
MW
3270 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3271 "warning: 0x%x\n", boardp->id, status);
27c868c2 3272 } else {
ecec1947
MW
3273 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3274 "successful.\n", boardp->id);
27c868c2
MW
3275 }
3276
3277 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
3278 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 3279
27c868c2
MW
3280 } else {
3281 /*
3282 * Wide Board
3283 *
3284 * If the suggest reset bus flags are set, then reset the bus.
3285 * Otherwise only reset the device.
3286 */
3287 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 3288
27c868c2
MW
3289 /*
3290 * Reset the target's SCSI bus.
3291 */
3292 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
3293 switch (AdvResetChipAndSB(adv_dvc_varp)) {
3294 case ASC_TRUE:
ecec1947
MW
3295 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3296 "successful.\n", boardp->id);
27c868c2
MW
3297 break;
3298 case ASC_FALSE:
3299 default:
ecec1947
MW
3300 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3301 "error.\n", boardp->id);
27c868c2
MW
3302 ret = FAILED;
3303 break;
3304 }
3305 spin_lock_irqsave(&boardp->lock, flags);
3306 (void)AdvISR(adv_dvc_varp);
3307 }
3308 /* Board lock is held. */
3309
27c868c2
MW
3310 /* Save the time of the most recently completed reset. */
3311 boardp->last_reset = jiffies;
1da177e4 3312
27c868c2
MW
3313 /* Clear reset flag. */
3314 boardp->flags &= ~ASC_HOST_IN_RESET;
3315 spin_unlock_irqrestore(&boardp->lock, flags);
3316
27c868c2 3317 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 3318
27c868c2 3319 return ret;
1da177e4
LT
3320}
3321
3322/*
3323 * advansys_biosparam()
3324 *
3325 * Translate disk drive geometry if the "BIOS greater than 1 GB"
3326 * support is enabled for a drive.
3327 *
3328 * ip (information pointer) is an int array with the following definition:
3329 * ip[0]: heads
3330 * ip[1]: sectors
3331 * ip[2]: cylinders
3332 */
70c8d897 3333static int
1da177e4 3334advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 3335 sector_t capacity, int ip[])
1da177e4 3336{
27c868c2
MW
3337 asc_board_t *boardp;
3338
3339 ASC_DBG(1, "advansys_biosparam: begin\n");
3340 ASC_STATS(sdev->host, biosparam);
3341 boardp = ASC_BOARDP(sdev->host);
3342 if (ASC_NARROW_BOARD(boardp)) {
3343 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
3344 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
3345 ip[0] = 255;
3346 ip[1] = 63;
3347 } else {
3348 ip[0] = 64;
3349 ip[1] = 32;
3350 }
3351 } else {
3352 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
3353 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
3354 ip[0] = 255;
3355 ip[1] = 63;
3356 } else {
3357 ip[0] = 64;
3358 ip[1] = 32;
3359 }
3360 }
3361 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
3362 ASC_DBG(1, "advansys_biosparam: end\n");
3363 return 0;
1da177e4
LT
3364}
3365
8dfb5379 3366static struct scsi_host_template advansys_template = {
27c868c2 3367 .proc_name = "advansys",
1da177e4 3368#ifdef CONFIG_PROC_FS
27c868c2 3369 .proc_info = advansys_proc_info,
1da177e4 3370#endif
27c868c2 3371 .name = "advansys",
27c868c2
MW
3372 .info = advansys_info,
3373 .queuecommand = advansys_queuecommand,
3374 .eh_bus_reset_handler = advansys_reset,
3375 .bios_param = advansys_biosparam,
3376 .slave_configure = advansys_slave_configure,
3377 /*
3378 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
8dfb5379
MW
3379 * must be set. The flag will be cleared in advansys_board_found
3380 * for non-ISA adapters.
27c868c2
MW
3381 */
3382 .unchecked_isa_dma = 1,
3383 /*
3384 * All adapters controlled by this driver are capable of large
3385 * scatter-gather lists. According to the mid-level SCSI documentation
3386 * this obviates any performance gain provided by setting
3387 * 'use_clustering'. But empirically while CPU utilization is increased
3388 * by enabling clustering, I/O throughput increases as well.
3389 */
3390 .use_clustering = ENABLE_CLUSTERING,
1da177e4 3391};
1da177e4 3392
1da177e4
LT
3393/*
3394 * --- Miscellaneous Driver Functions
3395 */
3396
3397/*
3398 * First-level interrupt handler.
3399 *
3400 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
3401 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
3402 * is not referenced. 'dev_id' could be used to identify an interrupt passed
3403 * to the AdvanSys driver which is for a device sharing an interrupt with
3404 * an AdvanSys adapter.
3405 */
27c868c2 3406static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 3407{
074c8fe4 3408 unsigned long flags;
074c8fe4
MW
3409 struct Scsi_Host *shost = dev_id;
3410 asc_board_t *boardp = ASC_BOARDP(shost);
3411 irqreturn_t result = IRQ_NONE;
27c868c2 3412
074c8fe4
MW
3413 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
3414 spin_lock_irqsave(&boardp->lock, flags);
3415 if (ASC_NARROW_BOARD(boardp)) {
3416 /*
3417 * Narrow Board
3418 */
3419 if (AscIsIntPending(shost->io_port)) {
3420 result = IRQ_HANDLED;
3421 ASC_STATS(shost, interrupt);
3422 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
3423 AscISR(&boardp->dvc_var.asc_dvc_var);
3424 }
3425 } else {
3426 /*
3427 * Wide Board
3428 */
3429 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
3430 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
3431 result = IRQ_HANDLED;
3432 ASC_STATS(shost, interrupt);
3433 }
3434 }
27c868c2 3435
074c8fe4 3436 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3437
27c868c2
MW
3438 /*
3439 * If interrupts were enabled on entry, then they
3440 * are now enabled here.
27c868c2 3441 */
1da177e4 3442
27c868c2 3443 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 3444 return result;
1da177e4
LT
3445}
3446
47d853cc
MW
3447static void
3448advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
3449{
3450 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
3451 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
3452
3453 if (sdev->lun == 0) {
3454 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
3455 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
3456 asc_dvc->init_sdtr |= tid_bit;
3457 } else {
3458 asc_dvc->init_sdtr &= ~tid_bit;
3459 }
3460
3461 if (orig_init_sdtr != asc_dvc->init_sdtr)
3462 AscAsyncFix(asc_dvc, sdev);
3463 }
3464
3465 if (sdev->tagged_supported) {
3466 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
3467 if (sdev->lun == 0) {
3468 asc_dvc->cfg->can_tagged_qng |= tid_bit;
3469 asc_dvc->use_tagged_qng |= tid_bit;
3470 }
3471 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3472 asc_dvc->max_dvc_qng[sdev->id]);
3473 }
3474 } else {
3475 if (sdev->lun == 0) {
3476 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
3477 asc_dvc->use_tagged_qng &= ~tid_bit;
3478 }
3479 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
3480 }
3481
3482 if ((sdev->lun == 0) &&
3483 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
3484 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
3485 asc_dvc->cfg->disc_enable);
3486 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
3487 asc_dvc->use_tagged_qng);
3488 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
3489 asc_dvc->cfg->can_tagged_qng);
3490
3491 asc_dvc->max_dvc_qng[sdev->id] =
3492 asc_dvc->cfg->max_tag_qng[sdev->id];
3493 AscWriteLramByte(asc_dvc->iop_base,
3494 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
3495 asc_dvc->max_dvc_qng[sdev->id]);
3496 }
3497}
3498
1da177e4 3499/*
47d853cc
MW
3500 * Wide Transfers
3501 *
3502 * If the EEPROM enabled WDTR for the device and the device supports wide
3503 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
3504 * write the new value to the microcode.
1da177e4 3505 */
47d853cc
MW
3506static void
3507advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
1da177e4 3508{
47d853cc
MW
3509 unsigned short cfg_word;
3510 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
3511 if ((cfg_word & tidmask) != 0)
3512 return;
3513
3514 cfg_word |= tidmask;
3515 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
1da177e4 3516
27c868c2 3517 /*
47d853cc
MW
3518 * Clear the microcode SDTR and WDTR negotiation done indicators for
3519 * the target to cause it to negotiate with the new setting set above.
3520 * WDTR when accepted causes the target to enter asynchronous mode, so
3521 * SDTR must be negotiated.
27c868c2 3522 */
47d853cc
MW
3523 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3524 cfg_word &= ~tidmask;
3525 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3526 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3527 cfg_word &= ~tidmask;
3528 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3529}
3530
3531/*
3532 * Synchronous Transfers
3533 *
3534 * If the EEPROM enabled SDTR for the device and the device
3535 * supports synchronous transfers, then turn on the device's
3536 * 'sdtr_able' bit. Write the new value to the microcode.
3537 */
3538static void
3539advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
3540{
3541 unsigned short cfg_word;
3542 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3543 if ((cfg_word & tidmask) != 0)
3544 return;
3545
3546 cfg_word |= tidmask;
3547 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3548
3549 /*
3550 * Clear the microcode "SDTR negotiation" done indicator for the
3551 * target to cause it to negotiate with the new setting set above.
3552 */
3553 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3554 cfg_word &= ~tidmask;
3555 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3556}
3557
3558/*
3559 * PPR (Parallel Protocol Request) Capable
3560 *
3561 * If the device supports DT mode, then it must be PPR capable.
3562 * The PPR message will be used in place of the SDTR and WDTR
3563 * messages to negotiate synchronous speed and offset, transfer
3564 * width, and protocol options.
3565 */
3566static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
3567 AdvPortAddr iop_base, unsigned short tidmask)
3568{
3569 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3570 adv_dvc->ppr_able |= tidmask;
3571 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3572}
3573
3574static void
3575advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
3576{
3577 AdvPortAddr iop_base = adv_dvc->iop_base;
3578 unsigned short tidmask = 1 << sdev->id;
3579
3580 if (sdev->lun == 0) {
3581 /*
3582 * Handle WDTR, SDTR, and Tag Queuing. If the feature
3583 * is enabled in the EEPROM and the device supports the
3584 * feature, then enable it in the microcode.
3585 */
3586
3587 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
3588 advansys_wide_enable_wdtr(iop_base, tidmask);
3589 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
3590 advansys_wide_enable_sdtr(iop_base, tidmask);
3591 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
3592 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
3593
3594 /*
3595 * Tag Queuing is disabled for the BIOS which runs in polled
3596 * mode and would see no benefit from Tag Queuing. Also by
3597 * disabling Tag Queuing in the BIOS devices with Tag Queuing
3598 * bugs will at least work with the BIOS.
3599 */
3600 if ((adv_dvc->tagqng_able & tidmask) &&
3601 sdev->tagged_supported) {
3602 unsigned short cfg_word;
3603 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
3604 cfg_word |= tidmask;
3605 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
3606 cfg_word);
3607 AdvWriteByteLram(iop_base,
3608 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
3609 adv_dvc->max_dvc_qng);
27c868c2 3610 }
47d853cc
MW
3611 }
3612
3613 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
3614 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3615 adv_dvc->max_dvc_qng);
27c868c2 3616 } else {
47d853cc 3617 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
27c868c2 3618 }
47d853cc
MW
3619}
3620
3621/*
3622 * Set the number of commands to queue per device for the
3623 * specified host adapter.
3624 */
3625static int advansys_slave_configure(struct scsi_device *sdev)
3626{
3627 asc_board_t *boardp = ASC_BOARDP(sdev->host);
3628 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
3629
3630 /*
3631 * Save a pointer to the sdev and set its initial/maximum
3632 * queue depth. Only save the pointer for a lun0 dev though.
3633 */
3634 if (sdev->lun == 0)
3635 boardp->device[sdev->id] = sdev;
3636
3637 if (ASC_NARROW_BOARD(boardp))
3638 advansys_narrow_slave_configure(sdev,
3639 &boardp->dvc_var.asc_dvc_var);
3640 else
3641 advansys_wide_slave_configure(sdev,
3642 &boardp->dvc_var.adv_dvc_var);
3643
27c868c2 3644 return 0;
1da177e4
LT
3645}
3646
1da177e4
LT
3647/*
3648 * Execute a single 'Scsi_Cmnd'.
3649 *
3650 * The function 'done' is called when the request has been completed.
3651 *
3652 * Scsi_Cmnd:
3653 *
3654 * host - board controlling device
3655 * device - device to send command
3656 * target - target of device
3657 * lun - lun of device
3658 * cmd_len - length of SCSI CDB
3659 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
3660 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
3661 *
3662 * if (use_sg == 0) {
3663 * request_buffer - buffer address for request
3664 * request_bufflen - length of request buffer
3665 * } else {
3666 * request_buffer - pointer to scatterlist structure
3667 * }
3668 *
3669 * sense_buffer - sense command buffer
3670 *
3671 * result (4 bytes of an int):
3672 * Byte Meaning
3673 * 0 SCSI Status Byte Code
3674 * 1 SCSI One Byte Message Code
3675 * 2 Host Error Code
3676 * 3 Mid-Level Error Code
3677 *
3678 * host driver fields:
3679 * SCp - Scsi_Pointer used for command processing status
3680 * scsi_done - used to save caller's done function
3681 * host_scribble - used for pointer to another struct scsi_cmnd
3682 *
349d2c44
MW
3683 * If this function returns ASC_NOERROR the request will be completed
3684 * from the interrupt handler.
1da177e4 3685 *
6ed1ef07
MW
3686 * If this function returns ASC_ERROR the host error code has been set,
3687 * and the called must call asc_scsi_done.
1da177e4 3688 *
b6622925
MW
3689 * If ASC_BUSY is returned the request will be returned to the midlayer
3690 * and re-tried later.
1da177e4 3691 */
27c868c2 3692static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 3693{
27c868c2
MW
3694 asc_board_t *boardp;
3695 ASC_DVC_VAR *asc_dvc_varp;
3696 ADV_DVC_VAR *adv_dvc_varp;
3697 ADV_SCSI_REQ_Q *adv_scsiqp;
3698 struct scsi_device *device;
3699 int ret;
3700
3701 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
3702 (ulong)scp, (ulong)scp->scsi_done);
3703
3704 boardp = ASC_BOARDP(scp->device->host);
3705 device = boardp->device[scp->device->id];
3706
3707 if (ASC_NARROW_BOARD(boardp)) {
3708 /*
3709 * Build and execute Narrow Board request.
3710 */
3711
3712 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3713
3714 /*
3715 * Build Asc Library request structure using the
3716 * global structures 'asc_scsi_req' and 'asc_sg_head'.
3717 *
3718 * If an error is returned, then the request has been
3719 * queued on the board done queue. It will be completed
3720 * by the caller.
3721 *
3722 * asc_build_req() can not return ASC_BUSY.
3723 */
3724 if (asc_build_req(boardp, scp) == ASC_ERROR) {
3725 ASC_STATS(scp->device->host, build_error);
3726 return ASC_ERROR;
3727 }
3728
27c868c2
MW
3729 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
3730 case ASC_NOERROR:
3731 ASC_STATS(scp->device->host, exe_noerror);
3732 /*
ecec1947
MW
3733 * Increment monotonically increasing per device
3734 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
3735 */
3736 boardp->reqcnt[scp->device->id]++;
ecec1947
MW
3737 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
3738 "ASC_NOERROR\n");
27c868c2
MW
3739 break;
3740 case ASC_BUSY:
27c868c2
MW
3741 ASC_STATS(scp->device->host, exe_busy);
3742 break;
3743 case ASC_ERROR:
ecec1947
MW
3744 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3745 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
3746 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3747 ASC_STATS(scp->device->host, exe_error);
3748 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3749 break;
3750 default:
ecec1947
MW
3751 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3752 "AscExeScsiQueue() unknown, err_code 0x%x\n",
3753 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3754 ASC_STATS(scp->device->host, exe_unknown);
3755 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3756 break;
3757 }
3758 } else {
3759 /*
3760 * Build and execute Wide Board request.
3761 */
3762 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3763
3764 /*
3765 * Build and get a pointer to an Adv Library request structure.
3766 *
3767 * If the request is successfully built then send it below,
3768 * otherwise return with an error.
3769 */
3770 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
3771 case ASC_NOERROR:
ecec1947
MW
3772 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
3773 "ASC_NOERROR\n");
27c868c2
MW
3774 break;
3775 case ASC_BUSY:
ecec1947
MW
3776 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
3777 "ASC_BUSY\n");
27c868c2 3778 /*
ecec1947
MW
3779 * The asc_stats fields 'adv_build_noreq' and
3780 * 'adv_build_nosg' count wide board busy conditions.
3781 * They are updated in adv_build_req and
3782 * adv_get_sglist, respectively.
27c868c2
MW
3783 */
3784 return ASC_BUSY;
3785 case ASC_ERROR:
27c868c2 3786 default:
ecec1947
MW
3787 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
3788 "ASC_ERROR\n");
27c868c2
MW
3789 ASC_STATS(scp->device->host, build_error);
3790 return ASC_ERROR;
3791 }
1da177e4 3792
27c868c2
MW
3793 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
3794 case ASC_NOERROR:
3795 ASC_STATS(scp->device->host, exe_noerror);
3796 /*
ecec1947
MW
3797 * Increment monotonically increasing per device
3798 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
3799 */
3800 boardp->reqcnt[scp->device->id]++;
ecec1947
MW
3801 ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
3802 "ASC_NOERROR\n");
27c868c2
MW
3803 break;
3804 case ASC_BUSY:
27c868c2
MW
3805 ASC_STATS(scp->device->host, exe_busy);
3806 break;
3807 case ASC_ERROR:
ecec1947
MW
3808 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3809 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
3810 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
3811 ASC_STATS(scp->device->host, exe_error);
3812 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3813 break;
3814 default:
ecec1947
MW
3815 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3816 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
3817 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
3818 ASC_STATS(scp->device->host, exe_unknown);
3819 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3820 break;
3821 }
3822 }
3823
3824 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
3825 return ret;
1da177e4
LT
3826}
3827
3828/*
3829 * Build a request structure for the Asc Library (Narrow Board).
3830 *
3831 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
3832 * used to build the request.
3833 *
6ed1ef07 3834 * If an error occurs, then return ASC_ERROR.
1da177e4 3835 */
27c868c2 3836static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 3837{
27c868c2
MW
3838 /*
3839 * Mutually exclusive access is required to 'asc_scsi_q' and
3840 * 'asc_sg_head' until after the request is started.
3841 */
3842 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
3843
3844 /*
3845 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
3846 */
3847 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
3848
3849 /*
3850 * Build the ASC_SCSI_Q request.
27c868c2 3851 */
27c868c2
MW
3852 asc_scsi_q.cdbptr = &scp->cmnd[0];
3853 asc_scsi_q.q2.cdb_len = scp->cmd_len;
3854 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
3855 asc_scsi_q.q1.target_lun = scp->device->lun;
3856 asc_scsi_q.q2.target_ix =
3857 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
3858 asc_scsi_q.q1.sense_addr =
3859 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
3860 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
3861
3862 /*
3863 * If there are any outstanding requests for the current target,
3864 * then every 255th request send an ORDERED request. This heuristic
3865 * tries to retain the benefit of request sorting while preventing
3866 * request starvation. 255 is the max number of tags or pending commands
3867 * a device may have outstanding.
3868 *
3869 * The request count is incremented below for every successfully
3870 * started request.
3871 *
3872 */
3873 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
3874 (boardp->reqcnt[scp->device->id] % 255) == 0) {
3875 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
3876 } else {
3877 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
3878 }
1da177e4 3879
27c868c2
MW
3880 /*
3881 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
3882 * buffer command.
3883 */
3884 if (scp->use_sg == 0) {
3885 /*
3886 * CDB request of single contiguous buffer.
3887 */
3888 ASC_STATS(scp->device->host, cont_cnt);
3889 scp->SCp.dma_handle = scp->request_bufflen ?
394dbf3f 3890 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
3891 scp->request_bufflen,
3892 scp->sc_data_direction) : 0;
3893 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
3894 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
3895 ASC_STATS_ADD(scp->device->host, cont_xfer,
3896 ASC_CEILING(scp->request_bufflen, 512));
3897 asc_scsi_q.q1.sg_queue_cnt = 0;
3898 asc_scsi_q.sg_head = NULL;
3899 } else {
3900 /*
3901 * CDB scatter-gather request list.
3902 */
3903 int sgcnt;
3904 int use_sg;
3905 struct scatterlist *slp;
3906
3907 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
3908 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
3909 scp->sc_data_direction);
27c868c2
MW
3910
3911 if (use_sg > scp->device->host->sg_tablesize) {
394dbf3f
MW
3912 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
3913 "sg_tablesize %d\n", boardp->id, use_sg,
3914 scp->device->host->sg_tablesize);
3915 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
3916 scp->sc_data_direction);
3917 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3918 return ASC_ERROR;
3919 }
3920
3921 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 3922
27c868c2
MW
3923 /*
3924 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
3925 * structure to point to it.
3926 */
3927 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
3928
3929 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
3930 asc_scsi_q.sg_head = &asc_sg_head;
3931 asc_scsi_q.q1.data_cnt = 0;
3932 asc_scsi_q.q1.data_addr = 0;
3933 /* This is a byte value, otherwise it would need to be swapped. */
3934 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
3935 ASC_STATS_ADD(scp->device->host, sg_elem,
3936 asc_sg_head.entry_cnt);
1da177e4 3937
27c868c2
MW
3938 /*
3939 * Convert scatter-gather list into ASC_SG_HEAD list.
3940 */
3941 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
3942 asc_sg_head.sg_list[sgcnt].addr =
3943 cpu_to_le32(sg_dma_address(slp));
3944 asc_sg_head.sg_list[sgcnt].bytes =
3945 cpu_to_le32(sg_dma_len(slp));
3946 ASC_STATS_ADD(scp->device->host, sg_xfer,
3947 ASC_CEILING(sg_dma_len(slp), 512));
3948 }
3949 }
1da177e4 3950
27c868c2
MW
3951 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
3952 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 3953
27c868c2 3954 return ASC_NOERROR;
1da177e4
LT
3955}
3956
3957/*
3958 * Build a request structure for the Adv Library (Wide Board).
3959 *
3960 * If an adv_req_t can not be allocated to issue the request,
3961 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
3962 *
3963 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
3964 * microcode for DMA addresses or math operations are byte swapped
3965 * to little-endian order.
3966 */
27c868c2 3967static int
1da177e4 3968adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 3969 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 3970{
27c868c2
MW
3971 adv_req_t *reqp;
3972 ADV_SCSI_REQ_Q *scsiqp;
3973 int i;
3974 int ret;
27c868c2
MW
3975
3976 /*
3977 * Allocate an adv_req_t structure from the board to execute
3978 * the command.
3979 */
3980 if (boardp->adv_reqp == NULL) {
3981 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
3982 ASC_STATS(scp->device->host, adv_build_noreq);
3983 return ASC_BUSY;
3984 } else {
3985 reqp = boardp->adv_reqp;
3986 boardp->adv_reqp = reqp->next_reqp;
3987 reqp->next_reqp = NULL;
3988 }
1da177e4 3989
27c868c2
MW
3990 /*
3991 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
3992 */
3993 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
3994
3995 /*
3996 * Initialize the structure.
3997 */
3998 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
3999
4000 /*
4001 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
4002 */
4003 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
4004
4005 /*
4006 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
4007 */
4008 reqp->cmndp = scp;
4009
4010 /*
4011 * Build the ADV_SCSI_REQ_Q request.
4012 */
4013
f05ec594 4014 /* Set CDB length and copy it to the request structure. */
27c868c2
MW
4015 scsiqp->cdb_len = scp->cmd_len;
4016 /* Copy first 12 CDB bytes to cdb[]. */
4017 for (i = 0; i < scp->cmd_len && i < 12; i++) {
4018 scsiqp->cdb[i] = scp->cmnd[i];
4019 }
4020 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
4021 for (; i < scp->cmd_len; i++) {
4022 scsiqp->cdb16[i - 12] = scp->cmnd[i];
4023 }
1da177e4 4024
27c868c2
MW
4025 scsiqp->target_id = scp->device->id;
4026 scsiqp->target_lun = scp->device->lun;
1da177e4 4027
27c868c2
MW
4028 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4029 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 4030
27c868c2
MW
4031 /*
4032 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
4033 * buffer command.
4034 */
1da177e4 4035
1da177e4 4036 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
4037 scsiqp->vdata_addr = scp->request_buffer;
4038 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 4039
27c868c2
MW
4040 if (scp->use_sg == 0) {
4041 /*
4042 * CDB request of single contiguous buffer.
4043 */
4044 reqp->sgblkp = NULL;
4045 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
4046 if (scp->request_bufflen) {
4047 scsiqp->vdata_addr = scp->request_buffer;
4048 scp->SCp.dma_handle =
394dbf3f 4049 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
4050 scp->request_bufflen,
4051 scp->sc_data_direction);
4052 } else {
4053 scsiqp->vdata_addr = NULL;
4054 scp->SCp.dma_handle = 0;
4055 }
4056 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
4057 scsiqp->sg_list_ptr = NULL;
4058 scsiqp->sg_real_addr = 0;
4059 ASC_STATS(scp->device->host, cont_cnt);
4060 ASC_STATS_ADD(scp->device->host, cont_xfer,
4061 ASC_CEILING(scp->request_bufflen, 512));
4062 } else {
4063 /*
4064 * CDB scatter-gather request list.
4065 */
4066 struct scatterlist *slp;
4067 int use_sg;
4068
4069 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
4070 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4071 scp->sc_data_direction);
27c868c2
MW
4072
4073 if (use_sg > ADV_MAX_SG_LIST) {
394dbf3f
MW
4074 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
4075 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
4076 scp->device->host->sg_tablesize);
4077 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
4078 scp->sc_data_direction);
4079 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
4080
4081 /*
394dbf3f
MW
4082 * Free the 'adv_req_t' structure by adding it back
4083 * to the board free list.
27c868c2
MW
4084 */
4085 reqp->next_reqp = boardp->adv_reqp;
4086 boardp->adv_reqp = reqp;
4087
4088 return ASC_ERROR;
4089 }
4090
394dbf3f
MW
4091 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
4092 if (ret != ADV_SUCCESS) {
27c868c2 4093 /*
394dbf3f
MW
4094 * Free the adv_req_t structure by adding it back to
4095 * the board free list.
27c868c2
MW
4096 */
4097 reqp->next_reqp = boardp->adv_reqp;
4098 boardp->adv_reqp = reqp;
4099
4100 return ret;
4101 }
4102
4103 ASC_STATS(scp->device->host, sg_cnt);
4104 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
4105 }
1da177e4 4106
27c868c2
MW
4107 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4108 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 4109
27c868c2 4110 *adv_scsiqpp = scsiqp;
1da177e4 4111
27c868c2 4112 return ASC_NOERROR;
1da177e4
LT
4113}
4114
4115/*
4116 * Build scatter-gather list for Adv Library (Wide Board).
4117 *
4118 * Additional ADV_SG_BLOCK structures will need to be allocated
4119 * if the total number of scatter-gather elements exceeds
4120 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
4121 * assumed to be physically contiguous.
4122 *
4123 * Return:
4124 * ADV_SUCCESS(1) - SG List successfully created
4125 * ADV_ERROR(-1) - SG List creation failed
4126 */
27c868c2
MW
4127static int
4128adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
4129 int use_sg)
1da177e4 4130{
27c868c2
MW
4131 adv_sgblk_t *sgblkp;
4132 ADV_SCSI_REQ_Q *scsiqp;
4133 struct scatterlist *slp;
4134 int sg_elem_cnt;
4135 ADV_SG_BLOCK *sg_block, *prev_sg_block;
4136 ADV_PADDR sg_block_paddr;
4137 int i;
4138
4139 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
4140 slp = (struct scatterlist *)scp->request_buffer;
4141 sg_elem_cnt = use_sg;
4142 prev_sg_block = NULL;
4143 reqp->sgblkp = NULL;
4144
4145 do {
4146 /*
4147 * Allocate a 'adv_sgblk_t' structure from the board free
4148 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
4149 * (15) scatter-gather elements.
4150 */
4151 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
4152 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
4153 ASC_STATS(scp->device->host, adv_build_nosg);
4154
4155 /*
4156 * Allocation failed. Free 'adv_sgblk_t' structures already
4157 * allocated for the request.
4158 */
4159 while ((sgblkp = reqp->sgblkp) != NULL) {
4160 /* Remove 'sgblkp' from the request list. */
4161 reqp->sgblkp = sgblkp->next_sgblkp;
4162
4163 /* Add 'sgblkp' to the board free list. */
4164 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4165 boardp->adv_sgblkp = sgblkp;
4166 }
4167 return ASC_BUSY;
4168 } else {
4169 /* Complete 'adv_sgblk_t' board allocation. */
4170 boardp->adv_sgblkp = sgblkp->next_sgblkp;
4171 sgblkp->next_sgblkp = NULL;
4172
4173 /*
4174 * Get 8 byte aligned virtual and physical addresses for
4175 * the allocated ADV_SG_BLOCK structure.
4176 */
4177 sg_block =
4178 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
4179 sg_block_paddr = virt_to_bus(sg_block);
4180
4181 /*
4182 * Check if this is the first 'adv_sgblk_t' for the request.
4183 */
4184 if (reqp->sgblkp == NULL) {
4185 /* Request's first scatter-gather block. */
4186 reqp->sgblkp = sgblkp;
4187
4188 /*
4189 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
4190 * address pointers.
4191 */
4192 scsiqp->sg_list_ptr = sg_block;
4193 scsiqp->sg_real_addr =
4194 cpu_to_le32(sg_block_paddr);
4195 } else {
4196 /* Request's second or later scatter-gather block. */
4197 sgblkp->next_sgblkp = reqp->sgblkp;
4198 reqp->sgblkp = sgblkp;
4199
4200 /*
4201 * Point the previous ADV_SG_BLOCK structure to
4202 * the newly allocated ADV_SG_BLOCK structure.
4203 */
4204 ASC_ASSERT(prev_sg_block != NULL);
4205 prev_sg_block->sg_ptr =
4206 cpu_to_le32(sg_block_paddr);
4207 }
4208 }
4209
4210 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
4211 sg_block->sg_list[i].sg_addr =
4212 cpu_to_le32(sg_dma_address(slp));
4213 sg_block->sg_list[i].sg_count =
4214 cpu_to_le32(sg_dma_len(slp));
4215 ASC_STATS_ADD(scp->device->host, sg_xfer,
4216 ASC_CEILING(sg_dma_len(slp), 512));
4217
4218 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
4219 sg_block->sg_cnt = i + 1;
4220 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
4221 return ADV_SUCCESS;
4222 }
4223 slp++;
4224 }
4225 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
4226 prev_sg_block = sg_block;
4227 }
4228 while (1);
4229 /* NOTREACHED */
1da177e4
LT
4230}
4231
4232/*
4233 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
4234 *
4235 * Interrupt callback function for the Narrow SCSI Asc Library.
4236 */
27c868c2 4237static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 4238{
27c868c2
MW
4239 asc_board_t *boardp;
4240 struct scsi_cmnd *scp;
4241 struct Scsi_Host *shost;
27c868c2
MW
4242
4243 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
4244 (ulong)asc_dvc_varp, (ulong)qdonep);
4245 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
4246
4247 /*
4248 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4249 * command that has been completed.
4250 */
4251 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
4252 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
4253
4254 if (scp == NULL) {
4255 ASC_PRINT("asc_isr_callback: scp is NULL\n");
4256 return;
4257 }
4258 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4259
27c868c2 4260 shost = scp->device->host;
27c868c2
MW
4261 ASC_STATS(shost, callback);
4262 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
4263
27c868c2
MW
4264 boardp = ASC_BOARDP(shost);
4265 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
1da177e4 4266
27c868c2
MW
4267 /*
4268 * 'qdonep' contains the command's ending status.
4269 */
4270 switch (qdonep->d3.done_stat) {
4271 case QD_NO_ERROR:
4272 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
4273 scp->result = 0;
1da177e4 4274
27c868c2
MW
4275 /*
4276 * Check for an underrun condition.
4277 *
4278 * If there was no error and an underrun condition, then
47d853cc 4279 * return the number of underrun bytes.
27c868c2
MW
4280 */
4281 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
4282 qdonep->remain_bytes <= scp->request_bufflen) {
4283 ASC_DBG1(1,
4284 "asc_isr_callback: underrun condition %u bytes\n",
4285 (unsigned)qdonep->remain_bytes);
4286 scp->resid = qdonep->remain_bytes;
4287 }
4288 break;
4289
4290 case QD_WITH_ERROR:
4291 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
4292 switch (qdonep->d3.host_stat) {
4293 case QHSTA_NO_ERROR:
4294 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
4295 ASC_DBG(2,
4296 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4297 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4298 sizeof(scp->sense_buffer));
4299 /*
4300 * Note: The 'status_byte()' macro used by target drivers
4301 * defined in scsi.h shifts the status byte returned by
4302 * host drivers right by 1 bit. This is why target drivers
4303 * also use right shifted status byte definitions. For
4304 * instance target drivers use CHECK_CONDITION, defined to
4305 * 0x1, instead of the SCSI defined check condition value
4306 * of 0x2. Host drivers are supposed to return the status
4307 * byte as it is defined by SCSI.
4308 */
4309 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4310 STATUS_BYTE(qdonep->d3.scsi_stat);
4311 } else {
4312 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
4313 }
4314 break;
4315
4316 default:
4317 /* QHSTA error occurred */
4318 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
4319 qdonep->d3.host_stat);
4320 scp->result = HOST_BYTE(DID_BAD_TARGET);
4321 break;
4322 }
4323 break;
4324
4325 case QD_ABORTED_BY_HOST:
4326 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
4327 scp->result =
4328 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
4329 scsi_msg) |
4330 STATUS_BYTE(qdonep->d3.scsi_stat);
4331 break;
4332
4333 default:
4334 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
4335 qdonep->d3.done_stat);
4336 scp->result =
4337 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
4338 scsi_msg) |
4339 STATUS_BYTE(qdonep->d3.scsi_stat);
4340 break;
4341 }
1da177e4 4342
27c868c2
MW
4343 /*
4344 * If the 'init_tidmask' bit isn't already set for the target and the
4345 * current request finished normally, then set the bit for the target
4346 * to indicate that a device is present.
4347 */
4348 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4349 qdonep->d3.done_stat == QD_NO_ERROR &&
4350 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
4351 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4352 }
1da177e4 4353
6ed1ef07 4354 asc_scsi_done(scp);
1da177e4 4355
27c868c2 4356 return;
1da177e4
LT
4357}
4358
4359/*
4360 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
4361 *
4362 * Callback function for the Wide SCSI Adv Library.
4363 */
27c868c2 4364static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 4365{
27c868c2
MW
4366 asc_board_t *boardp;
4367 adv_req_t *reqp;
4368 adv_sgblk_t *sgblkp;
4369 struct scsi_cmnd *scp;
4370 struct Scsi_Host *shost;
27c868c2
MW
4371 ADV_DCNT resid_cnt;
4372
4373 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
4374 (ulong)adv_dvc_varp, (ulong)scsiqp);
4375 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4376
4377 /*
4378 * Get the adv_req_t structure for the command that has been
4379 * completed. The adv_req_t structure actually contains the
4380 * completed ADV_SCSI_REQ_Q structure.
4381 */
4382 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
4383 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
4384 if (reqp == NULL) {
4385 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
4386 return;
4387 }
1da177e4 4388
27c868c2
MW
4389 /*
4390 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4391 * command that has been completed.
4392 *
4393 * Note: The adv_req_t request structure and adv_sgblk_t structure,
4394 * if any, are dropped, because a board structure pointer can not be
4395 * determined.
4396 */
4397 scp = reqp->cmndp;
4398 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
4399 if (scp == NULL) {
4400 ASC_PRINT
4401 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
4402 return;
4403 }
4404 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4405
27c868c2 4406 shost = scp->device->host;
27c868c2
MW
4407 ASC_STATS(shost, callback);
4408 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
4409
27c868c2
MW
4410 boardp = ASC_BOARDP(shost);
4411 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
1da177e4 4412
27c868c2
MW
4413 /*
4414 * 'done_status' contains the command's ending status.
4415 */
4416 switch (scsiqp->done_status) {
4417 case QD_NO_ERROR:
4418 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
4419 scp->result = 0;
1da177e4 4420
27c868c2
MW
4421 /*
4422 * Check for an underrun condition.
4423 *
4424 * If there was no error and an underrun condition, then
4425 * then return the number of underrun bytes.
4426 */
4427 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
4428 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
4429 resid_cnt <= scp->request_bufflen) {
4430 ASC_DBG1(1,
4431 "adv_isr_callback: underrun condition %lu bytes\n",
4432 (ulong)resid_cnt);
4433 scp->resid = resid_cnt;
4434 }
4435 break;
4436
4437 case QD_WITH_ERROR:
4438 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
4439 switch (scsiqp->host_status) {
4440 case QHSTA_NO_ERROR:
4441 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
4442 ASC_DBG(2,
4443 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4444 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4445 sizeof(scp->sense_buffer));
4446 /*
4447 * Note: The 'status_byte()' macro used by target drivers
4448 * defined in scsi.h shifts the status byte returned by
4449 * host drivers right by 1 bit. This is why target drivers
4450 * also use right shifted status byte definitions. For
4451 * instance target drivers use CHECK_CONDITION, defined to
4452 * 0x1, instead of the SCSI defined check condition value
4453 * of 0x2. Host drivers are supposed to return the status
4454 * byte as it is defined by SCSI.
4455 */
4456 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4457 STATUS_BYTE(scsiqp->scsi_status);
4458 } else {
4459 scp->result = STATUS_BYTE(scsiqp->scsi_status);
4460 }
4461 break;
4462
4463 default:
4464 /* Some other QHSTA error occurred. */
4465 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
4466 scsiqp->host_status);
4467 scp->result = HOST_BYTE(DID_BAD_TARGET);
4468 break;
4469 }
4470 break;
4471
4472 case QD_ABORTED_BY_HOST:
4473 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
4474 scp->result =
4475 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
4476 break;
4477
4478 default:
4479 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
4480 scsiqp->done_status);
4481 scp->result =
4482 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
4483 break;
4484 }
1da177e4 4485
27c868c2
MW
4486 /*
4487 * If the 'init_tidmask' bit isn't already set for the target and the
4488 * current request finished normally, then set the bit for the target
4489 * to indicate that a device is present.
4490 */
4491 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4492 scsiqp->done_status == QD_NO_ERROR &&
4493 scsiqp->host_status == QHSTA_NO_ERROR) {
4494 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4495 }
1da177e4 4496
6ed1ef07 4497 asc_scsi_done(scp);
27c868c2
MW
4498
4499 /*
4500 * Free all 'adv_sgblk_t' structures allocated for the request.
4501 */
4502 while ((sgblkp = reqp->sgblkp) != NULL) {
4503 /* Remove 'sgblkp' from the request list. */
4504 reqp->sgblkp = sgblkp->next_sgblkp;
4505
4506 /* Add 'sgblkp' to the board free list. */
4507 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4508 boardp->adv_sgblkp = sgblkp;
4509 }
1da177e4 4510
27c868c2
MW
4511 /*
4512 * Free the adv_req_t structure used with the command by adding
4513 * it back to the board free list.
4514 */
4515 reqp->next_reqp = boardp->adv_reqp;
4516 boardp->adv_reqp = reqp;
1da177e4 4517
27c868c2 4518 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 4519
27c868c2 4520 return;
1da177e4
LT
4521}
4522
4523/*
4524 * adv_async_callback() - Adv Library asynchronous event callback function.
4525 */
27c868c2 4526static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 4527{
27c868c2
MW
4528 switch (code) {
4529 case ADV_ASYNC_SCSI_BUS_RESET_DET:
4530 /*
4531 * The firmware detected a SCSI Bus reset.
4532 */
4533 ASC_DBG(0,
4534 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
4535 break;
4536
4537 case ADV_ASYNC_RDMA_FAILURE:
4538 /*
4539 * Handle RDMA failure by resetting the SCSI Bus and
4540 * possibly the chip if it is unresponsive. Log the error
4541 * with a unique code.
4542 */
4543 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
4544 AdvResetChipAndSB(adv_dvc_varp);
4545 break;
4546
4547 case ADV_HOST_SCSI_BUS_RESET:
4548 /*
4549 * Host generated SCSI bus reset occurred.
4550 */
4551 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
4552 break;
4553
4554 default:
4555 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
4556 break;
4557 }
1da177e4
LT
4558}
4559
1da177e4
LT
4560#ifdef CONFIG_PROC_FS
4561/*
4562 * asc_prt_board_devices()
4563 *
4564 * Print driver information for devices attached to the board.
4565 *
4566 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4567 * cf. asc_prt_line().
4568 *
4569 * Return the number of characters copied into 'cp'. No more than
4570 * 'cplen' characters will be copied to 'cp'.
4571 */
27c868c2 4572static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4573{
27c868c2
MW
4574 asc_board_t *boardp;
4575 int leftlen;
4576 int totlen;
4577 int len;
4578 int chip_scsi_id;
4579 int i;
4580
4581 boardp = ASC_BOARDP(shost);
4582 leftlen = cplen;
4583 totlen = len = 0;
4584
4585 len = asc_prt_line(cp, leftlen,
4586 "\nDevice Information for AdvanSys SCSI Host %d:\n",
4587 shost->host_no);
4588 ASC_PRT_NEXT();
4589
4590 if (ASC_NARROW_BOARD(boardp)) {
4591 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
4592 } else {
4593 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
4594 }
1da177e4 4595
27c868c2
MW
4596 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
4597 ASC_PRT_NEXT();
4598 for (i = 0; i <= ADV_MAX_TID; i++) {
4599 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
4600 len = asc_prt_line(cp, leftlen, " %X,", i);
4601 ASC_PRT_NEXT();
4602 }
4603 }
4604 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
4605 ASC_PRT_NEXT();
1da177e4 4606
27c868c2 4607 return totlen;
1da177e4
LT
4608}
4609
4610/*
4611 * Display Wide Board BIOS Information.
4612 */
27c868c2 4613static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4614{
27c868c2
MW
4615 asc_board_t *boardp;
4616 int leftlen;
4617 int totlen;
4618 int len;
4619 ushort major, minor, letter;
4620
4621 boardp = ASC_BOARDP(shost);
4622 leftlen = cplen;
4623 totlen = len = 0;
4624
4625 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
4626 ASC_PRT_NEXT();
4627
4628 /*
4629 * If the BIOS saved a valid signature, then fill in
4630 * the BIOS code segment base address.
4631 */
4632 if (boardp->bios_signature != 0x55AA) {
4633 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
4634 ASC_PRT_NEXT();
4635 len = asc_prt_line(cp, leftlen,
4636 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
4637 ASC_PRT_NEXT();
4638 len = asc_prt_line(cp, leftlen,
4639 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
4640 ASC_PRT_NEXT();
4641 } else {
4642 major = (boardp->bios_version >> 12) & 0xF;
4643 minor = (boardp->bios_version >> 8) & 0xF;
4644 letter = (boardp->bios_version & 0xFF);
1da177e4 4645
27c868c2
MW
4646 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
4647 major, minor,
4648 letter >= 26 ? '?' : letter + 'A');
4649 ASC_PRT_NEXT();
1da177e4 4650
27c868c2
MW
4651 /*
4652 * Current available ROM BIOS release is 3.1I for UW
4653 * and 3.2I for U2W. This code doesn't differentiate
4654 * UW and U2W boards.
4655 */
4656 if (major < 3 || (major <= 3 && minor < 1) ||
4657 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
4658 len = asc_prt_line(cp, leftlen,
4659 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
4660 ASC_PRT_NEXT();
4661 len = asc_prt_line(cp, leftlen,
4662 "ftp://ftp.connectcom.net/pub\n");
4663 ASC_PRT_NEXT();
4664 }
4665 }
1da177e4 4666
27c868c2 4667 return totlen;
1da177e4
LT
4668}
4669
4670/*
4671 * Add serial number to information bar if signature AAh
4672 * is found in at bit 15-9 (7 bits) of word 1.
4673 *
4674 * Serial Number consists fo 12 alpha-numeric digits.
4675 *
4676 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
4677 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
4678 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
4679 * 5 - Product revision (A-J) Word0: " "
4680 *
4681 * Signature Word1: 15-9 (7 bits)
4682 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
4683 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
4684 *
4685 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
4686 *
4687 * Note 1: Only production cards will have a serial number.
4688 *
4689 * Note 2: Signature is most significant 7 bits (0xFE).
4690 *
4691 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
4692 */
27c868c2 4693static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 4694{
27c868c2
MW
4695 ushort w, num;
4696
4697 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
4698 return ASC_FALSE;
4699 } else {
4700 /*
4701 * First word - 6 digits.
4702 */
4703 w = serialnum[0];
4704
4705 /* Product type - 1st digit. */
4706 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
4707 /* Product type is P=Prototype */
4708 *cp += 0x8;
4709 }
4710 cp++;
4711
4712 /* Manufacturing location - 2nd digit. */
4713 *cp++ = 'A' + ((w & 0x1C00) >> 10);
4714
4715 /* Product ID - 3rd, 4th digits. */
4716 num = w & 0x3FF;
4717 *cp++ = '0' + (num / 100);
4718 num %= 100;
4719 *cp++ = '0' + (num / 10);
4720
4721 /* Product revision - 5th digit. */
4722 *cp++ = 'A' + (num % 10);
4723
4724 /*
4725 * Second word
4726 */
4727 w = serialnum[1];
4728
4729 /*
4730 * Year - 6th digit.
4731 *
4732 * If bit 15 of third word is set, then the
4733 * last digit of the year is greater than 7.
4734 */
4735 if (serialnum[2] & 0x8000) {
4736 *cp++ = '8' + ((w & 0x1C0) >> 6);
4737 } else {
4738 *cp++ = '0' + ((w & 0x1C0) >> 6);
4739 }
4740
4741 /* Week of year - 7th, 8th digits. */
4742 num = w & 0x003F;
4743 *cp++ = '0' + num / 10;
4744 num %= 10;
4745 *cp++ = '0' + num;
4746
4747 /*
4748 * Third word
4749 */
4750 w = serialnum[2] & 0x7FFF;
4751
4752 /* Serial number - 9th digit. */
4753 *cp++ = 'A' + (w / 1000);
4754
4755 /* 10th, 11th, 12th digits. */
4756 num = w % 1000;
4757 *cp++ = '0' + num / 100;
4758 num %= 100;
4759 *cp++ = '0' + num / 10;
4760 num %= 10;
4761 *cp++ = '0' + num;
4762
4763 *cp = '\0'; /* Null Terminate the string. */
4764 return ASC_TRUE;
4765 }
1da177e4
LT
4766}
4767
4768/*
4769 * asc_prt_asc_board_eeprom()
4770 *
4771 * Print board EEPROM configuration.
4772 *
4773 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4774 * cf. asc_prt_line().
4775 *
4776 * Return the number of characters copied into 'cp'. No more than
4777 * 'cplen' characters will be copied to 'cp'.
4778 */
27c868c2 4779static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4780{
27c868c2
MW
4781 asc_board_t *boardp;
4782 ASC_DVC_VAR *asc_dvc_varp;
4783 int leftlen;
4784 int totlen;
4785 int len;
4786 ASCEEP_CONFIG *ep;
4787 int i;
1da177e4 4788#ifdef CONFIG_ISA
27c868c2 4789 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 4790#endif /* CONFIG_ISA */
27c868c2
MW
4791 uchar serialstr[13];
4792
4793 boardp = ASC_BOARDP(shost);
4794 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4795 ep = &boardp->eep_config.asc_eep;
4796
4797 leftlen = cplen;
4798 totlen = len = 0;
4799
4800 len = asc_prt_line(cp, leftlen,
4801 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
4802 shost->host_no);
4803 ASC_PRT_NEXT();
4804
4805 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
4806 == ASC_TRUE) {
4807 len =
4808 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
4809 serialstr);
4810 ASC_PRT_NEXT();
4811 } else {
4812 if (ep->adapter_info[5] == 0xBB) {
4813 len = asc_prt_line(cp, leftlen,
4814 " Default Settings Used for EEPROM-less Adapter.\n");
4815 ASC_PRT_NEXT();
4816 } else {
4817 len = asc_prt_line(cp, leftlen,
4818 " Serial Number Signature Not Present.\n");
4819 ASC_PRT_NEXT();
4820 }
4821 }
1da177e4 4822
27c868c2
MW
4823 len = asc_prt_line(cp, leftlen,
4824 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4825 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
4826 ep->max_tag_qng);
4827 ASC_PRT_NEXT();
4828
4829 len = asc_prt_line(cp, leftlen,
4830 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
4831 ASC_PRT_NEXT();
4832
4833 len = asc_prt_line(cp, leftlen, " Target ID: ");
4834 ASC_PRT_NEXT();
4835 for (i = 0; i <= ASC_MAX_TID; i++) {
4836 len = asc_prt_line(cp, leftlen, " %d", i);
4837 ASC_PRT_NEXT();
4838 }
4839 len = asc_prt_line(cp, leftlen, "\n");
4840 ASC_PRT_NEXT();
4841
4842 len = asc_prt_line(cp, leftlen, " Disconnects: ");
4843 ASC_PRT_NEXT();
4844 for (i = 0; i <= ASC_MAX_TID; i++) {
4845 len = asc_prt_line(cp, leftlen, " %c",
4846 (ep->
4847 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4848 'N');
4849 ASC_PRT_NEXT();
4850 }
4851 len = asc_prt_line(cp, leftlen, "\n");
4852 ASC_PRT_NEXT();
4853
4854 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
4855 ASC_PRT_NEXT();
4856 for (i = 0; i <= ASC_MAX_TID; i++) {
4857 len = asc_prt_line(cp, leftlen, " %c",
4858 (ep->
4859 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4860 'N');
4861 ASC_PRT_NEXT();
4862 }
4863 len = asc_prt_line(cp, leftlen, "\n");
4864 ASC_PRT_NEXT();
4865
4866 len = asc_prt_line(cp, leftlen, " Start Motor: ");
4867 ASC_PRT_NEXT();
4868 for (i = 0; i <= ASC_MAX_TID; i++) {
4869 len = asc_prt_line(cp, leftlen, " %c",
4870 (ep->
4871 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4872 'N');
4873 ASC_PRT_NEXT();
4874 }
4875 len = asc_prt_line(cp, leftlen, "\n");
4876 ASC_PRT_NEXT();
4877
4878 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
4879 ASC_PRT_NEXT();
4880 for (i = 0; i <= ASC_MAX_TID; i++) {
4881 len = asc_prt_line(cp, leftlen, " %c",
4882 (ep->
4883 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4884 'N');
4885 ASC_PRT_NEXT();
4886 }
4887 len = asc_prt_line(cp, leftlen, "\n");
4888 ASC_PRT_NEXT();
1da177e4
LT
4889
4890#ifdef CONFIG_ISA
27c868c2
MW
4891 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4892 len = asc_prt_line(cp, leftlen,
4893 " Host ISA DMA speed: %d MB/S\n",
4894 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
4895 ASC_PRT_NEXT();
4896 }
1da177e4
LT
4897#endif /* CONFIG_ISA */
4898
27c868c2 4899 return totlen;
1da177e4
LT
4900}
4901
4902/*
4903 * asc_prt_adv_board_eeprom()
4904 *
4905 * Print board EEPROM configuration.
4906 *
4907 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4908 * cf. asc_prt_line().
4909 *
4910 * Return the number of characters copied into 'cp'. No more than
4911 * 'cplen' characters will be copied to 'cp'.
4912 */
27c868c2 4913static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4914{
27c868c2
MW
4915 asc_board_t *boardp;
4916 ADV_DVC_VAR *adv_dvc_varp;
4917 int leftlen;
4918 int totlen;
4919 int len;
4920 int i;
4921 char *termstr;
4922 uchar serialstr[13];
4923 ADVEEP_3550_CONFIG *ep_3550 = NULL;
4924 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
4925 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
4926 ushort word;
4927 ushort *wordp;
4928 ushort sdtr_speed = 0;
4929
4930 boardp = ASC_BOARDP(shost);
4931 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4932 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4933 ep_3550 = &boardp->eep_config.adv_3550_eep;
4934 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4935 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4936 } else {
4937 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4938 }
1da177e4 4939
27c868c2
MW
4940 leftlen = cplen;
4941 totlen = len = 0;
1da177e4 4942
27c868c2
MW
4943 len = asc_prt_line(cp, leftlen,
4944 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
4945 shost->host_no);
4946 ASC_PRT_NEXT();
1da177e4 4947
27c868c2
MW
4948 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4949 wordp = &ep_3550->serial_number_word1;
4950 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4951 wordp = &ep_38C0800->serial_number_word1;
4952 } else {
4953 wordp = &ep_38C1600->serial_number_word1;
4954 }
1da177e4 4955
27c868c2
MW
4956 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
4957 len =
4958 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
4959 serialstr);
4960 ASC_PRT_NEXT();
4961 } else {
4962 len = asc_prt_line(cp, leftlen,
4963 " Serial Number Signature Not Present.\n");
4964 ASC_PRT_NEXT();
4965 }
1da177e4 4966
27c868c2
MW
4967 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4968 len = asc_prt_line(cp, leftlen,
4969 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4970 ep_3550->adapter_scsi_id,
4971 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
4972 ASC_PRT_NEXT();
4973 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4974 len = asc_prt_line(cp, leftlen,
4975 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4976 ep_38C0800->adapter_scsi_id,
4977 ep_38C0800->max_host_qng,
4978 ep_38C0800->max_dvc_qng);
4979 ASC_PRT_NEXT();
4980 } else {
4981 len = asc_prt_line(cp, leftlen,
4982 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4983 ep_38C1600->adapter_scsi_id,
4984 ep_38C1600->max_host_qng,
4985 ep_38C1600->max_dvc_qng);
4986 ASC_PRT_NEXT();
4987 }
4988 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4989 word = ep_3550->termination;
4990 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4991 word = ep_38C0800->termination_lvd;
4992 } else {
4993 word = ep_38C1600->termination_lvd;
4994 }
4995 switch (word) {
4996 case 1:
4997 termstr = "Low Off/High Off";
4998 break;
4999 case 2:
5000 termstr = "Low Off/High On";
5001 break;
5002 case 3:
5003 termstr = "Low On/High On";
5004 break;
5005 default:
5006 case 0:
5007 termstr = "Automatic";
5008 break;
5009 }
1da177e4 5010
27c868c2
MW
5011 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5012 len = asc_prt_line(cp, leftlen,
5013 " termination: %u (%s), bios_ctrl: 0x%x\n",
5014 ep_3550->termination, termstr,
5015 ep_3550->bios_ctrl);
5016 ASC_PRT_NEXT();
5017 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5018 len = asc_prt_line(cp, leftlen,
5019 " termination: %u (%s), bios_ctrl: 0x%x\n",
5020 ep_38C0800->termination_lvd, termstr,
5021 ep_38C0800->bios_ctrl);
5022 ASC_PRT_NEXT();
5023 } else {
5024 len = asc_prt_line(cp, leftlen,
5025 " termination: %u (%s), bios_ctrl: 0x%x\n",
5026 ep_38C1600->termination_lvd, termstr,
5027 ep_38C1600->bios_ctrl);
5028 ASC_PRT_NEXT();
5029 }
1da177e4 5030
27c868c2
MW
5031 len = asc_prt_line(cp, leftlen, " Target ID: ");
5032 ASC_PRT_NEXT();
5033 for (i = 0; i <= ADV_MAX_TID; i++) {
5034 len = asc_prt_line(cp, leftlen, " %X", i);
5035 ASC_PRT_NEXT();
5036 }
5037 len = asc_prt_line(cp, leftlen, "\n");
5038 ASC_PRT_NEXT();
1da177e4 5039
27c868c2
MW
5040 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5041 word = ep_3550->disc_enable;
5042 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5043 word = ep_38C0800->disc_enable;
5044 } else {
5045 word = ep_38C1600->disc_enable;
5046 }
5047 len = asc_prt_line(cp, leftlen, " Disconnects: ");
5048 ASC_PRT_NEXT();
5049 for (i = 0; i <= ADV_MAX_TID; i++) {
5050 len = asc_prt_line(cp, leftlen, " %c",
5051 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5052 ASC_PRT_NEXT();
5053 }
5054 len = asc_prt_line(cp, leftlen, "\n");
5055 ASC_PRT_NEXT();
1da177e4 5056
27c868c2
MW
5057 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5058 word = ep_3550->tagqng_able;
5059 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5060 word = ep_38C0800->tagqng_able;
5061 } else {
5062 word = ep_38C1600->tagqng_able;
5063 }
5064 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
5065 ASC_PRT_NEXT();
5066 for (i = 0; i <= ADV_MAX_TID; i++) {
5067 len = asc_prt_line(cp, leftlen, " %c",
5068 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5069 ASC_PRT_NEXT();
5070 }
5071 len = asc_prt_line(cp, leftlen, "\n");
5072 ASC_PRT_NEXT();
5073
5074 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5075 word = ep_3550->start_motor;
5076 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5077 word = ep_38C0800->start_motor;
5078 } else {
5079 word = ep_38C1600->start_motor;
5080 }
5081 len = asc_prt_line(cp, leftlen, " Start Motor: ");
5082 ASC_PRT_NEXT();
5083 for (i = 0; i <= ADV_MAX_TID; i++) {
5084 len = asc_prt_line(cp, leftlen, " %c",
5085 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5086 ASC_PRT_NEXT();
5087 }
5088 len = asc_prt_line(cp, leftlen, "\n");
5089 ASC_PRT_NEXT();
5090
5091 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5092 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5093 ASC_PRT_NEXT();
5094 for (i = 0; i <= ADV_MAX_TID; i++) {
5095 len = asc_prt_line(cp, leftlen, " %c",
5096 (ep_3550->
5097 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
5098 'Y' : 'N');
5099 ASC_PRT_NEXT();
5100 }
5101 len = asc_prt_line(cp, leftlen, "\n");
5102 ASC_PRT_NEXT();
5103 }
5104
5105 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5106 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
5107 ASC_PRT_NEXT();
5108 for (i = 0; i <= ADV_MAX_TID; i++) {
5109 len = asc_prt_line(cp, leftlen, " %c",
5110 (ep_3550->
5111 ultra_able & ADV_TID_TO_TIDMASK(i))
5112 ? 'Y' : 'N');
5113 ASC_PRT_NEXT();
5114 }
5115 len = asc_prt_line(cp, leftlen, "\n");
5116 ASC_PRT_NEXT();
5117 }
5118
5119 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5120 word = ep_3550->wdtr_able;
5121 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5122 word = ep_38C0800->wdtr_able;
5123 } else {
5124 word = ep_38C1600->wdtr_able;
5125 }
5126 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
5127 ASC_PRT_NEXT();
5128 for (i = 0; i <= ADV_MAX_TID; i++) {
5129 len = asc_prt_line(cp, leftlen, " %c",
5130 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5131 ASC_PRT_NEXT();
5132 }
5133 len = asc_prt_line(cp, leftlen, "\n");
5134 ASC_PRT_NEXT();
5135
5136 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
5137 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
5138 len = asc_prt_line(cp, leftlen,
5139 " Synchronous Transfer Speed (Mhz):\n ");
5140 ASC_PRT_NEXT();
5141 for (i = 0; i <= ADV_MAX_TID; i++) {
5142 char *speed_str;
5143
5144 if (i == 0) {
5145 sdtr_speed = adv_dvc_varp->sdtr_speed1;
5146 } else if (i == 4) {
5147 sdtr_speed = adv_dvc_varp->sdtr_speed2;
5148 } else if (i == 8) {
5149 sdtr_speed = adv_dvc_varp->sdtr_speed3;
5150 } else if (i == 12) {
5151 sdtr_speed = adv_dvc_varp->sdtr_speed4;
5152 }
5153 switch (sdtr_speed & ADV_MAX_TID) {
5154 case 0:
5155 speed_str = "Off";
5156 break;
5157 case 1:
5158 speed_str = " 5";
5159 break;
5160 case 2:
5161 speed_str = " 10";
5162 break;
5163 case 3:
5164 speed_str = " 20";
5165 break;
5166 case 4:
5167 speed_str = " 40";
5168 break;
5169 case 5:
5170 speed_str = " 80";
5171 break;
5172 default:
5173 speed_str = "Unk";
5174 break;
5175 }
5176 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
5177 ASC_PRT_NEXT();
5178 if (i == 7) {
5179 len = asc_prt_line(cp, leftlen, "\n ");
5180 ASC_PRT_NEXT();
5181 }
5182 sdtr_speed >>= 4;
5183 }
5184 len = asc_prt_line(cp, leftlen, "\n");
5185 ASC_PRT_NEXT();
5186 }
5187
5188 return totlen;
5189}
5190
5191/*
5192 * asc_prt_driver_conf()
5193 *
5194 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5195 * cf. asc_prt_line().
1da177e4
LT
5196 *
5197 * Return the number of characters copied into 'cp'. No more than
5198 * 'cplen' characters will be copied to 'cp'.
5199 */
27c868c2 5200static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5201{
27c868c2
MW
5202 asc_board_t *boardp;
5203 int leftlen;
5204 int totlen;
5205 int len;
5206 int chip_scsi_id;
5207
5208 boardp = ASC_BOARDP(shost);
5209
5210 leftlen = cplen;
5211 totlen = len = 0;
5212
5213 len = asc_prt_line(cp, leftlen,
5214 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
5215 shost->host_no);
5216 ASC_PRT_NEXT();
5217
5218 len = asc_prt_line(cp, leftlen,
5219 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
5220 shost->host_busy, shost->last_reset, shost->max_id,
5221 shost->max_lun, shost->max_channel);
5222 ASC_PRT_NEXT();
5223
5224 len = asc_prt_line(cp, leftlen,
5225 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
5226 shost->unique_id, shost->can_queue, shost->this_id,
5227 shost->sg_tablesize, shost->cmd_per_lun);
5228 ASC_PRT_NEXT();
5229
5230 len = asc_prt_line(cp, leftlen,
5231 " unchecked_isa_dma %d, use_clustering %d\n",
5232 shost->unchecked_isa_dma, shost->use_clustering);
5233 ASC_PRT_NEXT();
5234
5235 len = asc_prt_line(cp, leftlen,
5236 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
5237 boardp->flags, boardp->last_reset, jiffies,
5238 boardp->asc_n_io_port);
5239 ASC_PRT_NEXT();
5240
4a2d31c8 5241 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
27c868c2
MW
5242 ASC_PRT_NEXT();
5243
5244 if (ASC_NARROW_BOARD(boardp)) {
5245 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
5246 } else {
5247 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
5248 }
1da177e4 5249
27c868c2 5250 return totlen;
1da177e4
LT
5251}
5252
5253/*
5254 * asc_prt_asc_board_info()
5255 *
5256 * Print dynamic board configuration information.
5257 *
5258 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5259 * cf. asc_prt_line().
5260 *
5261 * Return the number of characters copied into 'cp'. No more than
5262 * 'cplen' characters will be copied to 'cp'.
5263 */
27c868c2 5264static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5265{
27c868c2
MW
5266 asc_board_t *boardp;
5267 int chip_scsi_id;
5268 int leftlen;
5269 int totlen;
5270 int len;
5271 ASC_DVC_VAR *v;
5272 ASC_DVC_CFG *c;
5273 int i;
5274 int renegotiate = 0;
5275
5276 boardp = ASC_BOARDP(shost);
5277 v = &boardp->dvc_var.asc_dvc_var;
5278 c = &boardp->dvc_cfg.asc_dvc_cfg;
5279 chip_scsi_id = c->chip_scsi_id;
5280
5281 leftlen = cplen;
5282 totlen = len = 0;
5283
5284 len = asc_prt_line(cp, leftlen,
5285 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5286 shost->host_no);
5287 ASC_PRT_NEXT();
5288
5289 len = asc_prt_line(cp, leftlen,
5290 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
5291 c->chip_version, c->lib_version, c->lib_serial_no,
5292 c->mcode_date);
5293 ASC_PRT_NEXT();
5294
5295 len = asc_prt_line(cp, leftlen,
5296 " mcode_version 0x%x, err_code %u\n",
5297 c->mcode_version, v->err_code);
5298 ASC_PRT_NEXT();
5299
5300 /* Current number of commands waiting for the host. */
5301 len = asc_prt_line(cp, leftlen,
5302 " Total Command Pending: %d\n", v->cur_total_qng);
5303 ASC_PRT_NEXT();
5304
5305 len = asc_prt_line(cp, leftlen, " Command Queuing:");
5306 ASC_PRT_NEXT();
5307 for (i = 0; i <= ASC_MAX_TID; i++) {
5308 if ((chip_scsi_id == i) ||
5309 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5310 continue;
5311 }
5312 len = asc_prt_line(cp, leftlen, " %X:%c",
5313 i,
5314 (v->
5315 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
5316 'Y' : 'N');
5317 ASC_PRT_NEXT();
5318 }
5319 len = asc_prt_line(cp, leftlen, "\n");
5320 ASC_PRT_NEXT();
5321
5322 /* Current number of commands waiting for a device. */
5323 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
5324 ASC_PRT_NEXT();
5325 for (i = 0; i <= ASC_MAX_TID; i++) {
5326 if ((chip_scsi_id == i) ||
5327 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5328 continue;
5329 }
5330 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
5331 ASC_PRT_NEXT();
5332 }
5333 len = asc_prt_line(cp, leftlen, "\n");
5334 ASC_PRT_NEXT();
5335
5336 /* Current limit on number of commands that can be sent to a device. */
5337 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
5338 ASC_PRT_NEXT();
5339 for (i = 0; i <= ASC_MAX_TID; i++) {
5340 if ((chip_scsi_id == i) ||
5341 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5342 continue;
5343 }
5344 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
5345 ASC_PRT_NEXT();
5346 }
5347 len = asc_prt_line(cp, leftlen, "\n");
5348 ASC_PRT_NEXT();
5349
5350 /* Indicate whether the device has returned queue full status. */
5351 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
5352 ASC_PRT_NEXT();
5353 for (i = 0; i <= ASC_MAX_TID; i++) {
5354 if ((chip_scsi_id == i) ||
5355 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5356 continue;
5357 }
5358 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
5359 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
5360 i, boardp->queue_full_cnt[i]);
5361 } else {
5362 len = asc_prt_line(cp, leftlen, " %X:N", i);
5363 }
5364 ASC_PRT_NEXT();
5365 }
5366 len = asc_prt_line(cp, leftlen, "\n");
5367 ASC_PRT_NEXT();
5368
5369 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5370 ASC_PRT_NEXT();
5371 for (i = 0; i <= ASC_MAX_TID; i++) {
5372 if ((chip_scsi_id == i) ||
5373 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5374 continue;
5375 }
5376 len = asc_prt_line(cp, leftlen, " %X:%c",
5377 i,
5378 (v->
5379 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5380 'N');
5381 ASC_PRT_NEXT();
5382 }
5383 len = asc_prt_line(cp, leftlen, "\n");
5384 ASC_PRT_NEXT();
5385
5386 for (i = 0; i <= ASC_MAX_TID; i++) {
5387 uchar syn_period_ix;
5388
5389 if ((chip_scsi_id == i) ||
5390 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
5391 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
5392 continue;
5393 }
5394
5395 len = asc_prt_line(cp, leftlen, " %X:", i);
5396 ASC_PRT_NEXT();
5397
5398 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
5399 len = asc_prt_line(cp, leftlen, " Asynchronous");
5400 ASC_PRT_NEXT();
5401 } else {
5402 syn_period_ix =
5403 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
5404 1);
5405
5406 len = asc_prt_line(cp, leftlen,
5407 " Transfer Period Factor: %d (%d.%d Mhz),",
5408 v->sdtr_period_tbl[syn_period_ix],
5409 250 /
5410 v->sdtr_period_tbl[syn_period_ix],
5411 ASC_TENTHS(250,
5412 v->
5413 sdtr_period_tbl
5414 [syn_period_ix]));
5415 ASC_PRT_NEXT();
5416
5417 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
5418 boardp->
5419 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
5420 ASC_PRT_NEXT();
5421 }
5422
5423 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5424 len = asc_prt_line(cp, leftlen, "*\n");
5425 renegotiate = 1;
5426 } else {
5427 len = asc_prt_line(cp, leftlen, "\n");
5428 }
5429 ASC_PRT_NEXT();
5430 }
1da177e4 5431
27c868c2
MW
5432 if (renegotiate) {
5433 len = asc_prt_line(cp, leftlen,
5434 " * = Re-negotiation pending before next command.\n");
5435 ASC_PRT_NEXT();
5436 }
1da177e4 5437
27c868c2 5438 return totlen;
1da177e4
LT
5439}
5440
5441/*
5442 * asc_prt_adv_board_info()
5443 *
5444 * Print dynamic board configuration information.
5445 *
5446 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5447 * cf. asc_prt_line().
5448 *
5449 * Return the number of characters copied into 'cp'. No more than
5450 * 'cplen' characters will be copied to 'cp'.
5451 */
27c868c2 5452static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5453{
27c868c2
MW
5454 asc_board_t *boardp;
5455 int leftlen;
5456 int totlen;
5457 int len;
5458 int i;
5459 ADV_DVC_VAR *v;
5460 ADV_DVC_CFG *c;
5461 AdvPortAddr iop_base;
5462 ushort chip_scsi_id;
5463 ushort lramword;
5464 uchar lrambyte;
5465 ushort tagqng_able;
5466 ushort sdtr_able, wdtr_able;
5467 ushort wdtr_done, sdtr_done;
5468 ushort period = 0;
5469 int renegotiate = 0;
5470
5471 boardp = ASC_BOARDP(shost);
5472 v = &boardp->dvc_var.adv_dvc_var;
5473 c = &boardp->dvc_cfg.adv_dvc_cfg;
5474 iop_base = v->iop_base;
5475 chip_scsi_id = v->chip_scsi_id;
5476
5477 leftlen = cplen;
5478 totlen = len = 0;
5479
5480 len = asc_prt_line(cp, leftlen,
5481 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5482 shost->host_no);
5483 ASC_PRT_NEXT();
5484
5485 len = asc_prt_line(cp, leftlen,
5486 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
5487 v->iop_base,
5488 AdvReadWordRegister(iop_base,
5489 IOPW_SCSI_CFG1) & CABLE_DETECT,
5490 v->err_code);
5491 ASC_PRT_NEXT();
5492
5493 len = asc_prt_line(cp, leftlen,
5494 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
5495 c->chip_version, c->lib_version, c->mcode_date,
5496 c->mcode_version);
5497 ASC_PRT_NEXT();
5498
5499 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5500 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
5501 ASC_PRT_NEXT();
5502 for (i = 0; i <= ADV_MAX_TID; i++) {
5503 if ((chip_scsi_id == i) ||
5504 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5505 continue;
5506 }
5507
5508 len = asc_prt_line(cp, leftlen, " %X:%c",
5509 i,
5510 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5511 'N');
5512 ASC_PRT_NEXT();
5513 }
5514 len = asc_prt_line(cp, leftlen, "\n");
5515 ASC_PRT_NEXT();
5516
5517 len = asc_prt_line(cp, leftlen, " Queue Limit:");
5518 ASC_PRT_NEXT();
5519 for (i = 0; i <= ADV_MAX_TID; i++) {
5520 if ((chip_scsi_id == i) ||
5521 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5522 continue;
5523 }
5524
5525 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
5526 lrambyte);
5527
5528 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
5529 ASC_PRT_NEXT();
5530 }
5531 len = asc_prt_line(cp, leftlen, "\n");
5532 ASC_PRT_NEXT();
5533
5534 len = asc_prt_line(cp, leftlen, " Command Pending:");
5535 ASC_PRT_NEXT();
5536 for (i = 0; i <= ADV_MAX_TID; i++) {
5537 if ((chip_scsi_id == i) ||
5538 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5539 continue;
5540 }
5541
5542 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
5543 lrambyte);
5544
5545 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
5546 ASC_PRT_NEXT();
5547 }
5548 len = asc_prt_line(cp, leftlen, "\n");
5549 ASC_PRT_NEXT();
5550
5551 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5552 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
5553 ASC_PRT_NEXT();
5554 for (i = 0; i <= ADV_MAX_TID; i++) {
5555 if ((chip_scsi_id == i) ||
5556 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5557 continue;
5558 }
5559
5560 len = asc_prt_line(cp, leftlen, " %X:%c",
5561 i,
5562 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5563 'N');
5564 ASC_PRT_NEXT();
5565 }
5566 len = asc_prt_line(cp, leftlen, "\n");
5567 ASC_PRT_NEXT();
5568
5569 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
5570 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
5571 ASC_PRT_NEXT();
5572 for (i = 0; i <= ADV_MAX_TID; i++) {
5573 if ((chip_scsi_id == i) ||
5574 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5575 continue;
5576 }
5577
5578 AdvReadWordLram(iop_base,
5579 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
5580 lramword);
5581
5582 len = asc_prt_line(cp, leftlen, " %X:%d",
5583 i, (lramword & 0x8000) ? 16 : 8);
5584 ASC_PRT_NEXT();
5585
5586 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
5587 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5588 len = asc_prt_line(cp, leftlen, "*");
5589 ASC_PRT_NEXT();
5590 renegotiate = 1;
5591 }
5592 }
5593 len = asc_prt_line(cp, leftlen, "\n");
5594 ASC_PRT_NEXT();
5595
5596 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5597 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
5598 ASC_PRT_NEXT();
5599 for (i = 0; i <= ADV_MAX_TID; i++) {
5600 if ((chip_scsi_id == i) ||
5601 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5602 continue;
5603 }
5604
5605 len = asc_prt_line(cp, leftlen, " %X:%c",
5606 i,
5607 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5608 'N');
5609 ASC_PRT_NEXT();
5610 }
5611 len = asc_prt_line(cp, leftlen, "\n");
5612 ASC_PRT_NEXT();
5613
5614 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
5615 for (i = 0; i <= ADV_MAX_TID; i++) {
5616
5617 AdvReadWordLram(iop_base,
5618 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
5619 lramword);
5620 lramword &= ~0x8000;
5621
5622 if ((chip_scsi_id == i) ||
5623 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
5624 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
5625 continue;
5626 }
5627
5628 len = asc_prt_line(cp, leftlen, " %X:", i);
5629 ASC_PRT_NEXT();
5630
5631 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
5632 len = asc_prt_line(cp, leftlen, " Asynchronous");
5633 ASC_PRT_NEXT();
5634 } else {
5635 len =
5636 asc_prt_line(cp, leftlen,
5637 " Transfer Period Factor: ");
5638 ASC_PRT_NEXT();
5639
5640 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
5641 len =
5642 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
5643 ASC_PRT_NEXT();
5644 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
5645 len =
5646 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
5647 ASC_PRT_NEXT();
5648 } else { /* 20 Mhz or below. */
5649
5650 period = (((lramword >> 8) * 25) + 50) / 4;
5651
5652 if (period == 0) { /* Should never happen. */
5653 len =
5654 asc_prt_line(cp, leftlen,
5655 "%d (? Mhz), ");
5656 ASC_PRT_NEXT();
5657 } else {
5658 len = asc_prt_line(cp, leftlen,
5659 "%d (%d.%d Mhz),",
5660 period, 250 / period,
5661 ASC_TENTHS(250,
5662 period));
5663 ASC_PRT_NEXT();
5664 }
5665 }
5666
5667 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
5668 lramword & 0x1F);
5669 ASC_PRT_NEXT();
5670 }
5671
5672 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5673 len = asc_prt_line(cp, leftlen, "*\n");
5674 renegotiate = 1;
5675 } else {
5676 len = asc_prt_line(cp, leftlen, "\n");
5677 }
5678 ASC_PRT_NEXT();
5679 }
1da177e4 5680
27c868c2
MW
5681 if (renegotiate) {
5682 len = asc_prt_line(cp, leftlen,
5683 " * = Re-negotiation pending before next command.\n");
5684 ASC_PRT_NEXT();
5685 }
1da177e4 5686
27c868c2 5687 return totlen;
1da177e4
LT
5688}
5689
5690/*
5691 * asc_proc_copy()
5692 *
5693 * Copy proc information to a read buffer taking into account the current
5694 * read offset in the file and the remaining space in the read buffer.
5695 */
27c868c2 5696static int
1da177e4 5697asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 5698 char *cp, int cplen)
1da177e4 5699{
27c868c2
MW
5700 int cnt = 0;
5701
5702 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
5703 (unsigned)offset, (unsigned)advoffset, cplen);
5704 if (offset <= advoffset) {
5705 /* Read offset below current offset, copy everything. */
5706 cnt = min(cplen, leftlen);
5707 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
5708 (ulong)curbuf, (ulong)cp, cnt);
5709 memcpy(curbuf, cp, cnt);
5710 } else if (offset < advoffset + cplen) {
5711 /* Read offset within current range, partial copy. */
5712 cnt = (advoffset + cplen) - offset;
5713 cp = (cp + cplen) - cnt;
5714 cnt = min(cnt, leftlen);
5715 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
5716 (ulong)curbuf, (ulong)cp, cnt);
5717 memcpy(curbuf, cp, cnt);
5718 }
5719 return cnt;
1da177e4
LT
5720}
5721
5722/*
5723 * asc_prt_line()
5724 *
5725 * If 'cp' is NULL print to the console, otherwise print to a buffer.
5726 *
5727 * Return 0 if printing to the console, otherwise return the number of
5728 * bytes written to the buffer.
5729 *
5730 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
5731 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
5732 */
27c868c2 5733static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 5734{
27c868c2
MW
5735 va_list args;
5736 int ret;
5737 char s[ASC_PRTLINE_SIZE];
5738
5739 va_start(args, fmt);
5740 ret = vsprintf(s, fmt, args);
5741 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
5742 if (buf == NULL) {
5743 (void)printk(s);
5744 ret = 0;
5745 } else {
5746 ret = min(buflen, ret);
5747 memcpy(buf, s, ret);
5748 }
5749 va_end(args);
5750 return ret;
1da177e4
LT
5751}
5752#endif /* CONFIG_PROC_FS */
5753
1da177e4
LT
5754/*
5755 * --- Functions Required by the Asc Library
5756 */
5757
5758/*
5759 * Delay for 'n' milliseconds. Don't use the 'jiffies'
5760 * global variable which is incremented once every 5 ms
5761 * from a timer interrupt, because this function may be
5762 * called when interrupts are disabled.
5763 */
27c868c2 5764static void DvcSleepMilliSecond(ADV_DCNT n)
1da177e4 5765{
27c868c2
MW
5766 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
5767 mdelay(n);
1da177e4
LT
5768}
5769
5770/*
5771 * Currently and inline noop but leave as a placeholder.
5772 * Leave DvcEnterCritical() as a noop placeholder.
5773 */
27c868c2 5774static inline ulong DvcEnterCritical(void)
1da177e4 5775{
27c868c2 5776 return 0;
1da177e4
LT
5777}
5778
5779/*
5780 * Critical sections are all protected by the board spinlock.
5781 * Leave DvcLeaveCritical() as a noop placeholder.
5782 */
27c868c2 5783static inline void DvcLeaveCritical(ulong flags)
1da177e4 5784{
27c868c2 5785 return;
1da177e4
LT
5786}
5787
5788/*
5789 * void
5790 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
5791 *
5792 * Calling/Exit State:
5793 * none
5794 *
5795 * Description:
5796 * Output an ASC_SCSI_Q structure to the chip
5797 */
27c868c2 5798static void
1da177e4
LT
5799DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
5800{
27c868c2
MW
5801 int i;
5802
5803 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
5804 AscSetChipLramAddr(iop_base, s_addr);
5805 for (i = 0; i < 2 * words; i += 2) {
5806 if (i == 4 || i == 20) {
5807 continue;
5808 }
5809 outpw(iop_base + IOP_RAM_DATA,
5810 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
5811 }
1da177e4
LT
5812}
5813
5814/*
5815 * void
5816 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
5817 *
5818 * Calling/Exit State:
5819 * none
5820 *
5821 * Description:
5822 * Input an ASC_QDONE_INFO structure from the chip
5823 */
27c868c2 5824static void
1da177e4
LT
5825DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
5826{
27c868c2
MW
5827 int i;
5828 ushort word;
5829
5830 AscSetChipLramAddr(iop_base, s_addr);
5831 for (i = 0; i < 2 * words; i += 2) {
5832 if (i == 10) {
5833 continue;
5834 }
5835 word = inpw(iop_base + IOP_RAM_DATA);
5836 inbuf[i] = word & 0xff;
5837 inbuf[i + 1] = (word >> 8) & 0xff;
5838 }
5839 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
5840}
5841
1da177e4
LT
5842/*
5843 * Return the BIOS address of the adapter at the specified
5844 * I/O port and with the specified bus type.
5845 */
ecec1947
MW
5846static unsigned short __devinit
5847AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
1da177e4 5848{
ecec1947
MW
5849 unsigned short cfg_lsw;
5850 unsigned short bios_addr;
27c868c2
MW
5851
5852 /*
5853 * The PCI BIOS is re-located by the motherboard BIOS. Because
5854 * of this the driver can not determine where a PCI BIOS is
5855 * loaded and executes.
5856 */
ecec1947
MW
5857 if (bus_type & ASC_IS_PCI)
5858 return 0;
5859
1da177e4 5860#ifdef CONFIG_ISA
27c868c2
MW
5861 if ((bus_type & ASC_IS_EISA) != 0) {
5862 cfg_lsw = AscGetEisaChipCfg(iop_base);
5863 cfg_lsw &= 0x000F;
ecec1947
MW
5864 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
5865 return bios_addr;
5866 }
1da177e4
LT
5867#endif /* CONFIG_ISA */
5868
27c868c2 5869 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 5870
27c868c2
MW
5871 /*
5872 * ISA PnP uses the top bit as the 32K BIOS flag
5873 */
ecec1947 5874 if (bus_type == ASC_IS_ISAPNP)
27c868c2 5875 cfg_lsw &= 0x7FFF;
ecec1947
MW
5876 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
5877 return bios_addr;
1da177e4
LT
5878}
5879
1da177e4
LT
5880/*
5881 * --- Functions Required by the Adv Library
5882 */
5883
5884/*
5885 * DvcGetPhyAddr()
5886 *
5887 * Return the physical address of 'vaddr' and set '*lenp' to the
5888 * number of physically contiguous bytes that follow 'vaddr'.
5889 * 'flag' indicates the type of structure whose physical address
5890 * is being translated.
5891 *
5892 * Note: Because Linux currently doesn't page the kernel and all
5893 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
5894 */
5895ADV_PADDR
5896DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 5897 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 5898{
27c868c2 5899 ADV_PADDR paddr;
1da177e4 5900
27c868c2 5901 paddr = virt_to_bus(vaddr);
1da177e4 5902
27c868c2
MW
5903 ASC_DBG4(4,
5904 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
5905 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
5906 (ulong)paddr);
1da177e4 5907
27c868c2 5908 return paddr;
1da177e4
LT
5909}
5910
1da177e4
LT
5911/*
5912 * --- Tracing and Debugging Functions
5913 */
5914
5915#ifdef ADVANSYS_STATS
5916#ifdef CONFIG_PROC_FS
5917/*
5918 * asc_prt_board_stats()
5919 *
5920 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5921 * cf. asc_prt_line().
5922 *
5923 * Return the number of characters copied into 'cp'. No more than
5924 * 'cplen' characters will be copied to 'cp'.
5925 */
27c868c2 5926static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5927{
27c868c2
MW
5928 int leftlen;
5929 int totlen;
5930 int len;
5931 struct asc_stats *s;
5932 asc_board_t *boardp;
1da177e4 5933
27c868c2
MW
5934 leftlen = cplen;
5935 totlen = len = 0;
5936
5937 boardp = ASC_BOARDP(shost);
5938 s = &boardp->asc_stats;
5939
5940 len = asc_prt_line(cp, leftlen,
5941 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
5942 shost->host_no);
5943 ASC_PRT_NEXT();
5944
5945 len = asc_prt_line(cp, leftlen,
5946 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
5947 s->queuecommand, s->reset, s->biosparam,
5948 s->interrupt);
5949 ASC_PRT_NEXT();
5950
5951 len = asc_prt_line(cp, leftlen,
5952 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
5953 s->callback, s->done, s->build_error,
5954 s->adv_build_noreq, s->adv_build_nosg);
5955 ASC_PRT_NEXT();
5956
5957 len = asc_prt_line(cp, leftlen,
5958 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
5959 s->exe_noerror, s->exe_busy, s->exe_error,
5960 s->exe_unknown);
5961 ASC_PRT_NEXT();
5962
5963 /*
5964 * Display data transfer statistics.
5965 */
5966 if (s->cont_cnt > 0) {
5967 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
5968 ASC_PRT_NEXT();
5969
5970 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
5971 s->cont_xfer / 2,
5972 ASC_TENTHS(s->cont_xfer, 2));
5973 ASC_PRT_NEXT();
5974
5975 /* Contiguous transfer average size */
5976 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
5977 (s->cont_xfer / 2) / s->cont_cnt,
5978 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
5979 ASC_PRT_NEXT();
5980 }
1da177e4 5981
27c868c2 5982 if (s->sg_cnt > 0) {
1da177e4 5983
27c868c2
MW
5984 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
5985 s->sg_cnt, s->sg_elem);
5986 ASC_PRT_NEXT();
1da177e4 5987
27c868c2
MW
5988 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
5989 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
5990 ASC_PRT_NEXT();
1da177e4 5991
27c868c2
MW
5992 /* Scatter gather transfer statistics */
5993 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
5994 s->sg_elem / s->sg_cnt,
5995 ASC_TENTHS(s->sg_elem, s->sg_cnt));
5996 ASC_PRT_NEXT();
1da177e4 5997
27c868c2
MW
5998 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
5999 (s->sg_xfer / 2) / s->sg_elem,
6000 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
6001 ASC_PRT_NEXT();
1da177e4 6002
27c868c2
MW
6003 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
6004 (s->sg_xfer / 2) / s->sg_cnt,
6005 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
6006 ASC_PRT_NEXT();
6007 }
1da177e4 6008
27c868c2
MW
6009 /*
6010 * Display request queuing statistics.
6011 */
6012 len = asc_prt_line(cp, leftlen,
6013 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
6014 HZ);
6015 ASC_PRT_NEXT();
1da177e4 6016
27c868c2 6017 return totlen;
1da177e4 6018}
1da177e4
LT
6019#endif /* CONFIG_PROC_FS */
6020#endif /* ADVANSYS_STATS */
6021
6022#ifdef ADVANSYS_DEBUG
6023/*
6024 * asc_prt_scsi_host()
6025 */
27c868c2 6026static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 6027{
27c868c2
MW
6028 asc_board_t *boardp;
6029
6030 boardp = ASC_BOARDP(s);
6031
6032 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
6033 printk(" host_busy %u, host_no %d, last_reset %d,\n",
6034 s->host_busy, s->host_no, (unsigned)s->last_reset);
6035
4a2d31c8
MW
6036 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
6037 (ulong)s->base, (ulong)s->io_port, s->irq);
27c868c2
MW
6038
6039 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
6040 s->dma_channel, s->this_id, s->can_queue);
6041
6042 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
6043 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
6044
6045 if (ASC_NARROW_BOARD(boardp)) {
6046 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
6047 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
6048 } else {
6049 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
6050 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
6051 }
1da177e4
LT
6052}
6053
6054/*
6055 * asc_prt_scsi_cmnd()
6056 */
27c868c2 6057static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 6058{
27c868c2 6059 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 6060
27c868c2
MW
6061 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
6062 (ulong)s->device->host, (ulong)s->device, s->device->id,
6063 s->device->lun, s->device->channel);
1da177e4 6064
27c868c2 6065 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 6066
27c868c2
MW
6067 printk("sc_data_direction %u, resid %d\n",
6068 s->sc_data_direction, s->resid);
1da177e4 6069
27c868c2 6070 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 6071
27c868c2
MW
6072 printk(" serial_number 0x%x, retries %d, allowed %d\n",
6073 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 6074
27c868c2 6075 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 6076
ecec1947
MW
6077 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
6078 s->scsi_done, s->done, s->host_scribble, s->result);
1da177e4 6079
27c868c2 6080 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
6081}
6082
6083/*
6084 * asc_prt_asc_dvc_var()
6085 */
27c868c2 6086static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 6087{
27c868c2
MW
6088 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
6089
ecec1947
MW
6090 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
6091 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
27c868c2 6092
895d6b4c
MW
6093 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
6094 (unsigned)h->init_sdtr);
27c868c2 6095
ecec1947
MW
6096 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
6097 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
6098 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
6099 (unsigned)h->chip_no);
27c868c2 6100
ecec1947
MW
6101 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
6102 "%u,\n", (unsigned)h->queue_full_or_busy,
6103 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
27c868c2 6104
ecec1947
MW
6105 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
6106 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
6107 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
6108 (unsigned)h->in_critical_cnt);
27c868c2 6109
ecec1947
MW
6110 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
6111 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
6112 (unsigned)h->init_state, (unsigned)h->no_scam,
6113 (unsigned)h->pci_fix_asyn_xfer);
27c868c2
MW
6114
6115 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
6116}
6117
6118/*
6119 * asc_prt_asc_dvc_cfg()
6120 */
27c868c2 6121static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 6122{
27c868c2
MW
6123 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
6124
6125 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
6126 h->can_tagged_qng, h->cmd_qng_enabled);
6127 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
6128 h->disc_enable, h->sdtr_enable);
6129
6130 printk
6131 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
6132 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
6133 h->chip_version);
6134
6135 printk
6136 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
6137 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
6138 h->mcode_date);
6139
6140 printk(" mcode_version %d, overrun_buf 0x%lx\n",
6141 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
6142}
6143
6144/*
6145 * asc_prt_asc_scsi_q()
6146 */
27c868c2 6147static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 6148{
27c868c2
MW
6149 ASC_SG_HEAD *sgp;
6150 int i;
6151
6152 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
6153
6154 printk
6155 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
6156 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
6157 q->q2.tag_code);
6158
6159 printk
6160 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6161 (ulong)le32_to_cpu(q->q1.data_addr),
6162 (ulong)le32_to_cpu(q->q1.data_cnt),
6163 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
6164
6165 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
6166 (ulong)q->cdbptr, q->q2.cdb_len,
6167 (ulong)q->sg_head, q->q1.sg_queue_cnt);
6168
6169 if (q->sg_head) {
6170 sgp = q->sg_head;
6171 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
6172 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
6173 sgp->queue_cnt);
6174 for (i = 0; i < sgp->entry_cnt; i++) {
6175 printk(" [%u]: addr 0x%lx, bytes %lu\n",
6176 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
6177 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
6178 }
1da177e4 6179
27c868c2 6180 }
1da177e4
LT
6181}
6182
6183/*
6184 * asc_prt_asc_qdone_info()
6185 */
27c868c2 6186static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 6187{
27c868c2
MW
6188 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
6189 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
6190 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
6191 q->d2.tag_code);
6192 printk
6193 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
6194 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
6195}
6196
6197/*
6198 * asc_prt_adv_dvc_var()
6199 *
6200 * Display an ADV_DVC_VAR structure.
6201 */
27c868c2 6202static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 6203{
27c868c2
MW
6204 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
6205
6206 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
6207 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
6208
6209 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
6210 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
6211 (unsigned)h->wdtr_able);
6212
6213 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
6214 (unsigned)h->start_motor,
6215 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
6216
6217 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
6218 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
6219 (ulong)h->carr_freelist);
6220
6221 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
6222 (ulong)h->icq_sp, (ulong)h->irq_sp);
6223
6224 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
6225 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
6226
6227 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
6228 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
6229}
6230
6231/*
6232 * asc_prt_adv_dvc_cfg()
6233 *
6234 * Display an ADV_DVC_CFG structure.
6235 */
27c868c2 6236static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 6237{
27c868c2 6238 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 6239
27c868c2
MW
6240 printk(" disc_enable 0x%x, termination 0x%x\n",
6241 h->disc_enable, h->termination);
1da177e4 6242
27c868c2
MW
6243 printk(" chip_version 0x%x, mcode_date 0x%x\n",
6244 h->chip_version, h->mcode_date);
1da177e4 6245
27c868c2
MW
6246 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
6247 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 6248
13ac2d9c 6249 printk(" control_flag 0x%x\n", h->control_flag);
1da177e4
LT
6250}
6251
6252/*
6253 * asc_prt_adv_scsi_req_q()
6254 *
6255 * Display an ADV_SCSI_REQ_Q structure.
6256 */
27c868c2 6257static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 6258{
27c868c2
MW
6259 int sg_blk_cnt;
6260 struct asc_sg_block *sg_ptr;
6261
6262 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
6263
6264 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
6265 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
6266
6267 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
6268 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
6269
6270 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6271 (ulong)le32_to_cpu(q->data_cnt),
6272 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
6273
6274 printk
6275 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
6276 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
6277
6278 printk(" sg_working_ix 0x%x, target_cmd %u\n",
6279 q->sg_working_ix, q->target_cmd);
6280
6281 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
6282 (ulong)le32_to_cpu(q->scsiq_rptr),
6283 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
6284
6285 /* Display the request's ADV_SG_BLOCK structures. */
6286 if (q->sg_list_ptr != NULL) {
6287 sg_blk_cnt = 0;
6288 while (1) {
6289 /*
6290 * 'sg_ptr' is a physical address. Convert it to a virtual
6291 * address by indexing 'sg_blk_cnt' into the virtual address
6292 * array 'sg_list_ptr'.
6293 *
6294 * XXX - Assumes all SG physical blocks are virtually contiguous.
6295 */
6296 sg_ptr =
6297 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
6298 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
6299 if (sg_ptr->sg_ptr == 0) {
6300 break;
6301 }
6302 sg_blk_cnt++;
6303 }
6304 }
1da177e4
LT
6305}
6306
6307/*
6308 * asc_prt_adv_sgblock()
6309 *
6310 * Display an ADV_SG_BLOCK structure.
6311 */
27c868c2 6312static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 6313{
27c868c2
MW
6314 int i;
6315
6316 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
6317 (ulong)b, sgblockno);
6318 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
6319 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
6320 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
6321 if (b->sg_ptr != 0) {
6322 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
6323 }
6324 for (i = 0; i < b->sg_cnt; i++) {
6325 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
6326 i, (ulong)b->sg_list[i].sg_addr,
6327 (ulong)b->sg_list[i].sg_count);
6328 }
1da177e4
LT
6329}
6330
6331/*
6332 * asc_prt_hex()
6333 *
6334 * Print hexadecimal output in 4 byte groupings 32 bytes
6335 * or 8 double-words per line.
6336 */
27c868c2 6337static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 6338{
27c868c2
MW
6339 int i;
6340 int j;
6341 int k;
6342 int m;
6343
6344 printk("%s: (%d bytes)\n", f, l);
6345
6346 for (i = 0; i < l; i += 32) {
6347
6348 /* Display a maximum of 8 double-words per line. */
6349 if ((k = (l - i) / 4) >= 8) {
6350 k = 8;
6351 m = 0;
6352 } else {
6353 m = (l - i) % 4;
6354 }
6355
6356 for (j = 0; j < k; j++) {
6357 printk(" %2.2X%2.2X%2.2X%2.2X",
6358 (unsigned)s[i + (j * 4)],
6359 (unsigned)s[i + (j * 4) + 1],
6360 (unsigned)s[i + (j * 4) + 2],
6361 (unsigned)s[i + (j * 4) + 3]);
6362 }
6363
6364 switch (m) {
6365 case 0:
6366 default:
6367 break;
6368 case 1:
6369 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
6370 break;
6371 case 2:
6372 printk(" %2.2X%2.2X",
6373 (unsigned)s[i + (j * 4)],
6374 (unsigned)s[i + (j * 4) + 1]);
6375 break;
6376 case 3:
6377 printk(" %2.2X%2.2X%2.2X",
6378 (unsigned)s[i + (j * 4) + 1],
6379 (unsigned)s[i + (j * 4) + 2],
6380 (unsigned)s[i + (j * 4) + 3]);
6381 break;
6382 }
6383
6384 printk("\n");
6385 }
1da177e4
LT
6386}
6387#endif /* ADVANSYS_DEBUG */
6388
6389/*
6390 * --- Asc Library Functions
6391 */
6392
78e77d8b 6393static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 6394{
27c868c2 6395 PortAddr eisa_cfg_iop;
1da177e4 6396
27c868c2
MW
6397 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
6398 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
6399 return (inpw(eisa_cfg_iop));
1da177e4
LT
6400}
6401
78e77d8b 6402static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 6403{
27c868c2 6404 ushort cfg_lsw;
1da177e4 6405
27c868c2
MW
6406 if (AscGetChipScsiID(iop_base) == new_host_id) {
6407 return (new_host_id);
6408 }
6409 cfg_lsw = AscGetChipCfgLsw(iop_base);
6410 cfg_lsw &= 0xF8FF;
6411 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
6412 AscSetChipCfgLsw(iop_base, cfg_lsw);
6413 return (AscGetChipScsiID(iop_base));
1da177e4
LT
6414}
6415
ecec1947 6416static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 6417{
ecec1947 6418 unsigned char sc;
1da177e4 6419
27c868c2
MW
6420 AscSetBank(iop_base, 1);
6421 sc = inp(iop_base + IOP_REG_SC);
6422 AscSetBank(iop_base, 0);
ecec1947 6423 return sc;
1da177e4
LT
6424}
6425
ecec1947
MW
6426static unsigned char __devinit
6427AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
1da177e4 6428{
ecec1947 6429 if (bus_type & ASC_IS_EISA) {
27c868c2 6430 PortAddr eisa_iop;
ecec1947 6431 unsigned char revision;
27c868c2
MW
6432 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
6433 (PortAddr) ASC_EISA_REV_IOP_MASK;
6434 revision = inp(eisa_iop);
ecec1947 6435 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
27c868c2 6436 }
ecec1947 6437 return AscGetChipVerNo(iop_base);
1da177e4
LT
6438}
6439
27c868c2
MW
6440static ASC_DCNT
6441AscLoadMicroCode(PortAddr iop_base,
6442 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 6443{
27c868c2
MW
6444 ASC_DCNT chksum;
6445 ushort mcode_word_size;
6446 ushort mcode_chksum;
6447
6448 /* Write the microcode buffer starting at LRAM address 0. */
6449 mcode_word_size = (ushort)(mcode_size >> 1);
6450 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
6451 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
6452
6453 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
6454 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
6455 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
6456 (ushort)ASC_CODE_SEC_BEG,
6457 (ushort)((mcode_size -
6458 s_addr - (ushort)
6459 ASC_CODE_SEC_BEG) /
6460 2));
6461 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
6462 (ulong)mcode_chksum);
6463 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
6464 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
6465 return (chksum);
1da177e4
LT
6466}
6467
27c868c2 6468static int AscFindSignature(PortAddr iop_base)
1da177e4 6469{
27c868c2
MW
6470 ushort sig_word;
6471
6472 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
6473 iop_base, AscGetChipSignatureByte(iop_base));
6474 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
6475 ASC_DBG2(1,
6476 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
6477 iop_base, AscGetChipSignatureWord(iop_base));
6478 sig_word = AscGetChipSignatureWord(iop_base);
6479 if ((sig_word == (ushort)ASC_1000_ID0W) ||
6480 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
6481 return (1);
6482 }
6483 }
6484 return (0);
1da177e4
LT
6485}
6486
78e77d8b 6487static void __devinit AscToggleIRQAct(PortAddr iop_base)
1da177e4 6488{
27c868c2
MW
6489 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
6490 AscSetChipStatus(iop_base, 0);
6491 return;
1da177e4
LT
6492}
6493
78e77d8b 6494static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 6495{
27c868c2
MW
6496 ushort cfg_lsw;
6497 uchar chip_irq;
6498
6499 if ((bus_type & ASC_IS_EISA) != 0) {
6500 cfg_lsw = AscGetEisaChipCfg(iop_base);
6501 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
6502 if ((chip_irq == 13) || (chip_irq > 15)) {
6503 return (0);
6504 }
6505 return (chip_irq);
6506 }
6507 if ((bus_type & ASC_IS_VL) != 0) {
6508 cfg_lsw = AscGetChipCfgLsw(iop_base);
6509 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
6510 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
6511 return (0);
6512 }
6513 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
6514 }
6515 cfg_lsw = AscGetChipCfgLsw(iop_base);
6516 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
6517 if (chip_irq == 3)
6518 chip_irq += (uchar)2;
6519 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
6520}
6521
78e77d8b 6522static uchar __devinit
27c868c2 6523AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 6524{
27c868c2
MW
6525 ushort cfg_lsw;
6526
6527 if ((bus_type & ASC_IS_VL) != 0) {
6528 if (irq_no != 0) {
6529 if ((irq_no < ASC_MIN_IRQ_NO)
6530 || (irq_no > ASC_MAX_IRQ_NO)) {
6531 irq_no = 0;
6532 } else {
6533 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
6534 }
6535 }
6536 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
6537 cfg_lsw |= (ushort)0x0010;
6538 AscSetChipCfgLsw(iop_base, cfg_lsw);
6539 AscToggleIRQAct(iop_base);
6540 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
6541 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
6542 AscSetChipCfgLsw(iop_base, cfg_lsw);
6543 AscToggleIRQAct(iop_base);
6544 return (AscGetChipIRQ(iop_base, bus_type));
6545 }
6546 if ((bus_type & (ASC_IS_ISA)) != 0) {
6547 if (irq_no == 15)
6548 irq_no -= (uchar)2;
6549 irq_no -= (uchar)ASC_MIN_IRQ_NO;
6550 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
6551 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
6552 AscSetChipCfgLsw(iop_base, cfg_lsw);
6553 return (AscGetChipIRQ(iop_base, bus_type));
6554 }
6555 return (0);
1da177e4
LT
6556}
6557
6558#ifdef CONFIG_ISA
78e77d8b 6559static void __devinit AscEnableIsaDma(uchar dma_channel)
1da177e4 6560{
27c868c2
MW
6561 if (dma_channel < 4) {
6562 outp(0x000B, (ushort)(0xC0 | dma_channel));
6563 outp(0x000A, dma_channel);
6564 } else if (dma_channel < 8) {
6565 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
6566 outp(0x00D4, (ushort)(dma_channel - 4));
6567 }
6568 return;
1da177e4
LT
6569}
6570#endif /* CONFIG_ISA */
6571
27c868c2 6572static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 6573{
27c868c2
MW
6574 EXT_MSG ext_msg;
6575 EXT_MSG out_msg;
6576 ushort halt_q_addr;
6577 int sdtr_accept;
6578 ushort int_halt_code;
6579 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6580 ASC_SCSI_BIT_ID_TYPE target_id;
6581 PortAddr iop_base;
6582 uchar tag_code;
6583 uchar q_status;
6584 uchar halt_qp;
6585 uchar sdtr_data;
6586 uchar target_ix;
6587 uchar q_cntl, tid_no;
6588 uchar cur_dvc_qng;
6589 uchar asyn_sdtr;
6590 uchar scsi_status;
6591 asc_board_t *boardp;
6592
6593 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
6594 boardp = asc_dvc->drv_ptr;
6595
6596 iop_base = asc_dvc->iop_base;
6597 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
6598
6599 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
6600 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
6601 target_ix = AscReadLramByte(iop_base,
6602 (ushort)(halt_q_addr +
6603 (ushort)ASC_SCSIQ_B_TARGET_IX));
6604 q_cntl =
6605 AscReadLramByte(iop_base,
6606 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6607 tid_no = ASC_TIX_TO_TID(target_ix);
6608 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
6609 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6610 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
6611 } else {
6612 asyn_sdtr = 0;
6613 }
6614 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
6615 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6616 AscSetChipSDTR(iop_base, 0, tid_no);
6617 boardp->sdtr_data[tid_no] = 0;
6618 }
6619 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6620 return (0);
6621 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
6622 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6623 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6624 boardp->sdtr_data[tid_no] = asyn_sdtr;
6625 }
6626 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6627 return (0);
6628 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
6629
6630 AscMemWordCopyPtrFromLram(iop_base,
6631 ASCV_MSGIN_BEG,
6632 (uchar *)&ext_msg,
6633 sizeof(EXT_MSG) >> 1);
6634
47d853cc
MW
6635 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6636 ext_msg.msg_req == EXTENDED_SDTR &&
27c868c2
MW
6637 ext_msg.msg_len == MS_SDTR_LEN) {
6638 sdtr_accept = TRUE;
6639 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
6640
6641 sdtr_accept = FALSE;
6642 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
6643 }
6644 if ((ext_msg.xfer_period <
6645 asc_dvc->sdtr_period_tbl[asc_dvc->
6646 host_init_sdtr_index])
6647 || (ext_msg.xfer_period >
6648 asc_dvc->sdtr_period_tbl[asc_dvc->
6649 max_sdtr_index])) {
6650 sdtr_accept = FALSE;
6651 ext_msg.xfer_period =
6652 asc_dvc->sdtr_period_tbl[asc_dvc->
6653 host_init_sdtr_index];
6654 }
6655 if (sdtr_accept) {
6656 sdtr_data =
6657 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
6658 ext_msg.req_ack_offset);
6659 if ((sdtr_data == 0xFF)) {
6660
6661 q_cntl |= QC_MSG_OUT;
6662 asc_dvc->init_sdtr &= ~target_id;
6663 asc_dvc->sdtr_done &= ~target_id;
6664 AscSetChipSDTR(iop_base, asyn_sdtr,
6665 tid_no);
6666 boardp->sdtr_data[tid_no] = asyn_sdtr;
6667 }
6668 }
6669 if (ext_msg.req_ack_offset == 0) {
6670
6671 q_cntl &= ~QC_MSG_OUT;
6672 asc_dvc->init_sdtr &= ~target_id;
6673 asc_dvc->sdtr_done &= ~target_id;
6674 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6675 } else {
6676 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
6677
6678 q_cntl &= ~QC_MSG_OUT;
6679 asc_dvc->sdtr_done |= target_id;
6680 asc_dvc->init_sdtr |= target_id;
6681 asc_dvc->pci_fix_asyn_xfer &=
6682 ~target_id;
6683 sdtr_data =
6684 AscCalSDTRData(asc_dvc,
6685 ext_msg.xfer_period,
6686 ext_msg.
6687 req_ack_offset);
6688 AscSetChipSDTR(iop_base, sdtr_data,
6689 tid_no);
6690 boardp->sdtr_data[tid_no] = sdtr_data;
6691 } else {
6692
6693 q_cntl |= QC_MSG_OUT;
6694 AscMsgOutSDTR(asc_dvc,
6695 ext_msg.xfer_period,
6696 ext_msg.req_ack_offset);
6697 asc_dvc->pci_fix_asyn_xfer &=
6698 ~target_id;
6699 sdtr_data =
6700 AscCalSDTRData(asc_dvc,
6701 ext_msg.xfer_period,
6702 ext_msg.
6703 req_ack_offset);
6704 AscSetChipSDTR(iop_base, sdtr_data,
6705 tid_no);
6706 boardp->sdtr_data[tid_no] = sdtr_data;
6707 asc_dvc->sdtr_done |= target_id;
6708 asc_dvc->init_sdtr |= target_id;
6709 }
6710 }
6711
6712 AscWriteLramByte(iop_base,
6713 (ushort)(halt_q_addr +
6714 (ushort)ASC_SCSIQ_B_CNTL),
6715 q_cntl);
6716 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6717 return (0);
47d853cc
MW
6718 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6719 ext_msg.msg_req == EXTENDED_WDTR &&
27c868c2
MW
6720 ext_msg.msg_len == MS_WDTR_LEN) {
6721
6722 ext_msg.wdtr_width = 0;
6723 AscMemWordCopyPtrToLram(iop_base,
6724 ASCV_MSGOUT_BEG,
6725 (uchar *)&ext_msg,
6726 sizeof(EXT_MSG) >> 1);
6727 q_cntl |= QC_MSG_OUT;
6728 AscWriteLramByte(iop_base,
6729 (ushort)(halt_q_addr +
6730 (ushort)ASC_SCSIQ_B_CNTL),
6731 q_cntl);
6732 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6733 return (0);
6734 } else {
6735
6736 ext_msg.msg_type = MESSAGE_REJECT;
6737 AscMemWordCopyPtrToLram(iop_base,
6738 ASCV_MSGOUT_BEG,
6739 (uchar *)&ext_msg,
6740 sizeof(EXT_MSG) >> 1);
6741 q_cntl |= QC_MSG_OUT;
6742 AscWriteLramByte(iop_base,
6743 (ushort)(halt_q_addr +
6744 (ushort)ASC_SCSIQ_B_CNTL),
6745 q_cntl);
6746 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6747 return (0);
6748 }
6749 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
6750
6751 q_cntl |= QC_REQ_SENSE;
6752
6753 if ((asc_dvc->init_sdtr & target_id) != 0) {
6754
6755 asc_dvc->sdtr_done &= ~target_id;
6756
6757 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
6758 q_cntl |= QC_MSG_OUT;
6759 AscMsgOutSDTR(asc_dvc,
6760 asc_dvc->
6761 sdtr_period_tbl[(sdtr_data >> 4) &
6762 (uchar)(asc_dvc->
6763 max_sdtr_index -
6764 1)],
6765 (uchar)(sdtr_data & (uchar)
6766 ASC_SYN_MAX_OFFSET));
6767 }
6768
6769 AscWriteLramByte(iop_base,
6770 (ushort)(halt_q_addr +
6771 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6772
6773 tag_code = AscReadLramByte(iop_base,
6774 (ushort)(halt_q_addr + (ushort)
6775 ASC_SCSIQ_B_TAG_CODE));
6776 tag_code &= 0xDC;
6777 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
6778 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
6779 ) {
6780
6781 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
6782 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
6783
6784 }
6785 AscWriteLramByte(iop_base,
6786 (ushort)(halt_q_addr +
6787 (ushort)ASC_SCSIQ_B_TAG_CODE),
6788 tag_code);
6789
6790 q_status = AscReadLramByte(iop_base,
6791 (ushort)(halt_q_addr + (ushort)
6792 ASC_SCSIQ_B_STATUS));
6793 q_status |= (QS_READY | QS_BUSY);
6794 AscWriteLramByte(iop_base,
6795 (ushort)(halt_q_addr +
6796 (ushort)ASC_SCSIQ_B_STATUS),
6797 q_status);
6798
6799 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
6800 scsi_busy &= ~target_id;
6801 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6802
6803 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6804 return (0);
6805 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
6806
6807 AscMemWordCopyPtrFromLram(iop_base,
6808 ASCV_MSGOUT_BEG,
6809 (uchar *)&out_msg,
6810 sizeof(EXT_MSG) >> 1);
6811
47d853cc 6812 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
27c868c2 6813 (out_msg.msg_len == MS_SDTR_LEN) &&
47d853cc 6814 (out_msg.msg_req == EXTENDED_SDTR)) {
27c868c2
MW
6815
6816 asc_dvc->init_sdtr &= ~target_id;
6817 asc_dvc->sdtr_done &= ~target_id;
6818 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6819 boardp->sdtr_data[tid_no] = asyn_sdtr;
6820 }
6821 q_cntl &= ~QC_MSG_OUT;
6822 AscWriteLramByte(iop_base,
6823 (ushort)(halt_q_addr +
6824 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6825 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6826 return (0);
6827 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
6828
6829 scsi_status = AscReadLramByte(iop_base,
6830 (ushort)((ushort)halt_q_addr +
6831 (ushort)
6832 ASC_SCSIQ_SCSI_STATUS));
6833 cur_dvc_qng =
6834 AscReadLramByte(iop_base,
6835 (ushort)((ushort)ASC_QADR_BEG +
6836 (ushort)target_ix));
6837 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
6838
6839 scsi_busy = AscReadLramByte(iop_base,
6840 (ushort)ASCV_SCSIBUSY_B);
6841 scsi_busy |= target_id;
6842 AscWriteLramByte(iop_base,
6843 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6844 asc_dvc->queue_full_or_busy |= target_id;
6845
6846 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
6847 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
6848 cur_dvc_qng -= 1;
6849 asc_dvc->max_dvc_qng[tid_no] =
6850 cur_dvc_qng;
6851
6852 AscWriteLramByte(iop_base,
6853 (ushort)((ushort)
6854 ASCV_MAX_DVC_QNG_BEG
6855 + (ushort)
6856 tid_no),
6857 cur_dvc_qng);
6858
6859 /*
6860 * Set the device queue depth to the number of
6861 * active requests when the QUEUE FULL condition
6862 * was encountered.
6863 */
6864 boardp->queue_full |= target_id;
6865 boardp->queue_full_cnt[tid_no] =
6866 cur_dvc_qng;
6867 }
6868 }
6869 }
6870 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6871 return (0);
6872 }
1da177e4 6873#if CC_VERY_LONG_SG_LIST
27c868c2
MW
6874 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
6875 uchar q_no;
6876 ushort q_addr;
6877 uchar sg_wk_q_no;
6878 uchar first_sg_wk_q_no;
6879 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
6880 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
6881 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
6882 ushort sg_list_dwords;
6883 ushort sg_entry_cnt;
6884 uchar next_qp;
6885 int i;
6886
6887 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
6888 if (q_no == ASC_QLINK_END) {
6889 return (0);
6890 }
6891
6892 q_addr = ASC_QNO_TO_QADDR(q_no);
6893
6894 /*
6895 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
6896 * structure pointer using a macro provided by the driver.
6897 * The ASC_SCSI_REQ pointer provides a pointer to the
6898 * host ASC_SG_HEAD structure.
6899 */
6900 /* Read request's SRB pointer. */
6901 scsiq = (ASC_SCSI_Q *)
6902 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
6903 (ushort)
6904 (q_addr +
6905 ASC_SCSIQ_D_SRBPTR))));
6906
6907 /*
6908 * Get request's first and working SG queue.
6909 */
6910 sg_wk_q_no = AscReadLramByte(iop_base,
6911 (ushort)(q_addr +
6912 ASC_SCSIQ_B_SG_WK_QP));
6913
6914 first_sg_wk_q_no = AscReadLramByte(iop_base,
6915 (ushort)(q_addr +
6916 ASC_SCSIQ_B_FIRST_SG_WK_QP));
6917
6918 /*
6919 * Reset request's working SG queue back to the
6920 * first SG queue.
6921 */
6922 AscWriteLramByte(iop_base,
6923 (ushort)(q_addr +
6924 (ushort)ASC_SCSIQ_B_SG_WK_QP),
6925 first_sg_wk_q_no);
6926
6927 sg_head = scsiq->sg_head;
6928
6929 /*
6930 * Set sg_entry_cnt to the number of SG elements
6931 * that will be completed on this interrupt.
6932 *
6933 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
6934 * SG elements. The data_cnt and data_addr fields which
6935 * add 1 to the SG element capacity are not used when
6936 * restarting SG handling after a halt.
6937 */
6938 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
6939 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
6940
6941 /*
6942 * Keep track of remaining number of SG elements that will
6943 * need to be handled on the next interrupt.
6944 */
6945 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
6946 } else {
6947 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
6948 scsiq->remain_sg_entry_cnt = 0;
6949 }
6950
6951 /*
6952 * Copy SG elements into the list of allocated SG queues.
6953 *
6954 * Last index completed is saved in scsiq->next_sg_index.
6955 */
6956 next_qp = first_sg_wk_q_no;
6957 q_addr = ASC_QNO_TO_QADDR(next_qp);
6958 scsi_sg_q.sg_head_qp = q_no;
6959 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
6960 for (i = 0; i < sg_head->queue_cnt; i++) {
6961 scsi_sg_q.seq_no = i + 1;
6962 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
6963 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
6964 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
6965 /*
6966 * After very first SG queue RISC FW uses next
6967 * SG queue first element then checks sg_list_cnt
6968 * against zero and then decrements, so set
6969 * sg_list_cnt 1 less than number of SG elements
6970 * in each SG queue.
6971 */
6972 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
6973 scsi_sg_q.sg_cur_list_cnt =
6974 ASC_SG_LIST_PER_Q - 1;
6975 } else {
6976 /*
6977 * This is the last SG queue in the list of
6978 * allocated SG queues. If there are more
6979 * SG elements than will fit in the allocated
6980 * queues, then set the QCSG_SG_XFER_MORE flag.
6981 */
6982 if (scsiq->remain_sg_entry_cnt != 0) {
6983 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
6984 } else {
6985 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
6986 }
6987 /* equals sg_entry_cnt * 2 */
6988 sg_list_dwords = sg_entry_cnt << 1;
6989 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
6990 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
6991 sg_entry_cnt = 0;
6992 }
6993
6994 scsi_sg_q.q_no = next_qp;
6995 AscMemWordCopyPtrToLram(iop_base,
6996 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
6997 (uchar *)&scsi_sg_q,
6998 sizeof(ASC_SG_LIST_Q) >> 1);
6999
7000 AscMemDWordCopyPtrToLram(iop_base,
7001 q_addr + ASC_SGQ_LIST_BEG,
7002 (uchar *)&sg_head->
7003 sg_list[scsiq->next_sg_index],
7004 sg_list_dwords);
7005
7006 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
7007
7008 /*
7009 * If the just completed SG queue contained the
7010 * last SG element, then no more SG queues need
7011 * to be written.
7012 */
7013 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
7014 break;
7015 }
7016
7017 next_qp = AscReadLramByte(iop_base,
7018 (ushort)(q_addr +
7019 ASC_SCSIQ_B_FWD));
7020 q_addr = ASC_QNO_TO_QADDR(next_qp);
7021 }
7022
7023 /*
7024 * Clear the halt condition so the RISC will be restarted
7025 * after the return.
7026 */
7027 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7028 return (0);
7029 }
1da177e4 7030#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 7031 return (0);
1da177e4
LT
7032}
7033
27c868c2
MW
7034static uchar
7035_AscCopyLramScsiDoneQ(PortAddr iop_base,
7036 ushort q_addr,
7037 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 7038{
27c868c2
MW
7039 ushort _val;
7040 uchar sg_queue_cnt;
7041
7042 DvcGetQinfo(iop_base,
7043 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
7044 (uchar *)scsiq,
7045 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
7046
7047 _val = AscReadLramWord(iop_base,
7048 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
7049 scsiq->q_status = (uchar)_val;
7050 scsiq->q_no = (uchar)(_val >> 8);
7051 _val = AscReadLramWord(iop_base,
7052 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
7053 scsiq->cntl = (uchar)_val;
7054 sg_queue_cnt = (uchar)(_val >> 8);
7055 _val = AscReadLramWord(iop_base,
7056 (ushort)(q_addr +
7057 (ushort)ASC_SCSIQ_B_SENSE_LEN));
7058 scsiq->sense_len = (uchar)_val;
7059 scsiq->extra_bytes = (uchar)(_val >> 8);
7060
7061 /*
7062 * Read high word of remain bytes from alternate location.
7063 */
7064 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
7065 (ushort)(q_addr +
7066 (ushort)
7067 ASC_SCSIQ_W_ALT_DC1)))
7068 << 16);
7069 /*
7070 * Read low word of remain bytes from original location.
7071 */
7072 scsiq->remain_bytes += AscReadLramWord(iop_base,
7073 (ushort)(q_addr + (ushort)
7074 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
7075
7076 scsiq->remain_bytes &= max_dma_count;
7077 return (sg_queue_cnt);
1da177e4
LT
7078}
7079
27c868c2 7080static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 7081{
27c868c2
MW
7082 uchar next_qp;
7083 uchar n_q_used;
7084 uchar sg_list_qp;
7085 uchar sg_queue_cnt;
7086 uchar q_cnt;
7087 uchar done_q_tail;
7088 uchar tid_no;
7089 ASC_SCSI_BIT_ID_TYPE scsi_busy;
7090 ASC_SCSI_BIT_ID_TYPE target_id;
7091 PortAddr iop_base;
7092 ushort q_addr;
7093 ushort sg_q_addr;
7094 uchar cur_target_qng;
7095 ASC_QDONE_INFO scsiq_buf;
7096 ASC_QDONE_INFO *scsiq;
7097 int false_overrun;
27c868c2
MW
7098
7099 iop_base = asc_dvc->iop_base;
27c868c2
MW
7100 n_q_used = 1;
7101 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
7102 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
7103 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
7104 next_qp = AscReadLramByte(iop_base,
7105 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
7106 if (next_qp != ASC_QLINK_END) {
7107 AscPutVarDoneQTail(iop_base, next_qp);
7108 q_addr = ASC_QNO_TO_QADDR(next_qp);
7109 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
7110 asc_dvc->max_dma_count);
7111 AscWriteLramByte(iop_base,
7112 (ushort)(q_addr +
7113 (ushort)ASC_SCSIQ_B_STATUS),
7114 (uchar)(scsiq->
7115 q_status & (uchar)~(QS_READY |
7116 QS_ABORTED)));
7117 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
7118 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
7119 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
7120 sg_q_addr = q_addr;
7121 sg_list_qp = next_qp;
7122 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
7123 sg_list_qp = AscReadLramByte(iop_base,
7124 (ushort)(sg_q_addr
7125 + (ushort)
7126 ASC_SCSIQ_B_FWD));
7127 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
7128 if (sg_list_qp == ASC_QLINK_END) {
7129 AscSetLibErrorCode(asc_dvc,
7130 ASCQ_ERR_SG_Q_LINKS);
7131 scsiq->d3.done_stat = QD_WITH_ERROR;
7132 scsiq->d3.host_stat =
7133 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
7134 goto FATAL_ERR_QDONE;
7135 }
7136 AscWriteLramByte(iop_base,
7137 (ushort)(sg_q_addr + (ushort)
7138 ASC_SCSIQ_B_STATUS),
7139 QS_FREE);
7140 }
7141 n_q_used = sg_queue_cnt + 1;
7142 AscPutVarDoneQTail(iop_base, sg_list_qp);
7143 }
7144 if (asc_dvc->queue_full_or_busy & target_id) {
7145 cur_target_qng = AscReadLramByte(iop_base,
7146 (ushort)((ushort)
7147 ASC_QADR_BEG
7148 + (ushort)
7149 scsiq->d2.
7150 target_ix));
7151 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
7152 scsi_busy = AscReadLramByte(iop_base, (ushort)
7153 ASCV_SCSIBUSY_B);
7154 scsi_busy &= ~target_id;
7155 AscWriteLramByte(iop_base,
7156 (ushort)ASCV_SCSIBUSY_B,
7157 scsi_busy);
7158 asc_dvc->queue_full_or_busy &= ~target_id;
7159 }
7160 }
7161 if (asc_dvc->cur_total_qng >= n_q_used) {
7162 asc_dvc->cur_total_qng -= n_q_used;
7163 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
7164 asc_dvc->cur_dvc_qng[tid_no]--;
7165 }
7166 } else {
7167 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
7168 scsiq->d3.done_stat = QD_WITH_ERROR;
7169 goto FATAL_ERR_QDONE;
7170 }
7171 if ((scsiq->d2.srb_ptr == 0UL) ||
7172 ((scsiq->q_status & QS_ABORTED) != 0)) {
7173 return (0x11);
7174 } else if (scsiq->q_status == QS_DONE) {
7175 false_overrun = FALSE;
7176 if (scsiq->extra_bytes != 0) {
7177 scsiq->remain_bytes +=
7178 (ADV_DCNT)scsiq->extra_bytes;
7179 }
7180 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
7181 if (scsiq->d3.host_stat ==
7182 QHSTA_M_DATA_OVER_RUN) {
7183 if ((scsiq->
7184 cntl & (QC_DATA_IN | QC_DATA_OUT))
7185 == 0) {
7186 scsiq->d3.done_stat =
7187 QD_NO_ERROR;
7188 scsiq->d3.host_stat =
7189 QHSTA_NO_ERROR;
7190 } else if (false_overrun) {
7191 scsiq->d3.done_stat =
7192 QD_NO_ERROR;
7193 scsiq->d3.host_stat =
7194 QHSTA_NO_ERROR;
7195 }
7196 } else if (scsiq->d3.host_stat ==
7197 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
7198 AscStopChip(iop_base);
7199 AscSetChipControl(iop_base,
7200 (uchar)(CC_SCSI_RESET
7201 | CC_HALT));
7202 DvcDelayNanoSecond(asc_dvc, 60000);
7203 AscSetChipControl(iop_base, CC_HALT);
7204 AscSetChipStatus(iop_base,
7205 CIW_CLR_SCSI_RESET_INT);
7206 AscSetChipStatus(iop_base, 0);
7207 AscSetChipControl(iop_base, 0);
7208 }
7209 }
7210 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 7211 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
7212 } else {
7213 if ((AscReadLramByte(iop_base,
7214 (ushort)(q_addr + (ushort)
7215 ASC_SCSIQ_CDB_BEG))
7216 == START_STOP)) {
7217 asc_dvc->unit_not_ready &= ~target_id;
7218 if (scsiq->d3.done_stat != QD_NO_ERROR) {
7219 asc_dvc->start_motor &=
7220 ~target_id;
7221 }
7222 }
7223 }
7224 return (1);
7225 } else {
7226 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
7227 FATAL_ERR_QDONE:
7228 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 7229 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
7230 }
7231 return (0x80);
7232 }
7233 }
7234 return (0);
1da177e4
LT
7235}
7236
27c868c2 7237static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 7238{
27c868c2
MW
7239 ASC_CS_TYPE chipstat;
7240 PortAddr iop_base;
7241 ushort saved_ram_addr;
7242 uchar ctrl_reg;
7243 uchar saved_ctrl_reg;
7244 int int_pending;
7245 int status;
7246 uchar host_flag;
7247
7248 iop_base = asc_dvc->iop_base;
7249 int_pending = FALSE;
7250
7251 if (AscIsIntPending(iop_base) == 0) {
7252 return int_pending;
7253 }
1da177e4 7254
895d6b4c 7255 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
27c868c2
MW
7256 return (ERR);
7257 }
7258 if (asc_dvc->in_critical_cnt != 0) {
7259 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
7260 return (ERR);
7261 }
7262 if (asc_dvc->is_in_int) {
7263 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
7264 return (ERR);
7265 }
7266 asc_dvc->is_in_int = TRUE;
7267 ctrl_reg = AscGetChipControl(iop_base);
7268 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
7269 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
7270 chipstat = AscGetChipStatus(iop_base);
7271 if (chipstat & CSW_SCSI_RESET_LATCH) {
7272 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
7273 int i = 10;
7274 int_pending = TRUE;
7275 asc_dvc->sdtr_done = 0;
7276 saved_ctrl_reg &= (uchar)(~CC_HALT);
7277 while ((AscGetChipStatus(iop_base) &
7278 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
7279 DvcSleepMilliSecond(100);
7280 }
7281 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
7282 AscSetChipControl(iop_base, CC_HALT);
7283 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
7284 AscSetChipStatus(iop_base, 0);
7285 chipstat = AscGetChipStatus(iop_base);
7286 }
7287 }
7288 saved_ram_addr = AscGetChipLramAddr(iop_base);
7289 host_flag = AscReadLramByte(iop_base,
7290 ASCV_HOST_FLAG_B) &
7291 (uchar)(~ASC_HOST_FLAG_IN_ISR);
7292 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
7293 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
7294 if ((chipstat & CSW_INT_PENDING)
7295 || (int_pending)
7296 ) {
7297 AscAckInterrupt(iop_base);
7298 int_pending = TRUE;
7299 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
7300 if (AscIsrChipHalted(asc_dvc) == ERR) {
7301 goto ISR_REPORT_QDONE_FATAL_ERROR;
7302 } else {
7303 saved_ctrl_reg &= (uchar)(~CC_HALT);
7304 }
7305 } else {
7306 ISR_REPORT_QDONE_FATAL_ERROR:
7307 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
7308 while (((status =
7309 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
7310 }
7311 } else {
7312 do {
7313 if ((status =
7314 AscIsrQDone(asc_dvc)) == 1) {
7315 break;
7316 }
7317 } while (status == 0x11);
7318 }
7319 if ((status & 0x80) != 0)
7320 int_pending = ERR;
7321 }
7322 }
7323 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
7324 AscSetChipLramAddr(iop_base, saved_ram_addr);
7325 AscSetChipControl(iop_base, saved_ctrl_reg);
7326 asc_dvc->is_in_int = FALSE;
7327 return (int_pending);
1da177e4
LT
7328}
7329
7330/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
7331static uchar _asc_mcode_buf[] = {
7332 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d 7333 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
27c868c2 7334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d
MW
7336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
7338 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7339 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7340 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
629d688d
MW
7341 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
7342 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
7343 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
27c868c2 7344 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
629d688d
MW
7345 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
7346 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
7347 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
27c868c2 7348 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
629d688d
MW
7349 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
7350 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
7351 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
27c868c2 7352 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
629d688d
MW
7353 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
7354 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
7355 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
27c868c2 7356 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
629d688d
MW
7357 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
7358 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
7359 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
27c868c2 7360 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
629d688d
MW
7361 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
7362 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
7363 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
27c868c2 7364 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
629d688d
MW
7365 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
7366 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
7367 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
27c868c2 7368 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
629d688d
MW
7369 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
7370 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
7371 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
27c868c2 7372 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
629d688d
MW
7373 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
7374 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
7375 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
27c868c2 7376 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
629d688d
MW
7377 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
7378 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
7379 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
27c868c2 7380 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
629d688d
MW
7381 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
7382 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
7383 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
27c868c2 7384 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
629d688d
MW
7385 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
7386 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
7387 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
27c868c2 7388 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
629d688d
MW
7389 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
7390 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
7391 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
27c868c2 7392 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
629d688d
MW
7393 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
7394 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
7395 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
27c868c2 7396 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
629d688d
MW
7397 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
7398 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
7399 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
27c868c2 7400 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
629d688d
MW
7401 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
7402 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
7403 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
27c868c2 7404 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
629d688d
MW
7405 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
7406 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
7407 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
27c868c2 7408 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
629d688d
MW
7409 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
7410 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
7411 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
27c868c2 7412 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
629d688d
MW
7413 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
7414 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
7415 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
27c868c2 7416 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
629d688d
MW
7417 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
7418 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
7419 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
27c868c2 7420 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
629d688d
MW
7421 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
7422 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
7423 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
27c868c2 7424 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
629d688d
MW
7425 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
7426 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
7427 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
27c868c2 7428 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
629d688d
MW
7429 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
7430 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
7431 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
27c868c2 7432 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
629d688d
MW
7433 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
7434 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
7435 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
27c868c2 7436 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
629d688d
MW
7437 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
7438 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
7439 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
27c868c2 7440 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
629d688d
MW
7441 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
7442 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
7443 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
27c868c2 7444 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
7445 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
7446 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
7447 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
27c868c2 7448 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
629d688d
MW
7449 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
7450 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
7451 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
27c868c2 7452 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
629d688d
MW
7453 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
7454 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
7455 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
27c868c2 7456 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
629d688d
MW
7457 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
7458 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
7459 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
27c868c2 7460 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
629d688d
MW
7461 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
7462 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
7463 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
27c868c2 7464 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
629d688d
MW
7465 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
7466 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
7467 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
27c868c2 7468 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
629d688d
MW
7469 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
7470 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
7471 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
27c868c2 7472 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
629d688d
MW
7473 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
7474 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
7475 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
27c868c2 7476 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
629d688d
MW
7477 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
7478 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
7479 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
27c868c2 7480 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
629d688d
MW
7481 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
7482 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
7483 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
27c868c2 7484 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
629d688d
MW
7485 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
7486 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
7487 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
27c868c2 7488 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
629d688d
MW
7489 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
7490 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
7491 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
27c868c2 7492 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
629d688d
MW
7493 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
7494 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
7495 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
27c868c2 7496 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
629d688d
MW
7497 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
7498 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
7499 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
27c868c2 7500 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
7501 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
7502 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
7503 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
27c868c2 7504 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
629d688d
MW
7505 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
7506 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
7507 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
27c868c2 7508 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
629d688d
MW
7509 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
7510 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
7511 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
27c868c2 7512 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
629d688d
MW
7513 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
7514 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
7515 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
27c868c2 7516 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
629d688d
MW
7517 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
7518 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
7519 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
27c868c2 7520 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
629d688d
MW
7521 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
7522 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
7523 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
7524};
7525
27c868c2
MW
7526static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
7527static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
7528
7529#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
7530static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
7531 INQUIRY,
7532 REQUEST_SENSE,
7533 READ_CAPACITY,
7534 READ_TOC,
7535 MODE_SELECT,
7536 MODE_SENSE,
7537 MODE_SELECT_10,
7538 MODE_SENSE_10,
7539 0xFF,
7540 0xFF,
7541 0xFF,
7542 0xFF,
7543 0xFF,
7544 0xFF,
7545 0xFF,
7546 0xFF
1da177e4
LT
7547};
7548
27c868c2 7549static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 7550{
27c868c2
MW
7551 PortAddr iop_base;
7552 ulong last_int_level;
7553 int sta;
7554 int n_q_required;
7555 int disable_syn_offset_one_fix;
7556 int i;
7557 ASC_PADDR addr;
27c868c2
MW
7558 ushort sg_entry_cnt = 0;
7559 ushort sg_entry_cnt_minus_one = 0;
7560 uchar target_ix;
7561 uchar tid_no;
7562 uchar sdtr_data;
7563 uchar extra_bytes;
7564 uchar scsi_cmd;
7565 uchar disable_cmd;
7566 ASC_SG_HEAD *sg_head;
7567 ASC_DCNT data_cnt;
7568
7569 iop_base = asc_dvc->iop_base;
7570 sg_head = scsiq->sg_head;
27c868c2
MW
7571 if (asc_dvc->err_code != 0)
7572 return (ERR);
27c868c2
MW
7573 scsiq->q1.q_no = 0;
7574 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
7575 scsiq->q1.extra_bytes = 0;
7576 }
7577 sta = 0;
7578 target_ix = scsiq->q2.target_ix;
7579 tid_no = ASC_TIX_TO_TID(target_ix);
7580 n_q_required = 1;
7581 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
7582 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
7583 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
7584 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7585 AscMsgOutSDTR(asc_dvc,
7586 asc_dvc->
7587 sdtr_period_tbl[(sdtr_data >> 4) &
7588 (uchar)(asc_dvc->
7589 max_sdtr_index -
7590 1)],
7591 (uchar)(sdtr_data & (uchar)
7592 ASC_SYN_MAX_OFFSET));
7593 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
7594 }
7595 }
7596 last_int_level = DvcEnterCritical();
7597 if (asc_dvc->in_critical_cnt != 0) {
7598 DvcLeaveCritical(last_int_level);
7599 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
7600 return (ERR);
7601 }
7602 asc_dvc->in_critical_cnt++;
7603 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
7604 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
7605 asc_dvc->in_critical_cnt--;
7606 DvcLeaveCritical(last_int_level);
7607 return (ERR);
7608 }
1da177e4 7609#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
7610 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
7611 asc_dvc->in_critical_cnt--;
7612 DvcLeaveCritical(last_int_level);
7613 return (ERR);
7614 }
1da177e4 7615#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
7616 if (sg_entry_cnt == 1) {
7617 scsiq->q1.data_addr =
7618 (ADV_PADDR)sg_head->sg_list[0].addr;
7619 scsiq->q1.data_cnt =
7620 (ADV_DCNT)sg_head->sg_list[0].bytes;
7621 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
7622 }
7623 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
7624 }
7625 scsi_cmd = scsiq->cdbptr[0];
7626 disable_syn_offset_one_fix = FALSE;
7627 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
7628 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
7629 if (scsiq->q1.cntl & QC_SG_HEAD) {
7630 data_cnt = 0;
7631 for (i = 0; i < sg_entry_cnt; i++) {
7632 data_cnt +=
7633 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
7634 bytes);
7635 }
7636 } else {
7637 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
7638 }
7639 if (data_cnt != 0UL) {
7640 if (data_cnt < 512UL) {
7641 disable_syn_offset_one_fix = TRUE;
7642 } else {
7643 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
7644 i++) {
7645 disable_cmd =
7646 _syn_offset_one_disable_cmd[i];
7647 if (disable_cmd == 0xFF) {
7648 break;
7649 }
7650 if (scsi_cmd == disable_cmd) {
7651 disable_syn_offset_one_fix =
7652 TRUE;
7653 break;
7654 }
7655 }
7656 }
7657 }
7658 }
7659 if (disable_syn_offset_one_fix) {
7660 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
7661 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
7662 ASC_TAG_FLAG_DISABLE_DISCONNECT);
7663 } else {
7664 scsiq->q2.tag_code &= 0x27;
7665 }
7666 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
7667 if (asc_dvc->bug_fix_cntl) {
7668 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
7669 if ((scsi_cmd == READ_6) ||
7670 (scsi_cmd == READ_10)) {
7671 addr =
7672 (ADV_PADDR)le32_to_cpu(sg_head->
7673 sg_list
7674 [sg_entry_cnt_minus_one].
7675 addr) +
7676 (ADV_DCNT)le32_to_cpu(sg_head->
7677 sg_list
7678 [sg_entry_cnt_minus_one].
7679 bytes);
7680 extra_bytes =
7681 (uchar)((ushort)addr & 0x0003);
7682 if ((extra_bytes != 0)
7683 &&
7684 ((scsiq->q2.
7685 tag_code &
7686 ASC_TAG_FLAG_EXTRA_BYTES)
7687 == 0)) {
7688 scsiq->q2.tag_code |=
7689 ASC_TAG_FLAG_EXTRA_BYTES;
7690 scsiq->q1.extra_bytes =
7691 extra_bytes;
7692 data_cnt =
7693 le32_to_cpu(sg_head->
7694 sg_list
7695 [sg_entry_cnt_minus_one].
7696 bytes);
7697 data_cnt -=
7698 (ASC_DCNT) extra_bytes;
7699 sg_head->
7700 sg_list
7701 [sg_entry_cnt_minus_one].
7702 bytes =
7703 cpu_to_le32(data_cnt);
7704 }
7705 }
7706 }
7707 }
7708 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 7709#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7710 /*
7711 * Set the sg_entry_cnt to the maximum possible. The rest of
7712 * the SG elements will be copied when the RISC completes the
7713 * SG elements that fit and halts.
7714 */
7715 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
7716 sg_entry_cnt = ASC_MAX_SG_LIST;
7717 }
1da177e4 7718#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7719 n_q_required = AscSgListToQueue(sg_entry_cnt);
7720 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
7721 (uint) n_q_required)
7722 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
7723 if ((sta =
7724 AscSendScsiQueue(asc_dvc, scsiq,
7725 n_q_required)) == 1) {
7726 asc_dvc->in_critical_cnt--;
27c868c2
MW
7727 DvcLeaveCritical(last_int_level);
7728 return (sta);
7729 }
7730 }
7731 } else {
7732 if (asc_dvc->bug_fix_cntl) {
7733 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
7734 if ((scsi_cmd == READ_6) ||
7735 (scsi_cmd == READ_10)) {
7736 addr =
7737 le32_to_cpu(scsiq->q1.data_addr) +
7738 le32_to_cpu(scsiq->q1.data_cnt);
7739 extra_bytes =
7740 (uchar)((ushort)addr & 0x0003);
7741 if ((extra_bytes != 0)
7742 &&
7743 ((scsiq->q2.
7744 tag_code &
7745 ASC_TAG_FLAG_EXTRA_BYTES)
7746 == 0)) {
7747 data_cnt =
7748 le32_to_cpu(scsiq->q1.
7749 data_cnt);
7750 if (((ushort)data_cnt & 0x01FF)
7751 == 0) {
7752 scsiq->q2.tag_code |=
7753 ASC_TAG_FLAG_EXTRA_BYTES;
7754 data_cnt -= (ASC_DCNT)
7755 extra_bytes;
7756 scsiq->q1.data_cnt =
7757 cpu_to_le32
7758 (data_cnt);
7759 scsiq->q1.extra_bytes =
7760 extra_bytes;
7761 }
7762 }
7763 }
7764 }
7765 }
7766 n_q_required = 1;
7767 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
7768 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
7769 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
7770 n_q_required)) == 1) {
7771 asc_dvc->in_critical_cnt--;
27c868c2
MW
7772 DvcLeaveCritical(last_int_level);
7773 return (sta);
7774 }
7775 }
7776 }
7777 asc_dvc->in_critical_cnt--;
7778 DvcLeaveCritical(last_int_level);
7779 return (sta);
1da177e4
LT
7780}
7781
27c868c2
MW
7782static int
7783AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 7784{
27c868c2
MW
7785 PortAddr iop_base;
7786 uchar free_q_head;
7787 uchar next_qp;
7788 uchar tid_no;
7789 uchar target_ix;
7790 int sta;
7791
7792 iop_base = asc_dvc->iop_base;
7793 target_ix = scsiq->q2.target_ix;
7794 tid_no = ASC_TIX_TO_TID(target_ix);
7795 sta = 0;
7796 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
7797 if (n_q_required > 1) {
7798 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
7799 free_q_head, (uchar)
7800 (n_q_required)))
7801 != (uchar)ASC_QLINK_END) {
7802 asc_dvc->last_q_shortage = 0;
7803 scsiq->sg_head->queue_cnt = n_q_required - 1;
7804 scsiq->q1.q_no = free_q_head;
7805 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
7806 free_q_head)) == 1) {
7807 AscPutVarFreeQHead(iop_base, next_qp);
7808 asc_dvc->cur_total_qng += (uchar)(n_q_required);
7809 asc_dvc->cur_dvc_qng[tid_no]++;
7810 }
7811 return (sta);
7812 }
7813 } else if (n_q_required == 1) {
7814 if ((next_qp = AscAllocFreeQueue(iop_base,
7815 free_q_head)) !=
7816 ASC_QLINK_END) {
7817 scsiq->q1.q_no = free_q_head;
7818 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
7819 free_q_head)) == 1) {
7820 AscPutVarFreeQHead(iop_base, next_qp);
7821 asc_dvc->cur_total_qng++;
7822 asc_dvc->cur_dvc_qng[tid_no]++;
7823 }
7824 return (sta);
7825 }
7826 }
7827 return (sta);
1da177e4
LT
7828}
7829
27c868c2 7830static int AscSgListToQueue(int sg_list)
1da177e4 7831{
27c868c2 7832 int n_sg_list_qs;
1da177e4 7833
27c868c2
MW
7834 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
7835 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
7836 n_sg_list_qs++;
7837 return (n_sg_list_qs + 1);
1da177e4
LT
7838}
7839
27c868c2
MW
7840static uint
7841AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 7842{
27c868c2
MW
7843 uint cur_used_qs;
7844 uint cur_free_qs;
7845 ASC_SCSI_BIT_ID_TYPE target_id;
7846 uchar tid_no;
7847
7848 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
7849 tid_no = ASC_TIX_TO_TID(target_ix);
7850 if ((asc_dvc->unit_not_ready & target_id) ||
7851 (asc_dvc->queue_full_or_busy & target_id)) {
7852 return (0);
7853 }
7854 if (n_qs == 1) {
7855 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7856 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
7857 } else {
7858 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7859 (uint) ASC_MIN_FREE_Q;
7860 }
7861 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
7862 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
7863 if (asc_dvc->cur_dvc_qng[tid_no] >=
7864 asc_dvc->max_dvc_qng[tid_no]) {
7865 return (0);
7866 }
7867 return (cur_free_qs);
7868 }
7869 if (n_qs > 1) {
7870 if ((n_qs > asc_dvc->last_q_shortage)
7871 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
7872 asc_dvc->last_q_shortage = n_qs;
7873 }
7874 }
7875 return (0);
1da177e4
LT
7876}
7877
27c868c2 7878static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 7879{
27c868c2
MW
7880 ushort q_addr;
7881 uchar tid_no;
7882 uchar sdtr_data;
7883 uchar syn_period_ix;
7884 uchar syn_offset;
7885 PortAddr iop_base;
7886
7887 iop_base = asc_dvc->iop_base;
7888 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
7889 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
7890 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
7891 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7892 syn_period_ix =
7893 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
7894 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
7895 AscMsgOutSDTR(asc_dvc,
7896 asc_dvc->sdtr_period_tbl[syn_period_ix],
7897 syn_offset);
7898 scsiq->q1.cntl |= QC_MSG_OUT;
7899 }
7900 q_addr = ASC_QNO_TO_QADDR(q_no);
7901 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
7902 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
7903 }
7904 scsiq->q1.status = QS_FREE;
7905 AscMemWordCopyPtrToLram(iop_base,
7906 q_addr + ASC_SCSIQ_CDB_BEG,
7907 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
7908
7909 DvcPutScsiQ(iop_base,
7910 q_addr + ASC_SCSIQ_CPY_BEG,
7911 (uchar *)&scsiq->q1.cntl,
7912 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
7913 AscWriteLramWord(iop_base,
7914 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
7915 (ushort)(((ushort)scsiq->q1.
7916 q_no << 8) | (ushort)QS_READY));
7917 return (1);
1da177e4
LT
7918}
7919
27c868c2
MW
7920static int
7921AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 7922{
27c868c2
MW
7923 int sta;
7924 int i;
7925 ASC_SG_HEAD *sg_head;
7926 ASC_SG_LIST_Q scsi_sg_q;
7927 ASC_DCNT saved_data_addr;
7928 ASC_DCNT saved_data_cnt;
7929 PortAddr iop_base;
7930 ushort sg_list_dwords;
7931 ushort sg_index;
7932 ushort sg_entry_cnt;
7933 ushort q_addr;
7934 uchar next_qp;
7935
7936 iop_base = asc_dvc->iop_base;
7937 sg_head = scsiq->sg_head;
7938 saved_data_addr = scsiq->q1.data_addr;
7939 saved_data_cnt = scsiq->q1.data_cnt;
7940 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
7941 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 7942#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7943 /*
7944 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
7945 * then not all SG elements will fit in the allocated queues.
7946 * The rest of the SG elements will be copied when the RISC
7947 * completes the SG elements that fit and halts.
7948 */
7949 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
7950 /*
7951 * Set sg_entry_cnt to be the number of SG elements that
7952 * will fit in the allocated SG queues. It is minus 1, because
7953 * the first SG element is handled above. ASC_MAX_SG_LIST is
7954 * already inflated by 1 to account for this. For example it
7955 * may be 50 which is 1 + 7 queues * 7 SG elements.
7956 */
7957 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
7958
7959 /*
7960 * Keep track of remaining number of SG elements that will
7961 * need to be handled from a_isr.c.
7962 */
7963 scsiq->remain_sg_entry_cnt =
7964 sg_head->entry_cnt - ASC_MAX_SG_LIST;
7965 } else {
1da177e4 7966#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7967 /*
7968 * Set sg_entry_cnt to be the number of SG elements that
7969 * will fit in the allocated SG queues. It is minus 1, because
7970 * the first SG element is handled above.
7971 */
7972 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 7973#if CC_VERY_LONG_SG_LIST
27c868c2 7974 }
1da177e4 7975#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7976 if (sg_entry_cnt != 0) {
7977 scsiq->q1.cntl |= QC_SG_HEAD;
7978 q_addr = ASC_QNO_TO_QADDR(q_no);
7979 sg_index = 1;
7980 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
7981 scsi_sg_q.sg_head_qp = q_no;
7982 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
7983 for (i = 0; i < sg_head->queue_cnt; i++) {
7984 scsi_sg_q.seq_no = i + 1;
7985 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
7986 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
7987 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
7988 if (i == 0) {
7989 scsi_sg_q.sg_list_cnt =
7990 ASC_SG_LIST_PER_Q;
7991 scsi_sg_q.sg_cur_list_cnt =
7992 ASC_SG_LIST_PER_Q;
7993 } else {
7994 scsi_sg_q.sg_list_cnt =
7995 ASC_SG_LIST_PER_Q - 1;
7996 scsi_sg_q.sg_cur_list_cnt =
7997 ASC_SG_LIST_PER_Q - 1;
7998 }
7999 } else {
1da177e4 8000#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8001 /*
8002 * This is the last SG queue in the list of
8003 * allocated SG queues. If there are more
8004 * SG elements than will fit in the allocated
8005 * queues, then set the QCSG_SG_XFER_MORE flag.
8006 */
8007 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
8008 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8009 } else {
1da177e4 8010#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 8011 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 8012#if CC_VERY_LONG_SG_LIST
27c868c2 8013 }
1da177e4 8014#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
8015 sg_list_dwords = sg_entry_cnt << 1;
8016 if (i == 0) {
8017 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
8018 scsi_sg_q.sg_cur_list_cnt =
8019 sg_entry_cnt;
8020 } else {
8021 scsi_sg_q.sg_list_cnt =
8022 sg_entry_cnt - 1;
8023 scsi_sg_q.sg_cur_list_cnt =
8024 sg_entry_cnt - 1;
8025 }
8026 sg_entry_cnt = 0;
8027 }
8028 next_qp = AscReadLramByte(iop_base,
8029 (ushort)(q_addr +
8030 ASC_SCSIQ_B_FWD));
8031 scsi_sg_q.q_no = next_qp;
8032 q_addr = ASC_QNO_TO_QADDR(next_qp);
8033 AscMemWordCopyPtrToLram(iop_base,
8034 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8035 (uchar *)&scsi_sg_q,
8036 sizeof(ASC_SG_LIST_Q) >> 1);
8037 AscMemDWordCopyPtrToLram(iop_base,
8038 q_addr + ASC_SGQ_LIST_BEG,
8039 (uchar *)&sg_head->
8040 sg_list[sg_index],
8041 sg_list_dwords);
8042 sg_index += ASC_SG_LIST_PER_Q;
8043 scsiq->next_sg_index = sg_index;
8044 }
8045 } else {
8046 scsiq->q1.cntl &= ~QC_SG_HEAD;
8047 }
8048 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
8049 scsiq->q1.data_addr = saved_data_addr;
8050 scsiq->q1.data_cnt = saved_data_cnt;
8051 return (sta);
1da177e4
LT
8052}
8053
27c868c2
MW
8054static int
8055AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 8056{
27c868c2 8057 int sta = FALSE;
1da177e4 8058
27c868c2
MW
8059 if (AscHostReqRiscHalt(iop_base)) {
8060 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8061 AscStartChip(iop_base);
8062 return (sta);
8063 }
8064 return (sta);
1da177e4
LT
8065}
8066
27c868c2 8067static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 8068{
27c868c2
MW
8069 ASC_SCSI_BIT_ID_TYPE org_id;
8070 int i;
8071 int sta = TRUE;
8072
8073 AscSetBank(iop_base, 1);
8074 org_id = AscReadChipDvcID(iop_base);
8075 for (i = 0; i <= ASC_MAX_TID; i++) {
8076 if (org_id == (0x01 << i))
8077 break;
8078 }
8079 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8080 AscWriteChipDvcID(iop_base, id);
8081 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8082 AscSetBank(iop_base, 0);
8083 AscSetChipSyn(iop_base, sdtr_data);
8084 if (AscGetChipSyn(iop_base) != sdtr_data) {
8085 sta = FALSE;
8086 }
8087 } else {
8088 sta = FALSE;
8089 }
8090 AscSetBank(iop_base, 1);
8091 AscWriteChipDvcID(iop_base, org_id);
8092 AscSetBank(iop_base, 0);
8093 return (sta);
8094}
1da177e4 8095
27c868c2 8096static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 8097{
27c868c2
MW
8098 uchar i;
8099 ushort s_addr;
8100 PortAddr iop_base;
8101 ushort warn_code;
8102
8103 iop_base = asc_dvc->iop_base;
8104 warn_code = 0;
8105 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
8106 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
8107 64) >> 1)
8108 );
8109 i = ASC_MIN_ACTIVE_QNO;
8110 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
8111 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8112 (uchar)(i + 1));
8113 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8114 (uchar)(asc_dvc->max_total_qng));
8115 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8116 (uchar)i);
8117 i++;
8118 s_addr += ASC_QBLK_SIZE;
8119 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
8120 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8121 (uchar)(i + 1));
8122 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8123 (uchar)(i - 1));
8124 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8125 (uchar)i);
8126 }
8127 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8128 (uchar)ASC_QLINK_END);
8129 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8130 (uchar)(asc_dvc->max_total_qng - 1));
8131 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8132 (uchar)asc_dvc->max_total_qng);
8133 i++;
8134 s_addr += ASC_QBLK_SIZE;
8135 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
8136 i++, s_addr += ASC_QBLK_SIZE) {
8137 AscWriteLramByte(iop_base,
8138 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
8139 AscWriteLramByte(iop_base,
8140 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
8141 AscWriteLramByte(iop_base,
8142 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
8143 }
8144 return (warn_code);
1da177e4
LT
8145}
8146
27c868c2 8147static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8148{
27c868c2
MW
8149 PortAddr iop_base;
8150 int i;
8151 ushort lram_addr;
8152
8153 iop_base = asc_dvc->iop_base;
8154 AscPutRiscVarFreeQHead(iop_base, 1);
8155 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
8156 AscPutVarFreeQHead(iop_base, 1);
8157 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
8158 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
8159 (uchar)((int)asc_dvc->max_total_qng + 1));
8160 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
8161 (uchar)((int)asc_dvc->max_total_qng + 2));
8162 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
8163 asc_dvc->max_total_qng);
8164 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
8165 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8166 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
8167 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
8168 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
8169 AscPutQDoneInProgress(iop_base, 0);
8170 lram_addr = ASC_QADR_BEG;
8171 for (i = 0; i < 32; i++, lram_addr += 2) {
8172 AscWriteLramWord(iop_base, lram_addr, 0);
8173 }
8174 return (0);
1da177e4
LT
8175}
8176
27c868c2 8177static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 8178{
27c868c2
MW
8179 if (asc_dvc->err_code == 0) {
8180 asc_dvc->err_code = err_code;
8181 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8182 err_code);
8183 }
8184 return (err_code);
1da177e4
LT
8185}
8186
27c868c2
MW
8187static uchar
8188AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 8189{
27c868c2
MW
8190 EXT_MSG sdtr_buf;
8191 uchar sdtr_period_index;
8192 PortAddr iop_base;
8193
8194 iop_base = asc_dvc->iop_base;
47d853cc 8195 sdtr_buf.msg_type = EXTENDED_MESSAGE;
27c868c2 8196 sdtr_buf.msg_len = MS_SDTR_LEN;
47d853cc 8197 sdtr_buf.msg_req = EXTENDED_SDTR;
27c868c2
MW
8198 sdtr_buf.xfer_period = sdtr_period;
8199 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8200 sdtr_buf.req_ack_offset = sdtr_offset;
8201 if ((sdtr_period_index =
8202 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
8203 asc_dvc->max_sdtr_index) {
8204 AscMemWordCopyPtrToLram(iop_base,
8205 ASCV_MSGOUT_BEG,
8206 (uchar *)&sdtr_buf,
8207 sizeof(EXT_MSG) >> 1);
8208 return ((sdtr_period_index << 4) | sdtr_offset);
8209 } else {
8210
8211 sdtr_buf.req_ack_offset = 0;
8212 AscMemWordCopyPtrToLram(iop_base,
8213 ASCV_MSGOUT_BEG,
8214 (uchar *)&sdtr_buf,
8215 sizeof(EXT_MSG) >> 1);
8216 return (0);
8217 }
1da177e4
LT
8218}
8219
27c868c2
MW
8220static uchar
8221AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 8222{
27c868c2
MW
8223 uchar byte;
8224 uchar sdtr_period_ix;
8225
8226 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8227 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
8228 ) {
8229 return (0xFF);
8230 }
8231 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8232 return (byte);
1da177e4
LT
8233}
8234
27c868c2 8235static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 8236{
27c868c2
MW
8237 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8238 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8239 return;
1da177e4
LT
8240}
8241
27c868c2 8242static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 8243{
27c868c2
MW
8244 uchar *period_table;
8245 int max_index;
8246 int min_index;
8247 int i;
8248
8249 period_table = asc_dvc->sdtr_period_tbl;
8250 max_index = (int)asc_dvc->max_sdtr_index;
8251 min_index = (int)asc_dvc->host_init_sdtr_index;
8252 if ((syn_time <= period_table[max_index])) {
8253 for (i = min_index; i < (max_index - 1); i++) {
8254 if (syn_time <= period_table[i]) {
8255 return ((uchar)i);
8256 }
8257 }
8258 return ((uchar)max_index);
8259 } else {
8260 return ((uchar)(max_index + 1));
8261 }
1da177e4
LT
8262}
8263
27c868c2 8264static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 8265{
27c868c2
MW
8266 ushort q_addr;
8267 uchar next_qp;
8268 uchar q_status;
8269
8270 q_addr = ASC_QNO_TO_QADDR(free_q_head);
8271 q_status = (uchar)AscReadLramByte(iop_base,
8272 (ushort)(q_addr +
8273 ASC_SCSIQ_B_STATUS));
8274 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
8275 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
8276 return (next_qp);
8277 }
8278 return (ASC_QLINK_END);
1da177e4
LT
8279}
8280
27c868c2
MW
8281static uchar
8282AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 8283{
27c868c2 8284 uchar i;
1da177e4 8285
27c868c2
MW
8286 for (i = 0; i < n_free_q; i++) {
8287 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
8288 == ASC_QLINK_END) {
8289 return (ASC_QLINK_END);
8290 }
8291 }
8292 return (free_q_head);
1da177e4
LT
8293}
8294
27c868c2 8295static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 8296{
27c868c2
MW
8297 int count = 0;
8298 int sta = 0;
8299 uchar saved_stop_code;
8300
8301 if (AscIsChipHalted(iop_base))
8302 return (1);
8303 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
8304 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8305 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
8306 do {
8307 if (AscIsChipHalted(iop_base)) {
8308 sta = 1;
8309 break;
8310 }
8311 DvcSleepMilliSecond(100);
8312 } while (count++ < 20);
8313 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
8314 return (sta);
1da177e4
LT
8315}
8316
27c868c2 8317static int AscStopQueueExe(PortAddr iop_base)
1da177e4 8318{
27c868c2
MW
8319 int count = 0;
8320
8321 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
8322 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8323 ASC_STOP_REQ_RISC_STOP);
8324 do {
8325 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
8326 ASC_STOP_ACK_RISC_STOP) {
8327 return (1);
8328 }
8329 DvcSleepMilliSecond(100);
8330 } while (count++ < 20);
8331 }
8332 return (0);
1da177e4
LT
8333}
8334
27c868c2 8335static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
1da177e4 8336{
27c868c2 8337 udelay(micro_sec);
1da177e4
LT
8338}
8339
27c868c2 8340static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
1da177e4 8341{
27c868c2 8342 udelay((nano_sec + 999) / 1000);
1da177e4
LT
8343}
8344
27c868c2 8345static int AscStartChip(PortAddr iop_base)
1da177e4 8346{
27c868c2
MW
8347 AscSetChipControl(iop_base, 0);
8348 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8349 return (0);
8350 }
8351 return (1);
1da177e4
LT
8352}
8353
27c868c2 8354static int AscStopChip(PortAddr iop_base)
1da177e4 8355{
27c868c2
MW
8356 uchar cc_val;
8357
8358 cc_val =
8359 AscGetChipControl(iop_base) &
8360 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
8361 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
8362 AscSetChipIH(iop_base, INS_HALT);
8363 AscSetChipIH(iop_base, INS_RFLAG_WTM);
8364 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
8365 return (0);
8366 }
8367 return (1);
1da177e4
LT
8368}
8369
27c868c2 8370static int AscIsChipHalted(PortAddr iop_base)
1da177e4 8371{
27c868c2
MW
8372 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8373 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
8374 return (1);
8375 }
8376 }
8377 return (0);
1da177e4
LT
8378}
8379
27c868c2 8380static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 8381{
27c868c2
MW
8382 AscSetBank(iop_base, 1);
8383 AscWriteChipIH(iop_base, ins_code);
8384 AscSetBank(iop_base, 0);
8385 return;
1da177e4
LT
8386}
8387
27c868c2 8388static void AscAckInterrupt(PortAddr iop_base)
1da177e4 8389{
27c868c2
MW
8390 uchar host_flag;
8391 uchar risc_flag;
8392 ushort loop;
8393
8394 loop = 0;
8395 do {
8396 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8397 if (loop++ > 0x7FFF) {
8398 break;
8399 }
8400 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8401 host_flag =
8402 AscReadLramByte(iop_base,
8403 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8404 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8405 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8406 AscSetChipStatus(iop_base, CIW_INT_ACK);
8407 loop = 0;
8408 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8409 AscSetChipStatus(iop_base, CIW_INT_ACK);
8410 if (loop++ > 3) {
8411 break;
8412 }
8413 }
8414 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8415 return;
1da177e4
LT
8416}
8417
27c868c2 8418static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 8419{
27c868c2 8420 ushort cfg;
1da177e4 8421
27c868c2
MW
8422 cfg = AscGetChipCfgLsw(iop_base);
8423 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
8424 return;
1da177e4
LT
8425}
8426
27c868c2 8427static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 8428{
27c868c2 8429 ushort cfg;
1da177e4 8430
27c868c2
MW
8431 cfg = AscGetChipCfgLsw(iop_base);
8432 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
8433 return;
1da177e4
LT
8434}
8435
27c868c2 8436static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 8437{
27c868c2
MW
8438 uchar val;
8439
8440 val = AscGetChipControl(iop_base) &
8441 (~
8442 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
8443 CC_CHIP_RESET));
8444 if (bank == 1) {
8445 val |= CC_BANK_ONE;
8446 } else if (bank == 2) {
8447 val |= CC_DIAG | CC_BANK_ONE;
8448 } else {
8449 val &= ~CC_BANK_ONE;
8450 }
8451 AscSetChipControl(iop_base, val);
8452 return;
1da177e4
LT
8453}
8454
27c868c2 8455static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 8456{
27c868c2
MW
8457 PortAddr iop_base;
8458 int i = 10;
1da177e4 8459
27c868c2
MW
8460 iop_base = asc_dvc->iop_base;
8461 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
8462 && (i-- > 0)) {
8463 DvcSleepMilliSecond(100);
8464 }
8465 AscStopChip(iop_base);
8466 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
8467 DvcDelayNanoSecond(asc_dvc, 60000);
8468 AscSetChipIH(iop_base, INS_RFLAG_WTM);
8469 AscSetChipIH(iop_base, INS_HALT);
8470 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
8471 AscSetChipControl(iop_base, CC_HALT);
8472 DvcSleepMilliSecond(200);
8473 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8474 AscSetChipStatus(iop_base, 0);
8475 return (AscIsChipHalted(iop_base));
1da177e4
LT
8476}
8477
78e77d8b 8478static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
1da177e4 8479{
27c868c2
MW
8480 if (bus_type & ASC_IS_ISA)
8481 return (ASC_MAX_ISA_DMA_COUNT);
8482 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
8483 return (ASC_MAX_VL_DMA_COUNT);
8484 return (ASC_MAX_PCI_DMA_COUNT);
1da177e4
LT
8485}
8486
8487#ifdef CONFIG_ISA
78e77d8b 8488static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 8489{
27c868c2
MW
8490 ushort channel;
8491
8492 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
8493 if (channel == 0x03)
8494 return (0);
8495 else if (channel == 0x00)
8496 return (7);
8497 return (channel + 4);
1da177e4
LT
8498}
8499
78e77d8b 8500static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 8501{
27c868c2
MW
8502 ushort cfg_lsw;
8503 uchar value;
8504
8505 if ((dma_channel >= 5) && (dma_channel <= 7)) {
8506 if (dma_channel == 7)
8507 value = 0x00;
8508 else
8509 value = dma_channel - 4;
8510 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
8511 cfg_lsw |= value;
8512 AscSetChipCfgLsw(iop_base, cfg_lsw);
8513 return (AscGetIsaDmaChannel(iop_base));
8514 }
8515 return (0);
1da177e4
LT
8516}
8517
78e77d8b 8518static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 8519{
27c868c2
MW
8520 speed_value &= 0x07;
8521 AscSetBank(iop_base, 1);
8522 AscWriteChipDmaSpeed(iop_base, speed_value);
8523 AscSetBank(iop_base, 0);
8524 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
8525}
8526
78e77d8b 8527static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 8528{
27c868c2 8529 uchar speed_value;
1da177e4 8530
27c868c2
MW
8531 AscSetBank(iop_base, 1);
8532 speed_value = AscReadChipDmaSpeed(iop_base);
8533 speed_value &= 0x07;
8534 AscSetBank(iop_base, 0);
8535 return (speed_value);
1da177e4
LT
8536}
8537#endif /* CONFIG_ISA */
8538
c2dce2fa 8539static int __devinit AscInitGetConfig(asc_board_t *boardp)
1da177e4 8540{
c2dce2fa 8541 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9649af39 8542 unsigned short warn_code = 0;
27c868c2 8543
27c868c2 8544 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9649af39 8545 if (asc_dvc->err_code != 0)
c2dce2fa 8546 return asc_dvc->err_code;
27c868c2 8547
9649af39 8548 if (AscFindSignature(asc_dvc->iop_base)) {
27c868c2
MW
8549 warn_code |= AscInitAscDvcVar(asc_dvc);
8550 warn_code |= AscInitFromEEP(asc_dvc);
8551 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
ecec1947 8552 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
27c868c2 8553 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
27c868c2
MW
8554 } else {
8555 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
8556 }
c2dce2fa
MW
8557
8558 switch (warn_code) {
8559 case 0: /* No error */
8560 break;
8561 case ASC_WARN_IO_PORT_ROTATE:
8562 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
8563 "modified\n", boardp->id);
8564 break;
8565 case ASC_WARN_AUTO_CONFIG:
8566 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
8567 "switch enabled\n", boardp->id);
8568 break;
8569 case ASC_WARN_EEPROM_CHKSUM:
8570 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
8571 "error\n", boardp->id);
8572 break;
8573 case ASC_WARN_IRQ_MODIFIED:
8574 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
8575 boardp->id);
8576 break;
8577 case ASC_WARN_CMD_QNG_CONFLICT:
8578 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
8579 "w/o disconnects\n", boardp->id);
8580 break;
8581 default:
8582 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
8583 "0x%x\n", boardp->id, warn_code);
8584 break;
8585 }
8586
8587 if (asc_dvc->err_code != 0) {
8588 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
8589 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
8590 asc_dvc->err_code);
8591 }
8592
8593 return asc_dvc->err_code;
1da177e4
LT
8594}
8595
c2dce2fa 8596static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 8597{
c2dce2fa 8598 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
394dbf3f
MW
8599 PortAddr iop_base = asc_dvc->iop_base;
8600 unsigned short cfg_msw;
8601 unsigned short warn_code = 0;
27c868c2
MW
8602
8603 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
8604 if (asc_dvc->err_code != 0)
c2dce2fa 8605 return asc_dvc->err_code;
394dbf3f 8606 if (!AscFindSignature(asc_dvc->iop_base)) {
27c868c2 8607 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
c2dce2fa 8608 return asc_dvc->err_code;
27c868c2 8609 }
1da177e4 8610
27c868c2
MW
8611 cfg_msw = AscGetChipCfgMsw(iop_base);
8612 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 8613 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
8614 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
8615 AscSetChipCfgMsw(iop_base, cfg_msw);
8616 }
8617 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
8618 asc_dvc->cfg->cmd_qng_enabled) {
8619 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
8620 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
8621 }
8622 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
8623 warn_code |= ASC_WARN_AUTO_CONFIG;
8624 }
8625 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
8626 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
8627 != asc_dvc->irq_no) {
8628 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
8629 }
8630 }
9649af39 8631#ifdef CONFIG_PCI
27c868c2
MW
8632 if (asc_dvc->bus_type & ASC_IS_PCI) {
8633 cfg_msw &= 0xFFC0;
8634 AscSetChipCfgMsw(iop_base, cfg_msw);
8635 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
8636 } else {
9649af39
MW
8637 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
8638 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
27c868c2
MW
8639 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
8640 asc_dvc->bug_fix_cntl |=
8641 ASC_BUG_FIX_ASYN_USE_SYN;
8642 }
8643 }
9649af39
MW
8644 } else
8645#endif /* CONFIG_PCI */
8646 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
27c868c2
MW
8647 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
8648 == ASC_CHIP_VER_ASYN_BUG) {
8649 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
8650 }
8651 }
8652 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
8653 asc_dvc->cfg->chip_scsi_id) {
8654 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
8655 }
1da177e4 8656#ifdef CONFIG_ISA
27c868c2
MW
8657 if (asc_dvc->bus_type & ASC_IS_ISA) {
8658 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
8659 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
8660 }
1da177e4 8661#endif /* CONFIG_ISA */
394dbf3f
MW
8662
8663 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
c2dce2fa
MW
8664
8665 switch (warn_code) {
8666 case 0: /* No error. */
8667 break;
8668 case ASC_WARN_IO_PORT_ROTATE:
8669 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
8670 "modified\n", boardp->id);
8671 break;
8672 case ASC_WARN_AUTO_CONFIG:
8673 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
8674 "switch enabled\n", boardp->id);
8675 break;
8676 case ASC_WARN_EEPROM_CHKSUM:
8677 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
8678 "error\n", boardp->id);
8679 break;
8680 case ASC_WARN_IRQ_MODIFIED:
8681 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
8682 boardp->id);
8683 break;
8684 case ASC_WARN_CMD_QNG_CONFLICT:
8685 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
8686 "disconnects\n",
8687 boardp->id);
8688 break;
8689 default:
8690 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
8691 "0x%x\n", boardp->id, warn_code);
8692 break;
8693 }
8694
8695 if (asc_dvc->err_code != 0) {
8696 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
8697 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
8698 asc_dvc->err_code);
8699 }
8700
8701 return asc_dvc->err_code;
1da177e4
LT
8702}
8703
27c868c2 8704static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 8705{
27c868c2
MW
8706 ushort warn_code;
8707 PortAddr iop_base;
8708
8709 iop_base = asc_dvc->iop_base;
8710 warn_code = 0;
8711 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
8712 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
8713 AscResetChipAndScsiBus(asc_dvc);
8714 DvcSleepMilliSecond((ASC_DCNT)
8715 ((ushort)asc_dvc->scsi_reset_wait * 1000));
8716 }
8717 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
8718 if (asc_dvc->err_code != 0)
8719 return (UW_ERR);
8720 if (!AscFindSignature(asc_dvc->iop_base)) {
8721 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
8722 return (warn_code);
8723 }
8724 AscDisableInterrupt(iop_base);
8725 warn_code |= AscInitLram(asc_dvc);
8726 if (asc_dvc->err_code != 0)
8727 return (UW_ERR);
8728 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
8729 (ulong)_asc_mcode_chksum);
8730 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
8731 _asc_mcode_size) != _asc_mcode_chksum) {
8732 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
8733 return (warn_code);
8734 }
8735 warn_code |= AscInitMicroCodeVar(asc_dvc);
8736 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
8737 AscEnableInterrupt(iop_base);
8738 return (warn_code);
1da177e4
LT
8739}
8740
78e77d8b 8741static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8742{
27c868c2
MW
8743 int i;
8744 PortAddr iop_base;
8745 ushort warn_code;
8746 uchar chip_version;
8747
8748 iop_base = asc_dvc->iop_base;
8749 warn_code = 0;
8750 asc_dvc->err_code = 0;
8751 if ((asc_dvc->bus_type &
8752 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
8753 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
8754 }
8755 AscSetChipControl(iop_base, CC_HALT);
8756 AscSetChipStatus(iop_base, 0);
8757 asc_dvc->bug_fix_cntl = 0;
8758 asc_dvc->pci_fix_asyn_xfer = 0;
8759 asc_dvc->pci_fix_asyn_xfer_always = 0;
8760 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
8761 asc_dvc->sdtr_done = 0;
8762 asc_dvc->cur_total_qng = 0;
8763 asc_dvc->is_in_int = 0;
8764 asc_dvc->in_critical_cnt = 0;
8765 asc_dvc->last_q_shortage = 0;
8766 asc_dvc->use_tagged_qng = 0;
8767 asc_dvc->no_scam = 0;
8768 asc_dvc->unit_not_ready = 0;
8769 asc_dvc->queue_full_or_busy = 0;
8770 asc_dvc->redo_scam = 0;
8771 asc_dvc->res2 = 0;
8772 asc_dvc->host_init_sdtr_index = 0;
8773 asc_dvc->cfg->can_tagged_qng = 0;
8774 asc_dvc->cfg->cmd_qng_enabled = 0;
8775 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
8776 asc_dvc->init_sdtr = 0;
8777 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
8778 asc_dvc->scsi_reset_wait = 3;
8779 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
8780 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
8781 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
8782 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
8783 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
8784 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
8785 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
8786 ASC_LIB_VERSION_MINOR;
8787 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
8788 asc_dvc->cfg->chip_version = chip_version;
8789 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
8790 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
8791 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
8792 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
8793 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
8794 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
8795 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
8796 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
8797 asc_dvc->max_sdtr_index = 7;
8798 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
8799 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
8800 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
8801 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
8802 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
8803 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
8804 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
8805 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
8806 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
8807 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
8808 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
8809 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
8810 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
8811 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
8812 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
8813 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
8814 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
8815 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
8816 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
8817 asc_dvc->max_sdtr_index = 15;
8818 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
8819 AscSetExtraControl(iop_base,
8820 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8821 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
8822 AscSetExtraControl(iop_base,
8823 (SEC_ACTIVE_NEGATE |
8824 SEC_ENABLE_FILTER));
8825 }
8826 }
8827 if (asc_dvc->bus_type == ASC_IS_PCI) {
8828 AscSetExtraControl(iop_base,
8829 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8830 }
1da177e4 8831
27c868c2 8832 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
1da177e4 8833#ifdef CONFIG_ISA
27c868c2 8834 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
59fcf844
MW
8835 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
8836 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
8837 asc_dvc->bus_type = ASC_IS_ISAPNP;
8838 }
27c868c2
MW
8839 asc_dvc->cfg->isa_dma_channel =
8840 (uchar)AscGetIsaDmaChannel(iop_base);
8841 }
1da177e4 8842#endif /* CONFIG_ISA */
27c868c2
MW
8843 for (i = 0; i <= ASC_MAX_TID; i++) {
8844 asc_dvc->cur_dvc_qng[i] = 0;
8845 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
8846 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
8847 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
8848 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
8849 }
8850 return (warn_code);
1da177e4
LT
8851}
8852
78e77d8b 8853static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 8854{
27c868c2
MW
8855 ASCEEP_CONFIG eep_config_buf;
8856 ASCEEP_CONFIG *eep_config;
8857 PortAddr iop_base;
8858 ushort chksum;
8859 ushort warn_code;
8860 ushort cfg_msw, cfg_lsw;
8861 int i;
8862 int write_eep = 0;
8863
8864 iop_base = asc_dvc->iop_base;
8865 warn_code = 0;
8866 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
8867 AscStopQueueExe(iop_base);
8868 if ((AscStopChip(iop_base) == FALSE) ||
8869 (AscGetChipScsiCtrl(iop_base) != 0)) {
8870 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
8871 AscResetChipAndScsiBus(asc_dvc);
8872 DvcSleepMilliSecond((ASC_DCNT)
8873 ((ushort)asc_dvc->scsi_reset_wait * 1000));
8874 }
8875 if (AscIsChipHalted(iop_base) == FALSE) {
8876 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
8877 return (warn_code);
8878 }
8879 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
8880 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
8881 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
8882 return (warn_code);
8883 }
8884 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
8885 cfg_msw = AscGetChipCfgMsw(iop_base);
8886 cfg_lsw = AscGetChipCfgLsw(iop_base);
8887 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 8888 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
8889 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
8890 AscSetChipCfgMsw(iop_base, cfg_msw);
8891 }
8892 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
8893 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
8894 if (chksum == 0) {
8895 chksum = 0xaa55;
8896 }
8897 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
8898 warn_code |= ASC_WARN_AUTO_CONFIG;
8899 if (asc_dvc->cfg->chip_version == 3) {
8900 if (eep_config->cfg_lsw != cfg_lsw) {
8901 warn_code |= ASC_WARN_EEPROM_RECOVER;
8902 eep_config->cfg_lsw =
8903 AscGetChipCfgLsw(iop_base);
8904 }
8905 if (eep_config->cfg_msw != cfg_msw) {
8906 warn_code |= ASC_WARN_EEPROM_RECOVER;
8907 eep_config->cfg_msw =
8908 AscGetChipCfgMsw(iop_base);
8909 }
8910 }
8911 }
8912 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
8913 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
8914 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
8915 eep_config->chksum);
8916 if (chksum != eep_config->chksum) {
8917 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
8918 ASC_CHIP_VER_PCI_ULTRA_3050) {
8919 ASC_DBG(1,
8920 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
8921 eep_config->init_sdtr = 0xFF;
8922 eep_config->disc_enable = 0xFF;
8923 eep_config->start_motor = 0xFF;
8924 eep_config->use_cmd_qng = 0;
8925 eep_config->max_total_qng = 0xF0;
8926 eep_config->max_tag_qng = 0x20;
8927 eep_config->cntl = 0xBFFF;
8928 ASC_EEP_SET_CHIP_ID(eep_config, 7);
8929 eep_config->no_scam = 0;
8930 eep_config->adapter_info[0] = 0;
8931 eep_config->adapter_info[1] = 0;
8932 eep_config->adapter_info[2] = 0;
8933 eep_config->adapter_info[3] = 0;
8934 eep_config->adapter_info[4] = 0;
8935 /* Indicate EEPROM-less board. */
8936 eep_config->adapter_info[5] = 0xBB;
8937 } else {
8938 ASC_PRINT
8939 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
8940 write_eep = 1;
8941 warn_code |= ASC_WARN_EEPROM_CHKSUM;
8942 }
8943 }
8944 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
8945 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
8946 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
8947 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
8948 asc_dvc->start_motor = eep_config->start_motor;
8949 asc_dvc->dvc_cntl = eep_config->cntl;
8950 asc_dvc->no_scam = eep_config->no_scam;
8951 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
8952 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
8953 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
8954 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
8955 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
8956 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
8957 if (!AscTestExternalLram(asc_dvc)) {
8958 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
8959 ASC_IS_PCI_ULTRA)) {
8960 eep_config->max_total_qng =
8961 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
8962 eep_config->max_tag_qng =
8963 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
8964 } else {
8965 eep_config->cfg_msw |= 0x0800;
8966 cfg_msw |= 0x0800;
8967 AscSetChipCfgMsw(iop_base, cfg_msw);
8968 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
8969 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
8970 }
8971 } else {
8972 }
8973 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
8974 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
8975 }
8976 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
8977 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
8978 }
8979 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
8980 eep_config->max_tag_qng = eep_config->max_total_qng;
8981 }
8982 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
8983 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
8984 }
8985 asc_dvc->max_total_qng = eep_config->max_total_qng;
8986 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
8987 eep_config->use_cmd_qng) {
8988 eep_config->disc_enable = eep_config->use_cmd_qng;
8989 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
8990 }
8991 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
8992 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
8993 }
8994 ASC_EEP_SET_CHIP_ID(eep_config,
8995 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
8996 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
8997 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
8998 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
8999 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
9000 }
1da177e4 9001
27c868c2
MW
9002 for (i = 0; i <= ASC_MAX_TID; i++) {
9003 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
9004 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
9005 asc_dvc->cfg->sdtr_period_offset[i] =
9006 (uchar)(ASC_DEF_SDTR_OFFSET |
9007 (asc_dvc->host_init_sdtr_index << 4));
9008 }
9009 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
9010 if (write_eep) {
9011 if ((i =
9012 AscSetEEPConfig(iop_base, eep_config,
9013 asc_dvc->bus_type)) != 0) {
9014 ASC_PRINT1
9015 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
9016 i);
9017 } else {
9018 ASC_PRINT
9019 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
9020 }
9021 }
9022 return (warn_code);
1da177e4
LT
9023}
9024
27c868c2 9025static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 9026{
27c868c2
MW
9027 int i;
9028 ushort warn_code;
9029 PortAddr iop_base;
9030 ASC_PADDR phy_addr;
9031 ASC_DCNT phy_size;
9032
9033 iop_base = asc_dvc->iop_base;
9034 warn_code = 0;
9035 for (i = 0; i <= ASC_MAX_TID; i++) {
9036 AscPutMCodeInitSDTRAtID(iop_base, i,
9037 asc_dvc->cfg->sdtr_period_offset[i]
9038 );
9039 }
1da177e4 9040
27c868c2
MW
9041 AscInitQLinkVar(asc_dvc);
9042 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
9043 asc_dvc->cfg->disc_enable);
9044 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
9045 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
9046
9047 /* Align overrun buffer on an 8 byte boundary. */
9048 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
9049 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
9050 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
9051 (uchar *)&phy_addr, 1);
9052 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
9053 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
9054 (uchar *)&phy_size, 1);
9055
9056 asc_dvc->cfg->mcode_date =
9057 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
9058 asc_dvc->cfg->mcode_version =
9059 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
9060
9061 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
9062 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
9063 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
9064 return (warn_code);
9065 }
9066 if (AscStartChip(iop_base) != 1) {
9067 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
9068 return (warn_code);
9069 }
1da177e4 9070
27c868c2 9071 return (warn_code);
1da177e4
LT
9072}
9073
78e77d8b 9074static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 9075{
27c868c2
MW
9076 PortAddr iop_base;
9077 ushort q_addr;
9078 ushort saved_word;
9079 int sta;
9080
9081 iop_base = asc_dvc->iop_base;
9082 sta = 0;
9083 q_addr = ASC_QNO_TO_QADDR(241);
9084 saved_word = AscReadLramWord(iop_base, q_addr);
9085 AscSetChipLramAddr(iop_base, q_addr);
9086 AscSetChipLramData(iop_base, 0x55AA);
9087 DvcSleepMilliSecond(10);
9088 AscSetChipLramAddr(iop_base, q_addr);
9089 if (AscGetChipLramData(iop_base) == 0x55AA) {
9090 sta = 1;
9091 AscWriteLramWord(iop_base, q_addr, saved_word);
9092 }
9093 return (sta);
1da177e4
LT
9094}
9095
78e77d8b 9096static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 9097{
27c868c2
MW
9098 uchar read_back;
9099 int retry;
9100
9101 retry = 0;
9102 while (TRUE) {
9103 AscSetChipEEPCmd(iop_base, cmd_reg);
9104 DvcSleepMilliSecond(1);
9105 read_back = AscGetChipEEPCmd(iop_base);
9106 if (read_back == cmd_reg) {
9107 return (1);
9108 }
9109 if (retry++ > ASC_EEP_MAX_RETRY) {
9110 return (0);
9111 }
9112 }
1da177e4
LT
9113}
9114
78e77d8b 9115static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 9116{
27c868c2
MW
9117 ushort read_back;
9118 int retry;
9119
9120 retry = 0;
9121 while (TRUE) {
9122 AscSetChipEEPData(iop_base, data_reg);
9123 DvcSleepMilliSecond(1);
9124 read_back = AscGetChipEEPData(iop_base);
9125 if (read_back == data_reg) {
9126 return (1);
9127 }
9128 if (retry++ > ASC_EEP_MAX_RETRY) {
9129 return (0);
9130 }
9131 }
1da177e4
LT
9132}
9133
78e77d8b 9134static void __devinit AscWaitEEPRead(void)
1da177e4 9135{
27c868c2
MW
9136 DvcSleepMilliSecond(1);
9137 return;
1da177e4
LT
9138}
9139
78e77d8b 9140static void __devinit AscWaitEEPWrite(void)
1da177e4 9141{
27c868c2
MW
9142 DvcSleepMilliSecond(20);
9143 return;
1da177e4
LT
9144}
9145
78e77d8b 9146static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 9147{
27c868c2
MW
9148 ushort read_wval;
9149 uchar cmd_reg;
9150
9151 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9152 AscWaitEEPRead();
9153 cmd_reg = addr | ASC_EEP_CMD_READ;
9154 AscWriteEEPCmdReg(iop_base, cmd_reg);
9155 AscWaitEEPRead();
9156 read_wval = AscGetChipEEPData(iop_base);
9157 AscWaitEEPRead();
9158 return (read_wval);
1da177e4
LT
9159}
9160
78e77d8b 9161static ushort __devinit
27c868c2 9162AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 9163{
27c868c2
MW
9164 ushort read_wval;
9165
9166 read_wval = AscReadEEPWord(iop_base, addr);
9167 if (read_wval != word_val) {
9168 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
9169 AscWaitEEPRead();
9170 AscWriteEEPDataReg(iop_base, word_val);
9171 AscWaitEEPRead();
9172 AscWriteEEPCmdReg(iop_base,
9173 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
9174 AscWaitEEPWrite();
9175 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9176 AscWaitEEPRead();
9177 return (AscReadEEPWord(iop_base, addr));
9178 }
9179 return (read_wval);
1da177e4
LT
9180}
9181
78e77d8b 9182static ushort __devinit
27c868c2 9183AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9184{
27c868c2
MW
9185 ushort wval;
9186 ushort sum;
9187 ushort *wbuf;
9188 int cfg_beg;
9189 int cfg_end;
9190 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
9191 int s_addr;
9192
9193 wbuf = (ushort *)cfg_buf;
9194 sum = 0;
9195 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
9196 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9197 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
9198 sum += *wbuf;
9199 }
9200 if (bus_type & ASC_IS_VL) {
9201 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9202 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9203 } else {
9204 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9205 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9206 }
9207 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9208 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
9209 if (s_addr <= uchar_end_in_config) {
9210 /*
9211 * Swap all char fields - must unswap bytes already swapped
9212 * by AscReadEEPWord().
9213 */
9214 *wbuf = le16_to_cpu(wval);
9215 } else {
9216 /* Don't swap word field at the end - cntl field. */
9217 *wbuf = wval;
9218 }
9219 sum += wval; /* Checksum treats all EEPROM data as words. */
9220 }
9221 /*
9222 * Read the checksum word which will be compared against 'sum'
9223 * by the caller. Word field already swapped.
9224 */
9225 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
9226 return (sum);
1da177e4
LT
9227}
9228
78e77d8b 9229static int __devinit
27c868c2 9230AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9231{
27c868c2
MW
9232 int n_error;
9233 ushort *wbuf;
9234 ushort word;
9235 ushort sum;
9236 int s_addr;
9237 int cfg_beg;
9238 int cfg_end;
9239 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
9240
9241 wbuf = (ushort *)cfg_buf;
9242 n_error = 0;
9243 sum = 0;
9244 /* Write two config words; AscWriteEEPWord() will swap bytes. */
9245 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9246 sum += *wbuf;
9247 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9248 n_error++;
9249 }
9250 }
9251 if (bus_type & ASC_IS_VL) {
9252 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9253 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9254 } else {
9255 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9256 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9257 }
9258 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9259 if (s_addr <= uchar_end_in_config) {
9260 /*
9261 * This is a char field. Swap char fields before they are
9262 * swapped again by AscWriteEEPWord().
9263 */
9264 word = cpu_to_le16(*wbuf);
9265 if (word !=
9266 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
9267 n_error++;
9268 }
9269 } else {
9270 /* Don't swap word field at the end - cntl field. */
9271 if (*wbuf !=
9272 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9273 n_error++;
9274 }
9275 }
9276 sum += *wbuf; /* Checksum calculated from word values. */
9277 }
9278 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
9279 *wbuf = sum;
9280 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
9281 n_error++;
9282 }
1da177e4 9283
27c868c2
MW
9284 /* Read EEPROM back again. */
9285 wbuf = (ushort *)cfg_buf;
9286 /*
9287 * Read two config words; Byte-swapping done by AscReadEEPWord().
9288 */
9289 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9290 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
9291 n_error++;
9292 }
9293 }
9294 if (bus_type & ASC_IS_VL) {
9295 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9296 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9297 } else {
9298 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9299 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9300 }
9301 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9302 if (s_addr <= uchar_end_in_config) {
9303 /*
9304 * Swap all char fields. Must unswap bytes already swapped
9305 * by AscReadEEPWord().
9306 */
9307 word =
9308 le16_to_cpu(AscReadEEPWord
9309 (iop_base, (uchar)s_addr));
9310 } else {
9311 /* Don't swap word field at the end - cntl field. */
9312 word = AscReadEEPWord(iop_base, (uchar)s_addr);
9313 }
9314 if (*wbuf != word) {
9315 n_error++;
9316 }
9317 }
9318 /* Read checksum; Byte swapping not needed. */
9319 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
9320 n_error++;
9321 }
9322 return (n_error);
1da177e4
LT
9323}
9324
78e77d8b 9325static int __devinit
27c868c2 9326AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9327{
27c868c2
MW
9328 int retry;
9329 int n_error;
9330
9331 retry = 0;
9332 while (TRUE) {
9333 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
9334 bus_type)) == 0) {
9335 break;
9336 }
9337 if (++retry > ASC_EEP_MAX_RETRY) {
9338 break;
9339 }
9340 }
9341 return (n_error);
1da177e4
LT
9342}
9343
47d853cc 9344static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
1da177e4 9345{
47d853cc
MW
9346 char type = sdev->type;
9347 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
27c868c2
MW
9348
9349 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
9350 if (!(asc_dvc->init_sdtr & tid_bits)) {
47d853cc
MW
9351 if ((type == TYPE_ROM) &&
9352 (strncmp(sdev->vendor, "HP ", 3) == 0)) {
27c868c2
MW
9353 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9354 }
9355 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
47d853cc
MW
9356 if ((type == TYPE_PROCESSOR) ||
9357 (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
9358 (type == TYPE_TAPE)) {
27c868c2
MW
9359 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9360 }
9361
9362 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
9363 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
47d853cc
MW
9364 sdev->id,
9365 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
27c868c2
MW
9366 }
9367 }
9368 }
1da177e4
LT
9369}
9370
27c868c2 9371static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 9372{
27c868c2
MW
9373 uchar byte_data;
9374 ushort word_data;
9375
9376 if (isodd_word(addr)) {
9377 AscSetChipLramAddr(iop_base, addr - 1);
9378 word_data = AscGetChipLramData(iop_base);
9379 byte_data = (uchar)((word_data >> 8) & 0xFF);
9380 } else {
9381 AscSetChipLramAddr(iop_base, addr);
9382 word_data = AscGetChipLramData(iop_base);
9383 byte_data = (uchar)(word_data & 0xFF);
9384 }
9385 return (byte_data);
1da177e4 9386}
27c868c2
MW
9387
9388static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 9389{
27c868c2 9390 ushort word_data;
1da177e4 9391
27c868c2
MW
9392 AscSetChipLramAddr(iop_base, addr);
9393 word_data = AscGetChipLramData(iop_base);
9394 return (word_data);
1da177e4
LT
9395}
9396
9397#if CC_VERY_LONG_SG_LIST
27c868c2 9398static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 9399{
27c868c2
MW
9400 ushort val_low, val_high;
9401 ASC_DCNT dword_data;
9402
9403 AscSetChipLramAddr(iop_base, addr);
9404 val_low = AscGetChipLramData(iop_base);
9405 val_high = AscGetChipLramData(iop_base);
9406 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
9407 return (dword_data);
1da177e4
LT
9408}
9409#endif /* CC_VERY_LONG_SG_LIST */
9410
27c868c2 9411static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 9412{
27c868c2
MW
9413 AscSetChipLramAddr(iop_base, addr);
9414 AscSetChipLramData(iop_base, word_val);
9415 return;
1da177e4
LT
9416}
9417
27c868c2 9418static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 9419{
27c868c2
MW
9420 ushort word_data;
9421
9422 if (isodd_word(addr)) {
9423 addr--;
9424 word_data = AscReadLramWord(iop_base, addr);
9425 word_data &= 0x00FF;
9426 word_data |= (((ushort)byte_val << 8) & 0xFF00);
9427 } else {
9428 word_data = AscReadLramWord(iop_base, addr);
9429 word_data &= 0xFF00;
9430 word_data |= ((ushort)byte_val & 0x00FF);
9431 }
9432 AscWriteLramWord(iop_base, addr, word_data);
9433 return;
1da177e4
LT
9434}
9435
9436/*
9437 * Copy 2 bytes to LRAM.
9438 *
9439 * The source data is assumed to be in little-endian order in memory
9440 * and is maintained in little-endian order when written to LRAM.
9441 */
27c868c2
MW
9442static void
9443AscMemWordCopyPtrToLram(PortAddr iop_base,
9444 ushort s_addr, uchar *s_buffer, int words)
1da177e4 9445{
27c868c2
MW
9446 int i;
9447
9448 AscSetChipLramAddr(iop_base, s_addr);
9449 for (i = 0; i < 2 * words; i += 2) {
9450 /*
9451 * On a little-endian system the second argument below
9452 * produces a little-endian ushort which is written to
9453 * LRAM in little-endian order. On a big-endian system
9454 * the second argument produces a big-endian ushort which
9455 * is "transparently" byte-swapped by outpw() and written
9456 * in little-endian order to LRAM.
9457 */
9458 outpw(iop_base + IOP_RAM_DATA,
9459 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
9460 }
9461 return;
1da177e4
LT
9462}
9463
9464/*
9465 * Copy 4 bytes to LRAM.
9466 *
9467 * The source data is assumed to be in little-endian order in memory
9468 * and is maintained in little-endian order when writen to LRAM.
9469 */
27c868c2
MW
9470static void
9471AscMemDWordCopyPtrToLram(PortAddr iop_base,
9472 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 9473{
27c868c2
MW
9474 int i;
9475
9476 AscSetChipLramAddr(iop_base, s_addr);
9477 for (i = 0; i < 4 * dwords; i += 4) {
9478 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
9479 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
9480 }
9481 return;
1da177e4
LT
9482}
9483
9484/*
9485 * Copy 2 bytes from LRAM.
9486 *
9487 * The source data is assumed to be in little-endian order in LRAM
9488 * and is maintained in little-endian order when written to memory.
9489 */
27c868c2
MW
9490static void
9491AscMemWordCopyPtrFromLram(PortAddr iop_base,
9492 ushort s_addr, uchar *d_buffer, int words)
1da177e4 9493{
27c868c2
MW
9494 int i;
9495 ushort word;
9496
9497 AscSetChipLramAddr(iop_base, s_addr);
9498 for (i = 0; i < 2 * words; i += 2) {
9499 word = inpw(iop_base + IOP_RAM_DATA);
9500 d_buffer[i] = word & 0xff;
9501 d_buffer[i + 1] = (word >> 8) & 0xff;
9502 }
9503 return;
1da177e4
LT
9504}
9505
27c868c2 9506static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 9507{
27c868c2
MW
9508 ASC_DCNT sum;
9509 int i;
1da177e4 9510
27c868c2
MW
9511 sum = 0L;
9512 for (i = 0; i < words; i++, s_addr += 2) {
9513 sum += AscReadLramWord(iop_base, s_addr);
9514 }
9515 return (sum);
1da177e4
LT
9516}
9517
27c868c2
MW
9518static void
9519AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 9520{
27c868c2 9521 int i;
1da177e4 9522
27c868c2
MW
9523 AscSetChipLramAddr(iop_base, s_addr);
9524 for (i = 0; i < words; i++) {
9525 AscSetChipLramData(iop_base, set_wval);
9526 }
9527 return;
1da177e4
LT
9528}
9529
1da177e4
LT
9530/*
9531 * --- Adv Library Functions
9532 */
9533
9534/* a_mcode.h */
9535
9536/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9537static unsigned char _adv_asc3550_buf[] = {
9538 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
629d688d
MW
9539 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
9540 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
9541 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
27c868c2 9542 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
629d688d
MW
9543 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
9544 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
9545 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
27c868c2 9546 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
629d688d
MW
9547 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
9548 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
9549 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
27c868c2 9550 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
629d688d
MW
9551 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
9552 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
9553 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
27c868c2 9554 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
629d688d
MW
9555 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
9556 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
9557 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
27c868c2 9558 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
629d688d
MW
9559 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
9560 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
9561 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
27c868c2 9562 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
629d688d
MW
9563 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
9564 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
9565 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
27c868c2 9566 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
629d688d
MW
9567 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
9568 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
9569 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
27c868c2 9570 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
629d688d
MW
9571 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
9572 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
9573 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
27c868c2 9574 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
629d688d
MW
9575 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
9576 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
9577 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
27c868c2 9578 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
629d688d
MW
9579 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
9580 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
9581 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
27c868c2 9582 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
9583 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
9584 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
9585 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
27c868c2 9586 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
9587 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
9588 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
9589 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
27c868c2 9590 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
629d688d
MW
9591 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
9592 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
9593 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
27c868c2 9594 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
629d688d
MW
9595 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
9596 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
9597 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
27c868c2 9598 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
629d688d
MW
9599 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
9600 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
9601 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
27c868c2 9602 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
9603 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
9604 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
9605 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
27c868c2 9606 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
629d688d
MW
9607 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
9608 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
9609 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
27c868c2 9610 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
629d688d
MW
9611 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
9612 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
9613 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
27c868c2 9614 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
629d688d
MW
9615 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
9616 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
9617 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
27c868c2 9618 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
629d688d
MW
9619 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
9620 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
9621 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
27c868c2 9622 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
629d688d
MW
9623 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
9624 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
9625 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
27c868c2 9626 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
629d688d
MW
9627 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
9628 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
9629 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
27c868c2 9630 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
629d688d
MW
9631 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
9632 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
9633 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
27c868c2 9634 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
629d688d
MW
9635 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
9636 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
9637 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
27c868c2 9638 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
629d688d
MW
9639 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
9640 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
9641 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
27c868c2 9642 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
629d688d
MW
9643 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
9644 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
9645 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
27c868c2 9646 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
629d688d
MW
9647 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
9648 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
9649 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
27c868c2 9650 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
629d688d
MW
9651 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
9652 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
9653 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
27c868c2 9654 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
629d688d
MW
9655 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
9656 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
9657 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
27c868c2 9658 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
629d688d
MW
9659 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
9660 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
9661 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
27c868c2 9662 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
629d688d
MW
9663 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
9664 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
9665 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
27c868c2 9666 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
629d688d
MW
9667 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
9668 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
9669 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
27c868c2 9670 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
629d688d
MW
9671 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
9672 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
9673 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
27c868c2 9674 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
629d688d
MW
9675 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
9676 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
9677 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
27c868c2 9678 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
629d688d
MW
9679 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
9680 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
9681 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
27c868c2 9682 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
629d688d
MW
9683 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
9684 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
9685 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
27c868c2 9686 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
629d688d
MW
9687 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
9688 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
9689 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
27c868c2 9690 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
629d688d
MW
9691 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
9692 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
9693 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
27c868c2 9694 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
629d688d
MW
9695 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
9696 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
9697 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
27c868c2 9698 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
629d688d
MW
9699 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
9700 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
9701 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
27c868c2 9702 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
629d688d
MW
9703 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
9704 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
9705 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
27c868c2 9706 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
629d688d
MW
9707 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
9708 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
9709 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
27c868c2 9710 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
629d688d
MW
9711 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
9712 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
9713 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
27c868c2 9714 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
629d688d
MW
9715 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
9716 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
9717 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
27c868c2 9718 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
629d688d
MW
9719 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
9720 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
9721 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
27c868c2 9722 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
629d688d
MW
9723 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
9724 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
9725 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
27c868c2 9726 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
629d688d
MW
9727 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
9728 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
9729 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
27c868c2 9730 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
629d688d
MW
9731 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
9732 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
9733 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
27c868c2 9734 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
629d688d
MW
9735 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
9736 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
9737 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
27c868c2 9738 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
629d688d
MW
9739 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
9740 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
9741 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
27c868c2 9742 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
629d688d
MW
9743 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
9744 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
9745 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
27c868c2 9746 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
629d688d
MW
9747 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
9748 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
9749 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
27c868c2 9750 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
629d688d
MW
9751 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
9752 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
9753 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
27c868c2 9754 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
629d688d
MW
9755 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
9756 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
9757 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
27c868c2 9758 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
629d688d
MW
9759 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
9760 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
9761 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
27c868c2 9762 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
629d688d
MW
9763 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
9764 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
9765 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
27c868c2 9766 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
629d688d
MW
9767 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
9768 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
9769 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
27c868c2 9770 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
629d688d
MW
9771 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
9772 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
9773 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
27c868c2 9774 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
629d688d
MW
9775 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
9776 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
9777 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
27c868c2 9778 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
629d688d
MW
9779 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
9780 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
9781 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
27c868c2 9782 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
629d688d
MW
9783 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
9784 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
9785 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
27c868c2 9786 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
629d688d
MW
9787 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
9788 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
9789 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
27c868c2 9790 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
629d688d
MW
9791 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
9792 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
9793 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
27c868c2 9794 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
629d688d
MW
9795 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
9796 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
9797 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
27c868c2 9798 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
629d688d
MW
9799 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
9800 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
9801 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
27c868c2 9802 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
629d688d
MW
9803 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
9804 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
9805 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
27c868c2 9806 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
629d688d
MW
9807 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
9808 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
9809 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
27c868c2 9810 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
629d688d
MW
9811 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
9812 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
9813 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
27c868c2 9814 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
629d688d
MW
9815 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
9816 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
9817 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
27c868c2 9818 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
629d688d
MW
9819 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
9820 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
9821 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
27c868c2 9822 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
629d688d
MW
9823 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
9824 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
9825 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
27c868c2 9826 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
629d688d
MW
9827 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
9828 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
9829 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
27c868c2 9830 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
629d688d
MW
9831 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
9832 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
9833 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
27c868c2 9834 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
629d688d
MW
9835 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
9836 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
9837 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
27c868c2 9838 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
629d688d
MW
9839 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
9840 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
9841 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
27c868c2 9842 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
629d688d
MW
9843 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
9844 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
9845 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
27c868c2 9846 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
629d688d
MW
9847 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
9848 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
9849 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
27c868c2 9850 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
629d688d
MW
9851 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
9852 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
9853 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
27c868c2 9854 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
629d688d
MW
9855 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
9856 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
9857 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
27c868c2 9858 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
629d688d
MW
9859 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
9860 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
9861 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
27c868c2 9862 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
629d688d
MW
9863 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
9864 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
9865 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
27c868c2 9866 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
629d688d
MW
9867 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
9868 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
9869 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
27c868c2 9870 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
629d688d
MW
9871 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
9872 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
9873 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
27c868c2 9874 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
629d688d
MW
9875 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
9876 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
9877 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
27c868c2 9878 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
629d688d
MW
9879 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
9880 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
9881 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
27c868c2 9882 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
629d688d
MW
9883 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
9884 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
9885 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
27c868c2 9886 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
629d688d
MW
9887 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
9888 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
9889 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
27c868c2 9890 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
629d688d
MW
9891 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
9892 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
9893 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
27c868c2 9894 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
629d688d
MW
9895 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
9896 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
9897 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
27c868c2 9898 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
629d688d
MW
9899 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
9900 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
9901 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
27c868c2 9902 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
629d688d
MW
9903 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
9904 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
9905 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
27c868c2 9906 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
629d688d
MW
9907 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
9908 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
9909 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
27c868c2 9910 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
629d688d
MW
9911 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
9912 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
9913 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
27c868c2 9914 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
629d688d
MW
9915 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
9916 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
9917 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
27c868c2 9918 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
629d688d
MW
9919 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
9920 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
9921 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
27c868c2 9922 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
629d688d
MW
9923 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
9924 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
9925 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
27c868c2 9926 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
629d688d
MW
9927 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
9928 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
9929 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
27c868c2 9930 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
629d688d
MW
9931 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
9932 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
9933 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
27c868c2 9934 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
629d688d
MW
9935 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
9936 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
9937 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
27c868c2 9938 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
629d688d
MW
9939 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
9940 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
9941 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
27c868c2 9942 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
629d688d
MW
9943 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
9944 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
9945 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
27c868c2 9946 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
629d688d
MW
9947 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
9948 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
9949 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
27c868c2 9950 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
629d688d
MW
9951 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
9952 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
9953 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
27c868c2 9954 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
629d688d
MW
9955 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
9956 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
1da177e4
LT
9957};
9958
27c868c2
MW
9959static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
9960static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
9961
9962/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9963static unsigned char _adv_asc38C0800_buf[] = {
9964 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
629d688d
MW
9965 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
9966 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
9967 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
27c868c2 9968 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
629d688d
MW
9969 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
9970 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
9971 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
27c868c2 9972 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
629d688d
MW
9973 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
9974 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
9975 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
27c868c2 9976 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
629d688d
MW
9977 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
9978 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
9979 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
27c868c2 9980 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
629d688d
MW
9981 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
9982 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
9983 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
27c868c2 9984 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
629d688d
MW
9985 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
9986 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
9987 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
27c868c2 9988 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
629d688d
MW
9989 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
9990 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
9991 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
27c868c2 9992 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
629d688d
MW
9993 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
9994 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
9995 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
27c868c2 9996 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
629d688d
MW
9997 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
9998 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
9999 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
27c868c2 10000 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
629d688d
MW
10001 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
10002 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
10003 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
27c868c2 10004 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
629d688d
MW
10005 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
10006 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
10007 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
27c868c2 10008 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
10009 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
10010 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
10011 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
27c868c2 10012 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
10013 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
10014 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
10015 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
27c868c2 10016 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
629d688d
MW
10017 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
10018 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
10019 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
27c868c2 10020 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
629d688d
MW
10021 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
10022 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
10023 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
27c868c2 10024 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
629d688d
MW
10025 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
10026 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
10027 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
27c868c2 10028 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
10029 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
10030 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
10031 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
27c868c2 10032 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
629d688d
MW
10033 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
10034 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
10035 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
27c868c2 10036 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
629d688d
MW
10037 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
10038 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
10039 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
27c868c2 10040 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
629d688d
MW
10041 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
10042 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
10043 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
27c868c2 10044 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
629d688d
MW
10045 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
10046 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
10047 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
27c868c2 10048 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
629d688d
MW
10049 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
10050 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
10051 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
27c868c2 10052 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
629d688d
MW
10053 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
10054 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
10055 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
27c868c2 10056 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
629d688d
MW
10057 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
10058 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
10059 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
27c868c2 10060 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
629d688d
MW
10061 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
10062 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
10063 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
27c868c2 10064 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
629d688d
MW
10065 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
10066 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
10067 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
27c868c2 10068 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
629d688d
MW
10069 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
10070 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
10071 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
27c868c2 10072 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
629d688d
MW
10073 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
10074 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
10075 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
27c868c2 10076 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
629d688d
MW
10077 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
10078 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
10079 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
27c868c2 10080 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
629d688d
MW
10081 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
10082 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
10083 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
27c868c2 10084 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
629d688d
MW
10085 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
10086 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
10087 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
27c868c2 10088 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
629d688d
MW
10089 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
10090 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
10091 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
27c868c2 10092 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
629d688d
MW
10093 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
10094 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
10095 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
27c868c2 10096 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
629d688d
MW
10097 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
10098 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
10099 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
27c868c2 10100 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
629d688d
MW
10101 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
10102 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
10103 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
27c868c2 10104 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
629d688d
MW
10105 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
10106 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
10107 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
27c868c2 10108 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
629d688d
MW
10109 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
10110 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
10111 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
27c868c2 10112 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
629d688d
MW
10113 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
10114 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
10115 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
27c868c2 10116 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
629d688d
MW
10117 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
10118 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
10119 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
27c868c2 10120 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
629d688d
MW
10121 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
10122 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
10123 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
27c868c2 10124 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
629d688d
MW
10125 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
10126 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
10127 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
27c868c2 10128 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
629d688d
MW
10129 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
10130 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
10131 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
27c868c2 10132 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
629d688d
MW
10133 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
10134 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
10135 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
27c868c2 10136 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
629d688d
MW
10137 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
10138 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
10139 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
27c868c2 10140 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
629d688d
MW
10141 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
10142 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
10143 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
27c868c2 10144 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
629d688d
MW
10145 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
10146 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
10147 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
27c868c2 10148 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
629d688d
MW
10149 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
10150 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
10151 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
27c868c2 10152 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
629d688d
MW
10153 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
10154 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
10155 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
27c868c2 10156 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
629d688d
MW
10157 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
10158 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
10159 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
27c868c2 10160 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
629d688d
MW
10161 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
10162 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
10163 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
27c868c2 10164 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
629d688d
MW
10165 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
10166 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
10167 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
27c868c2 10168 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
629d688d
MW
10169 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
10170 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
10171 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
27c868c2 10172 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
629d688d
MW
10173 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
10174 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
10175 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
27c868c2 10176 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
629d688d
MW
10177 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
10178 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
10179 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
27c868c2 10180 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
629d688d
MW
10181 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
10182 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
10183 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
27c868c2 10184 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
629d688d
MW
10185 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
10186 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
10187 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
27c868c2 10188 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
629d688d
MW
10189 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
10190 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
10191 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
27c868c2 10192 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
629d688d
MW
10193 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
10194 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
10195 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
27c868c2 10196 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
629d688d
MW
10197 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
10198 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
10199 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
27c868c2 10200 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
629d688d
MW
10201 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
10202 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
10203 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
27c868c2 10204 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
629d688d
MW
10205 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
10206 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
10207 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
27c868c2 10208 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
629d688d
MW
10209 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
10210 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
10211 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
27c868c2 10212 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
629d688d
MW
10213 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
10214 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
10215 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
27c868c2 10216 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
629d688d
MW
10217 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
10218 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
10219 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
27c868c2 10220 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
629d688d
MW
10221 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
10222 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
10223 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
27c868c2 10224 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
629d688d
MW
10225 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
10226 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
10227 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
27c868c2 10228 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
629d688d
MW
10229 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
10230 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
10231 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
27c868c2 10232 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
629d688d
MW
10233 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
10234 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
10235 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
27c868c2 10236 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
629d688d
MW
10237 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
10238 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
10239 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
27c868c2 10240 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
629d688d
MW
10241 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
10242 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
10243 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
27c868c2 10244 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
629d688d
MW
10245 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
10246 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
10247 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
27c868c2 10248 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
629d688d
MW
10249 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
10250 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
10251 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
27c868c2 10252 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
629d688d
MW
10253 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
10254 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
10255 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
27c868c2 10256 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
629d688d
MW
10257 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
10258 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
10259 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
27c868c2 10260 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
629d688d
MW
10261 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
10262 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
10263 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
27c868c2 10264 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
629d688d
MW
10265 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
10266 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
10267 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
27c868c2 10268 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
629d688d
MW
10269 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
10270 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
10271 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
27c868c2 10272 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
629d688d
MW
10273 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
10274 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
10275 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
27c868c2 10276 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
629d688d
MW
10277 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
10278 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
10279 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
27c868c2 10280 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
629d688d
MW
10281 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
10282 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
10283 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
27c868c2 10284 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
629d688d
MW
10285 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
10286 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
10287 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
27c868c2 10288 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
629d688d
MW
10289 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
10290 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
10291 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
27c868c2 10292 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
629d688d
MW
10293 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
10294 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
10295 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
27c868c2 10296 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
629d688d
MW
10297 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
10298 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
10299 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
27c868c2 10300 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
629d688d
MW
10301 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
10302 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
10303 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
27c868c2 10304 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
629d688d
MW
10305 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
10306 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
10307 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
27c868c2 10308 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
629d688d
MW
10309 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
10310 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10311 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
27c868c2 10312 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
629d688d
MW
10313 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10314 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
10315 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
27c868c2 10316 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
629d688d
MW
10317 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
10318 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
10319 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
27c868c2 10320 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
629d688d
MW
10321 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
10322 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
10323 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
27c868c2 10324 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
629d688d
MW
10325 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
10326 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
10327 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
27c868c2 10328 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
629d688d
MW
10329 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
10330 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
10331 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
27c868c2 10332 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
629d688d
MW
10333 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
10334 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
10335 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
27c868c2 10336 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
629d688d
MW
10337 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
10338 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
10339 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
27c868c2 10340 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
629d688d
MW
10341 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
10342 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
10343 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
27c868c2 10344 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
629d688d
MW
10345 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
10346 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
10347 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
27c868c2 10348 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
629d688d
MW
10349 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
10350 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
10351 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
27c868c2 10352 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
629d688d
MW
10353 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
10354 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
10355 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
27c868c2 10356 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
629d688d
MW
10357 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
10358 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
10359 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
27c868c2 10360 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
629d688d
MW
10361 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
10362 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
10363 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
27c868c2 10364 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
629d688d
MW
10365 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
10366 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
10367 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
27c868c2 10368 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
629d688d
MW
10369 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
10370 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
10371 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
27c868c2 10372 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
629d688d
MW
10373 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
10374 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
10375 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
27c868c2 10376 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
629d688d
MW
10377 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
10378 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
10379 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
27c868c2 10380 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
629d688d
MW
10381 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
10382 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
10383 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
27c868c2 10384 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
629d688d
MW
10385 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
10386 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
10387 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
27c868c2 10388 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
629d688d
MW
10389 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
10390 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
10391 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
27c868c2 10392 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
629d688d
MW
10393 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
10394 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
10395 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
27c868c2 10396 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
629d688d
MW
10397 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
10398 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
10399 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
27c868c2 10400 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
629d688d
MW
10401 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
10402 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
10403 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
27c868c2 10404 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
629d688d
MW
10405 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
10406 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
10407 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
27c868c2 10408 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
10409};
10410
27c868c2
MW
10411static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
10412static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
10413
10414/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
10415static unsigned char _adv_asc38C1600_buf[] = {
10416 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
629d688d
MW
10417 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
10418 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
10419 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
27c868c2 10420 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
629d688d
MW
10421 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
10422 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
10423 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
27c868c2 10424 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
629d688d
MW
10425 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
10426 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
10427 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
27c868c2 10428 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
629d688d
MW
10429 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
10430 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
10431 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
27c868c2 10432 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
629d688d
MW
10433 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
10434 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
10435 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
27c868c2 10436 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
629d688d
MW
10437 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
10438 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
10439 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
27c868c2 10440 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
629d688d
MW
10441 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
10442 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
10443 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
27c868c2 10444 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
629d688d
MW
10445 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
10446 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
10447 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
27c868c2 10448 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
629d688d
MW
10449 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
10450 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
10451 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
27c868c2 10452 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
629d688d
MW
10453 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
10454 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
10455 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
27c868c2 10456 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
629d688d
MW
10457 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
10458 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
10459 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
27c868c2 10460 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
10461 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
10462 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
10463 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
27c868c2 10464 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
10465 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
10466 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
10467 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
27c868c2 10468 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
629d688d
MW
10469 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
10470 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
10471 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
27c868c2 10472 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
629d688d
MW
10473 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
10474 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
10475 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
27c868c2 10476 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
629d688d
MW
10477 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
10478 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
10479 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
27c868c2 10480 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
629d688d
MW
10481 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
10482 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
10483 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
27c868c2 10484 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
629d688d
MW
10485 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
10486 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
10487 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
27c868c2 10488 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
629d688d
MW
10489 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
10490 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
10491 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
27c868c2 10492 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
629d688d
MW
10493 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
10494 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
10495 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
27c868c2 10496 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
629d688d
MW
10497 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
10498 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
10499 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
27c868c2 10500 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
629d688d
MW
10501 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
10502 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
10503 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
27c868c2 10504 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
629d688d
MW
10505 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
10506 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
10507 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
27c868c2 10508 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
629d688d
MW
10509 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
10510 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
10511 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
27c868c2 10512 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
629d688d
MW
10513 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
10514 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
10515 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
27c868c2 10516 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
629d688d
MW
10517 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
10518 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
10519 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
27c868c2 10520 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
629d688d
MW
10521 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
10522 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
10523 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
27c868c2 10524 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
629d688d
MW
10525 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
10526 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
10527 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
27c868c2 10528 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
629d688d
MW
10529 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
10530 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
10531 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
27c868c2 10532 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
629d688d
MW
10533 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
10534 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
10535 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
27c868c2 10536 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
629d688d
MW
10537 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
10538 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
10539 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
27c868c2 10540 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
629d688d
MW
10541 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
10542 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
10543 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
27c868c2 10544 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
629d688d
MW
10545 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
10546 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
10547 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
27c868c2 10548 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
629d688d
MW
10549 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
10550 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
10551 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
27c868c2 10552 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
629d688d
MW
10553 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
10554 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
10555 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
27c868c2 10556 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
629d688d
MW
10557 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
10558 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
10559 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
27c868c2 10560 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
629d688d
MW
10561 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
10562 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
10563 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
27c868c2 10564 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
629d688d
MW
10565 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
10566 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
10567 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
27c868c2 10568 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
629d688d
MW
10569 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
10570 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
10571 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
27c868c2 10572 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
629d688d
MW
10573 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
10574 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
10575 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
27c868c2 10576 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
629d688d
MW
10577 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
10578 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
10579 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
27c868c2 10580 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
629d688d
MW
10581 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
10582 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
10583 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 10584 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
629d688d
MW
10585 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
10586 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
10587 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
27c868c2 10588 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
629d688d
MW
10589 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
10590 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
10591 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 10592 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
629d688d
MW
10593 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
10594 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
10595 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
27c868c2 10596 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
629d688d
MW
10597 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
10598 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
10599 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
27c868c2 10600 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
629d688d
MW
10601 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
10602 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
10603 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
27c868c2 10604 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
629d688d
MW
10605 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
10606 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
10607 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
27c868c2 10608 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
629d688d
MW
10609 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
10610 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
10611 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
27c868c2 10612 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
629d688d
MW
10613 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
10614 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
10615 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
27c868c2 10616 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
629d688d
MW
10617 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
10618 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
10619 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
27c868c2 10620 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
629d688d
MW
10621 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
10622 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
10623 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
27c868c2 10624 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
629d688d
MW
10625 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
10626 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
10627 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
27c868c2 10628 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
629d688d
MW
10629 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
10630 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
10631 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
27c868c2 10632 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
629d688d
MW
10633 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
10634 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
10635 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
27c868c2 10636 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
629d688d
MW
10637 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
10638 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
10639 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
27c868c2 10640 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
629d688d
MW
10641 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
10642 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
10643 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
27c868c2 10644 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
629d688d
MW
10645 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
10646 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
10647 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
27c868c2 10648 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
629d688d
MW
10649 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
10650 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
10651 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
27c868c2 10652 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
629d688d
MW
10653 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
10654 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
10655 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
27c868c2 10656 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
629d688d
MW
10657 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
10658 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
10659 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
27c868c2 10660 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
629d688d
MW
10661 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
10662 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
10663 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
27c868c2 10664 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
629d688d
MW
10665 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
10666 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
10667 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
27c868c2 10668 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
629d688d
MW
10669 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
10670 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
10671 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
27c868c2 10672 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
629d688d
MW
10673 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
10674 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
10675 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
27c868c2 10676 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
629d688d
MW
10677 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
10678 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
10679 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
27c868c2 10680 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
629d688d
MW
10681 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
10682 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
10683 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
27c868c2 10684 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
629d688d
MW
10685 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
10686 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
10687 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
27c868c2 10688 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
629d688d
MW
10689 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
10690 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
10691 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
27c868c2 10692 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
629d688d
MW
10693 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
10694 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
10695 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
27c868c2 10696 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
629d688d
MW
10697 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
10698 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
10699 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
27c868c2 10700 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
629d688d
MW
10701 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
10702 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
10703 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
27c868c2 10704 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
629d688d
MW
10705 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
10706 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
10707 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
27c868c2 10708 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
629d688d
MW
10709 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
10710 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
10711 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
27c868c2 10712 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
629d688d
MW
10713 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
10714 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
10715 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
27c868c2 10716 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
629d688d
MW
10717 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
10718 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
10719 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
27c868c2 10720 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
629d688d
MW
10721 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
10722 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
10723 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
27c868c2 10724 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
629d688d
MW
10725 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
10726 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
10727 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
27c868c2 10728 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
629d688d
MW
10729 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
10730 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
10731 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
27c868c2 10732 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
629d688d
MW
10733 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
10734 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
10735 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
27c868c2 10736 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
629d688d
MW
10737 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
10738 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
10739 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
27c868c2 10740 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
629d688d
MW
10741 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
10742 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
10743 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
27c868c2 10744 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
629d688d
MW
10745 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
10746 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
10747 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
27c868c2 10748 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
629d688d
MW
10749 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
10750 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
10751 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
27c868c2 10752 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
629d688d
MW
10753 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
10754 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
10755 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
27c868c2 10756 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
629d688d
MW
10757 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
10758 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
10759 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
27c868c2 10760 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
629d688d
MW
10761 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
10762 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
10763 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
27c868c2 10764 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
629d688d
MW
10765 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
10766 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
10767 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
27c868c2 10768 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
629d688d
MW
10769 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
10770 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
10771 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
27c868c2 10772 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
629d688d
MW
10773 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
10774 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
10775 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
27c868c2 10776 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
629d688d
MW
10777 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
10778 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
10779 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
27c868c2 10780 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
629d688d
MW
10781 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
10782 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
10783 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
27c868c2 10784 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
629d688d
MW
10785 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
10786 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
10787 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
27c868c2 10788 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
629d688d
MW
10789 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
10790 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
10791 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
27c868c2 10792 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
629d688d
MW
10793 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
10794 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
10795 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
27c868c2 10796 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
629d688d
MW
10797 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
10798 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
10799 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
27c868c2 10800 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
629d688d
MW
10801 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
10802 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
10803 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
27c868c2 10804 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
629d688d
MW
10805 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
10806 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
10807 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
27c868c2 10808 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
629d688d
MW
10809 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
10810 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
10811 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
27c868c2 10812 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
629d688d
MW
10813 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
10814 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
10815 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
27c868c2 10816 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
629d688d
MW
10817 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
10818 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
10819 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
27c868c2 10820 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
629d688d
MW
10821 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
10822 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
10823 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
27c868c2 10824 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
629d688d
MW
10825 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
10826 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
10827 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
27c868c2 10828 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
629d688d
MW
10829 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
10830 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
10831 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
27c868c2 10832 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
629d688d
MW
10833 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
10834 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
10835 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
27c868c2 10836 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
629d688d
MW
10837 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
10838 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
10839 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
27c868c2 10840 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
629d688d
MW
10841 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
10842 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
10843 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
27c868c2 10844 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
629d688d
MW
10845 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
10846 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
10847 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
27c868c2 10848 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
629d688d
MW
10849 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
10850 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
10851 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
27c868c2 10852 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
629d688d
MW
10853 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
10854 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
10855 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
27c868c2 10856 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
629d688d
MW
10857 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
10858 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
10859 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
27c868c2 10860 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
629d688d
MW
10861 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
10862 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
10863 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
27c868c2 10864 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
629d688d
MW
10865 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
10866 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
10867 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
27c868c2 10868 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
629d688d
MW
10869 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
10870 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
10871 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
27c868c2 10872 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
629d688d
MW
10873 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
10874 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
10875 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
27c868c2 10876 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
629d688d
MW
10877 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
10878 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
10879 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
27c868c2 10880 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
629d688d
MW
10881 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
10882 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
10883 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
27c868c2 10884 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
629d688d
MW
10885 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
10886 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
10887 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
27c868c2 10888 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
629d688d
MW
10889 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
10890 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
10891 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
27c868c2 10892 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
629d688d
MW
10893 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
10894 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
10895 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
27c868c2 10896 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
629d688d
MW
10897 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
10898 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
10899 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
27c868c2 10900 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
629d688d
MW
10901 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
10902 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
10903 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
27c868c2 10904 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
629d688d
MW
10905 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
10906 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
10907 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
27c868c2 10908 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
629d688d
MW
10909 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
10910 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
10911 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
27c868c2 10912 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
629d688d
MW
10913 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
10914 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
10915 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
27c868c2 10916 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
629d688d
MW
10917 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
10918 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
10919 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
27c868c2 10920 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
629d688d
MW
10921 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
10922 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
10923 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
27c868c2 10924 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
629d688d
MW
10925 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
10926 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
10927 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
27c868c2 10928 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
629d688d
MW
10929 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
10930 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
10931 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
27c868c2 10932 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
629d688d
MW
10933 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
10934 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
10935 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 10936 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
10937 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
10938 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
10939 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 10940 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
10941 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
10942 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
10943 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
10944};
10945
27c868c2
MW
10946static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
10947static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4 10948
1da177e4
LT
10949/*
10950 * EEPROM Configuration.
10951 *
10952 * All drivers should use this structure to set the default EEPROM
10953 * configuration. The BIOS now uses this structure when it is built.
10954 * Additional structure information can be found in a_condor.h where
10955 * the structure is defined.
10956 *
10957 * The *_Field_IsChar structs are needed to correct for endianness.
10958 * These values are read from the board 16 bits at a time directly
10959 * into the structs. Because some fields are char, the values will be
10960 * in the wrong order. The *_Field_IsChar tells when to flip the
10961 * bytes. Data read and written to PCI memory is automatically swapped
10962 * on big-endian platforms so char fields read as words are actually being
10963 * unswapped on big-endian platforms.
10964 */
78e77d8b 10965static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
27c868c2
MW
10966 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
10967 0x0000, /* cfg_msw */
10968 0xFFFF, /* disc_enable */
10969 0xFFFF, /* wdtr_able */
10970 0xFFFF, /* sdtr_able */
10971 0xFFFF, /* start_motor */
10972 0xFFFF, /* tagqng_able */
10973 0xFFFF, /* bios_scan */
10974 0, /* scam_tolerant */
10975 7, /* adapter_scsi_id */
10976 0, /* bios_boot_delay */
10977 3, /* scsi_reset_delay */
10978 0, /* bios_id_lun */
10979 0, /* termination */
10980 0, /* reserved1 */
10981 0xFFE7, /* bios_ctrl */
10982 0xFFFF, /* ultra_able */
10983 0, /* reserved2 */
10984 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
10985 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
10986 0, /* dvc_cntl */
10987 0, /* bug_fix */
10988 0, /* serial_number_word1 */
10989 0, /* serial_number_word2 */
10990 0, /* serial_number_word3 */
10991 0, /* check_sum */
10992 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
10993 , /* oem_name[16] */
10994 0, /* dvc_err_code */
10995 0, /* adv_err_code */
10996 0, /* adv_err_addr */
10997 0, /* saved_dvc_err_code */
10998 0, /* saved_adv_err_code */
10999 0, /* saved_adv_err_addr */
11000 0 /* num_of_err */
1da177e4
LT
11001};
11002
78e77d8b 11003static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11004 0, /* cfg_lsw */
11005 0, /* cfg_msw */
11006 0, /* -disc_enable */
11007 0, /* wdtr_able */
11008 0, /* sdtr_able */
11009 0, /* start_motor */
11010 0, /* tagqng_able */
11011 0, /* bios_scan */
11012 0, /* scam_tolerant */
11013 1, /* adapter_scsi_id */
11014 1, /* bios_boot_delay */
11015 1, /* scsi_reset_delay */
11016 1, /* bios_id_lun */
11017 1, /* termination */
11018 1, /* reserved1 */
11019 0, /* bios_ctrl */
11020 0, /* ultra_able */
11021 0, /* reserved2 */
11022 1, /* max_host_qng */
11023 1, /* max_dvc_qng */
11024 0, /* dvc_cntl */
11025 0, /* bug_fix */
11026 0, /* serial_number_word1 */
11027 0, /* serial_number_word2 */
11028 0, /* serial_number_word3 */
11029 0, /* check_sum */
11030 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11031 , /* oem_name[16] */
11032 0, /* dvc_err_code */
11033 0, /* adv_err_code */
11034 0, /* adv_err_addr */
11035 0, /* saved_dvc_err_code */
11036 0, /* saved_adv_err_code */
11037 0, /* saved_adv_err_addr */
11038 0 /* num_of_err */
1da177e4
LT
11039};
11040
78e77d8b 11041static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
27c868c2
MW
11042 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
11043 0x0000, /* 01 cfg_msw */
11044 0xFFFF, /* 02 disc_enable */
11045 0xFFFF, /* 03 wdtr_able */
11046 0x4444, /* 04 sdtr_speed1 */
11047 0xFFFF, /* 05 start_motor */
11048 0xFFFF, /* 06 tagqng_able */
11049 0xFFFF, /* 07 bios_scan */
11050 0, /* 08 scam_tolerant */
11051 7, /* 09 adapter_scsi_id */
11052 0, /* bios_boot_delay */
11053 3, /* 10 scsi_reset_delay */
11054 0, /* bios_id_lun */
11055 0, /* 11 termination_se */
11056 0, /* termination_lvd */
11057 0xFFE7, /* 12 bios_ctrl */
11058 0x4444, /* 13 sdtr_speed2 */
11059 0x4444, /* 14 sdtr_speed3 */
11060 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
11061 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11062 0, /* 16 dvc_cntl */
11063 0x4444, /* 17 sdtr_speed4 */
11064 0, /* 18 serial_number_word1 */
11065 0, /* 19 serial_number_word2 */
11066 0, /* 20 serial_number_word3 */
11067 0, /* 21 check_sum */
11068 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11069 , /* 22-29 oem_name[16] */
11070 0, /* 30 dvc_err_code */
11071 0, /* 31 adv_err_code */
11072 0, /* 32 adv_err_addr */
11073 0, /* 33 saved_dvc_err_code */
11074 0, /* 34 saved_adv_err_code */
11075 0, /* 35 saved_adv_err_addr */
11076 0, /* 36 reserved */
11077 0, /* 37 reserved */
11078 0, /* 38 reserved */
11079 0, /* 39 reserved */
11080 0, /* 40 reserved */
11081 0, /* 41 reserved */
11082 0, /* 42 reserved */
11083 0, /* 43 reserved */
11084 0, /* 44 reserved */
11085 0, /* 45 reserved */
11086 0, /* 46 reserved */
11087 0, /* 47 reserved */
11088 0, /* 48 reserved */
11089 0, /* 49 reserved */
11090 0, /* 50 reserved */
11091 0, /* 51 reserved */
11092 0, /* 52 reserved */
11093 0, /* 53 reserved */
11094 0, /* 54 reserved */
11095 0, /* 55 reserved */
11096 0, /* 56 cisptr_lsw */
11097 0, /* 57 cisprt_msw */
11098 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
11099 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
11100 0, /* 60 reserved */
11101 0, /* 61 reserved */
11102 0, /* 62 reserved */
11103 0 /* 63 reserved */
1da177e4
LT
11104};
11105
78e77d8b 11106static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11107 0, /* 00 cfg_lsw */
11108 0, /* 01 cfg_msw */
11109 0, /* 02 disc_enable */
11110 0, /* 03 wdtr_able */
11111 0, /* 04 sdtr_speed1 */
11112 0, /* 05 start_motor */
11113 0, /* 06 tagqng_able */
11114 0, /* 07 bios_scan */
11115 0, /* 08 scam_tolerant */
11116 1, /* 09 adapter_scsi_id */
11117 1, /* bios_boot_delay */
11118 1, /* 10 scsi_reset_delay */
11119 1, /* bios_id_lun */
11120 1, /* 11 termination_se */
11121 1, /* termination_lvd */
11122 0, /* 12 bios_ctrl */
11123 0, /* 13 sdtr_speed2 */
11124 0, /* 14 sdtr_speed3 */
11125 1, /* 15 max_host_qng */
11126 1, /* max_dvc_qng */
11127 0, /* 16 dvc_cntl */
11128 0, /* 17 sdtr_speed4 */
11129 0, /* 18 serial_number_word1 */
11130 0, /* 19 serial_number_word2 */
11131 0, /* 20 serial_number_word3 */
11132 0, /* 21 check_sum */
11133 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11134 , /* 22-29 oem_name[16] */
11135 0, /* 30 dvc_err_code */
11136 0, /* 31 adv_err_code */
11137 0, /* 32 adv_err_addr */
11138 0, /* 33 saved_dvc_err_code */
11139 0, /* 34 saved_adv_err_code */
11140 0, /* 35 saved_adv_err_addr */
11141 0, /* 36 reserved */
11142 0, /* 37 reserved */
11143 0, /* 38 reserved */
11144 0, /* 39 reserved */
11145 0, /* 40 reserved */
11146 0, /* 41 reserved */
11147 0, /* 42 reserved */
11148 0, /* 43 reserved */
11149 0, /* 44 reserved */
11150 0, /* 45 reserved */
11151 0, /* 46 reserved */
11152 0, /* 47 reserved */
11153 0, /* 48 reserved */
11154 0, /* 49 reserved */
11155 0, /* 50 reserved */
11156 0, /* 51 reserved */
11157 0, /* 52 reserved */
11158 0, /* 53 reserved */
11159 0, /* 54 reserved */
11160 0, /* 55 reserved */
11161 0, /* 56 cisptr_lsw */
11162 0, /* 57 cisprt_msw */
11163 0, /* 58 subsysvid */
11164 0, /* 59 subsysid */
11165 0, /* 60 reserved */
11166 0, /* 61 reserved */
11167 0, /* 62 reserved */
11168 0 /* 63 reserved */
1da177e4
LT
11169};
11170
78e77d8b 11171static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
27c868c2
MW
11172 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
11173 0x0000, /* 01 cfg_msw */
11174 0xFFFF, /* 02 disc_enable */
11175 0xFFFF, /* 03 wdtr_able */
11176 0x5555, /* 04 sdtr_speed1 */
11177 0xFFFF, /* 05 start_motor */
11178 0xFFFF, /* 06 tagqng_able */
11179 0xFFFF, /* 07 bios_scan */
11180 0, /* 08 scam_tolerant */
11181 7, /* 09 adapter_scsi_id */
11182 0, /* bios_boot_delay */
11183 3, /* 10 scsi_reset_delay */
11184 0, /* bios_id_lun */
11185 0, /* 11 termination_se */
11186 0, /* termination_lvd */
11187 0xFFE7, /* 12 bios_ctrl */
11188 0x5555, /* 13 sdtr_speed2 */
11189 0x5555, /* 14 sdtr_speed3 */
11190 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
11191 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11192 0, /* 16 dvc_cntl */
11193 0x5555, /* 17 sdtr_speed4 */
11194 0, /* 18 serial_number_word1 */
11195 0, /* 19 serial_number_word2 */
11196 0, /* 20 serial_number_word3 */
11197 0, /* 21 check_sum */
11198 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11199 , /* 22-29 oem_name[16] */
11200 0, /* 30 dvc_err_code */
11201 0, /* 31 adv_err_code */
11202 0, /* 32 adv_err_addr */
11203 0, /* 33 saved_dvc_err_code */
11204 0, /* 34 saved_adv_err_code */
11205 0, /* 35 saved_adv_err_addr */
11206 0, /* 36 reserved */
11207 0, /* 37 reserved */
11208 0, /* 38 reserved */
11209 0, /* 39 reserved */
11210 0, /* 40 reserved */
11211 0, /* 41 reserved */
11212 0, /* 42 reserved */
11213 0, /* 43 reserved */
11214 0, /* 44 reserved */
11215 0, /* 45 reserved */
11216 0, /* 46 reserved */
11217 0, /* 47 reserved */
11218 0, /* 48 reserved */
11219 0, /* 49 reserved */
11220 0, /* 50 reserved */
11221 0, /* 51 reserved */
11222 0, /* 52 reserved */
11223 0, /* 53 reserved */
11224 0, /* 54 reserved */
11225 0, /* 55 reserved */
11226 0, /* 56 cisptr_lsw */
11227 0, /* 57 cisprt_msw */
11228 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
11229 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
11230 0, /* 60 reserved */
11231 0, /* 61 reserved */
11232 0, /* 62 reserved */
11233 0 /* 63 reserved */
1da177e4
LT
11234};
11235
78e77d8b 11236static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11237 0, /* 00 cfg_lsw */
11238 0, /* 01 cfg_msw */
11239 0, /* 02 disc_enable */
11240 0, /* 03 wdtr_able */
11241 0, /* 04 sdtr_speed1 */
11242 0, /* 05 start_motor */
11243 0, /* 06 tagqng_able */
11244 0, /* 07 bios_scan */
11245 0, /* 08 scam_tolerant */
11246 1, /* 09 adapter_scsi_id */
11247 1, /* bios_boot_delay */
11248 1, /* 10 scsi_reset_delay */
11249 1, /* bios_id_lun */
11250 1, /* 11 termination_se */
11251 1, /* termination_lvd */
11252 0, /* 12 bios_ctrl */
11253 0, /* 13 sdtr_speed2 */
11254 0, /* 14 sdtr_speed3 */
11255 1, /* 15 max_host_qng */
11256 1, /* max_dvc_qng */
11257 0, /* 16 dvc_cntl */
11258 0, /* 17 sdtr_speed4 */
11259 0, /* 18 serial_number_word1 */
11260 0, /* 19 serial_number_word2 */
11261 0, /* 20 serial_number_word3 */
11262 0, /* 21 check_sum */
11263 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11264 , /* 22-29 oem_name[16] */
11265 0, /* 30 dvc_err_code */
11266 0, /* 31 adv_err_code */
11267 0, /* 32 adv_err_addr */
11268 0, /* 33 saved_dvc_err_code */
11269 0, /* 34 saved_adv_err_code */
11270 0, /* 35 saved_adv_err_addr */
11271 0, /* 36 reserved */
11272 0, /* 37 reserved */
11273 0, /* 38 reserved */
11274 0, /* 39 reserved */
11275 0, /* 40 reserved */
11276 0, /* 41 reserved */
11277 0, /* 42 reserved */
11278 0, /* 43 reserved */
11279 0, /* 44 reserved */
11280 0, /* 45 reserved */
11281 0, /* 46 reserved */
11282 0, /* 47 reserved */
11283 0, /* 48 reserved */
11284 0, /* 49 reserved */
11285 0, /* 50 reserved */
11286 0, /* 51 reserved */
11287 0, /* 52 reserved */
11288 0, /* 53 reserved */
11289 0, /* 54 reserved */
11290 0, /* 55 reserved */
11291 0, /* 56 cisptr_lsw */
11292 0, /* 57 cisprt_msw */
11293 0, /* 58 subsysvid */
11294 0, /* 59 subsysid */
11295 0, /* 60 reserved */
11296 0, /* 61 reserved */
11297 0, /* 62 reserved */
11298 0 /* 63 reserved */
1da177e4
LT
11299};
11300
c2dce2fa 11301#ifdef CONFIG_PCI
1da177e4
LT
11302/*
11303 * Initialize the ADV_DVC_VAR structure.
11304 *
11305 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11306 *
11307 * For a non-fatal error return a warning code. If there are no warnings
11308 * then 0 is returned.
11309 */
394dbf3f 11310static int __devinit
c2dce2fa 11311AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 11312{
c2dce2fa 11313 ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
9649af39
MW
11314 unsigned short warn_code = 0;
11315 AdvPortAddr iop_base = asc_dvc->iop_base;
9649af39 11316 u16 cmd;
27c868c2
MW
11317 int status;
11318
27c868c2 11319 asc_dvc->err_code = 0;
1da177e4 11320
27c868c2
MW
11321 /*
11322 * Save the state of the PCI Configuration Command Register
11323 * "Parity Error Response Control" Bit. If the bit is clear (0),
11324 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
11325 * DMA parity errors.
11326 */
11327 asc_dvc->cfg->control_flag = 0;
9649af39
MW
11328 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
11329 if ((cmd & PCI_COMMAND_PARITY) == 0)
27c868c2 11330 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
1da177e4 11331
27c868c2
MW
11332 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
11333 ADV_LIB_VERSION_MINOR;
11334 asc_dvc->cfg->chip_version =
11335 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
11336
11337 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
11338 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
11339 (ushort)ADV_CHIP_ID_BYTE);
11340
11341 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
11342 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
11343 (ushort)ADV_CHIP_ID_WORD);
11344
11345 /*
11346 * Reset the chip to start and allow register writes.
11347 */
11348 if (AdvFindSignature(iop_base) == 0) {
11349 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11350 return ADV_ERROR;
11351 } else {
11352 /*
11353 * The caller must set 'chip_type' to a valid setting.
11354 */
11355 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
11356 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
11357 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
11358 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
11359 return ADV_ERROR;
11360 }
1da177e4 11361
27c868c2
MW
11362 /*
11363 * Reset Chip.
11364 */
11365 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11366 ADV_CTRL_REG_CMD_RESET);
11367 DvcSleepMilliSecond(100);
11368 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11369 ADV_CTRL_REG_CMD_WR_IO_REG);
11370
11371 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
9649af39 11372 status = AdvInitFrom38C1600EEP(asc_dvc);
27c868c2 11373 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
9649af39 11374 status = AdvInitFrom38C0800EEP(asc_dvc);
27c868c2 11375 } else {
9649af39 11376 status = AdvInitFrom3550EEP(asc_dvc);
27c868c2
MW
11377 }
11378 warn_code |= status;
11379 }
1da177e4 11380
c2dce2fa
MW
11381 if (warn_code != 0) {
11382 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
11383 boardp->id, warn_code);
11384 }
11385
11386 if (asc_dvc->err_code) {
11387 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
11388 boardp->id, asc_dvc->err_code);
11389 }
11390
11391 return asc_dvc->err_code;
1da177e4 11392}
c2dce2fa 11393#endif
1da177e4 11394
a9f4a59a
MW
11395static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
11396{
11397 ADV_CARR_T *carrp;
11398 ADV_SDCNT buf_size;
11399 ADV_PADDR carr_paddr;
11400
11401 BUG_ON(!asc_dvc->carrier_buf);
11402
11403 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
11404 asc_dvc->carr_freelist = NULL;
11405 if (carrp == asc_dvc->carrier_buf) {
11406 buf_size = ADV_CARRIER_BUFSIZE;
11407 } else {
11408 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
11409 }
11410
11411 do {
11412 /* Get physical address of the carrier 'carrp'. */
11413 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
11414 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
11415 (uchar *)carrp,
11416 (ADV_SDCNT *)&contig_len,
11417 ADV_IS_CARRIER_FLAG));
11418
11419 buf_size -= sizeof(ADV_CARR_T);
11420
11421 /*
11422 * If the current carrier is not physically contiguous, then
11423 * maybe there was a page crossing. Try the next carrier
11424 * aligned start address.
11425 */
11426 if (contig_len < sizeof(ADV_CARR_T)) {
11427 carrp++;
11428 continue;
11429 }
11430
11431 carrp->carr_pa = carr_paddr;
11432 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
11433
11434 /*
11435 * Insert the carrier at the beginning of the freelist.
11436 */
11437 carrp->next_vpa =
11438 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
11439 asc_dvc->carr_freelist = carrp;
11440
11441 carrp++;
11442 } while (buf_size > 0);
11443}
11444
b9d96614
MW
11445/*
11446 * Load the Microcode
11447 *
11448 * Write the microcode image to RISC memory starting at address 0.
11449 *
11450 * The microcode is stored compressed in the following format:
11451 *
11452 * 254 word (508 byte) table indexed by byte code followed
11453 * by the following byte codes:
11454 *
11455 * 1-Byte Code:
11456 * 00: Emit word 0 in table.
11457 * 01: Emit word 1 in table.
11458 * .
11459 * FD: Emit word 253 in table.
11460 *
11461 * Multi-Byte Code:
11462 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
11463 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
11464 *
11465 * Returns 0 or an error if the checksum doesn't match
11466 */
11467static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
11468 int memsize, int chksum)
11469{
11470 int i, j, end, len = 0;
11471 ADV_DCNT sum;
11472
11473 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
11474
11475 for (i = 253 * 2; i < size; i++) {
11476 if (buf[i] == 0xff) {
11477 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
11478 for (j = 0; j < buf[i + 1]; j++) {
11479 AdvWriteWordAutoIncLram(iop_base, word);
11480 len += 2;
11481 }
11482 i += 3;
11483 } else if (buf[i] == 0xfe) {
11484 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
11485 AdvWriteWordAutoIncLram(iop_base, word);
11486 i += 2;
11487 len += 2;
11488 } else {
11489 unsigned char off = buf[i] * 2;
11490 unsigned short word = (buf[off + 1] << 8) | buf[off];
11491 AdvWriteWordAutoIncLram(iop_base, word);
11492 len += 2;
11493 }
11494 }
11495
11496 end = len;
11497
11498 while (len < memsize) {
11499 AdvWriteWordAutoIncLram(iop_base, 0);
11500 len += 2;
11501 }
11502
11503 /* Verify the microcode checksum. */
11504 sum = 0;
11505 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
11506
11507 for (len = 0; len < end; len += 2) {
11508 sum += AdvReadWordAutoIncLram(iop_base);
11509 }
11510
11511 if (sum != chksum)
11512 return ASC_IERR_MCODE_CHKSUM;
11513
11514 return 0;
11515}
11516
1da177e4
LT
11517/*
11518 * Initialize the ASC-3550.
11519 *
11520 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11521 *
11522 * For a non-fatal error return a warning code. If there are no warnings
11523 * then 0 is returned.
11524 *
11525 * Needed after initialization for error recovery.
11526 */
27c868c2 11527static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 11528{
27c868c2
MW
11529 AdvPortAddr iop_base;
11530 ushort warn_code;
27c868c2
MW
11531 int begin_addr;
11532 int end_addr;
11533 ushort code_sum;
11534 int word;
27c868c2
MW
11535 int i;
11536 ushort scsi_cfg1;
11537 uchar tid;
11538 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
11539 ushort wdtr_able = 0, sdtr_able, tagqng_able;
11540 uchar max_cmd[ADV_MAX_TID + 1];
11541
11542 /* If there is already an error, don't continue. */
b9d96614 11543 if (asc_dvc->err_code != 0)
27c868c2 11544 return ADV_ERROR;
1da177e4 11545
27c868c2
MW
11546 /*
11547 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
11548 */
11549 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
b9d96614 11550 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
27c868c2
MW
11551 return ADV_ERROR;
11552 }
1da177e4 11553
27c868c2
MW
11554 warn_code = 0;
11555 iop_base = asc_dvc->iop_base;
11556
11557 /*
11558 * Save the RISC memory BIOS region before writing the microcode.
11559 * The BIOS may already be loaded and using its RISC LRAM region
11560 * so its region must be saved and restored.
11561 *
11562 * Note: This code makes the assumption, which is currently true,
11563 * that a chip reset does not clear RISC LRAM.
11564 */
11565 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11566 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11567 bios_mem[i]);
11568 }
1da177e4 11569
27c868c2
MW
11570 /*
11571 * Save current per TID negotiated values.
11572 */
11573 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
11574 ushort bios_version, major, minor;
11575
11576 bios_version =
11577 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
11578 major = (bios_version >> 12) & 0xF;
11579 minor = (bios_version >> 8) & 0xF;
11580 if (major < 3 || (major == 3 && minor == 1)) {
11581 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
11582 AdvReadWordLram(iop_base, 0x120, wdtr_able);
11583 } else {
11584 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11585 }
11586 }
11587 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11588 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
11589 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11590 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
11591 max_cmd[tid]);
11592 }
1da177e4 11593
b9d96614
MW
11594 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
11595 _adv_asc3550_size, ADV_3550_MEMSIZE,
11596 _adv_asc3550_chksum);
11597 if (asc_dvc->err_code)
27c868c2 11598 return ADV_ERROR;
1da177e4 11599
27c868c2
MW
11600 /*
11601 * Restore the RISC memory BIOS region.
11602 */
11603 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11604 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11605 bios_mem[i]);
11606 }
1da177e4 11607
27c868c2
MW
11608 /*
11609 * Calculate and write the microcode code checksum to the microcode
11610 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
11611 */
11612 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
11613 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
11614 code_sum = 0;
11615 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
11616 for (word = begin_addr; word < end_addr; word += 2) {
11617 code_sum += AdvReadWordAutoIncLram(iop_base);
11618 }
11619 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
11620
11621 /*
11622 * Read and save microcode version and date.
11623 */
11624 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
11625 asc_dvc->cfg->mcode_date);
11626 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
11627 asc_dvc->cfg->mcode_version);
11628
11629 /*
11630 * Set the chip type to indicate the ASC3550.
11631 */
11632 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
11633
11634 /*
11635 * If the PCI Configuration Command Register "Parity Error Response
11636 * Control" Bit was clear (0), then set the microcode variable
11637 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
11638 * to ignore DMA parity errors.
11639 */
11640 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
11641 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11642 word |= CONTROL_FLAG_IGNORE_PERR;
11643 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11644 }
1da177e4 11645
27c868c2
MW
11646 /*
11647 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
11648 * threshold of 128 bytes. This register is only accessible to the host.
11649 */
11650 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
11651 START_CTL_EMFU | READ_CMD_MRM);
11652
11653 /*
11654 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 11655 * queuing will be set in slave_configure() based on what a
27c868c2
MW
11656 * device reports it is capable of in Inquiry byte 7.
11657 *
11658 * If SCSI Bus Resets have been disabled, then directly set
11659 * SDTR and WDTR from the EEPROM configuration. This will allow
11660 * the BIOS and warm boot to work without a SCSI bus hang on
11661 * the Inquiry caused by host and target mismatched DTR values.
11662 * Without the SCSI Bus Reset, before an Inquiry a device can't
11663 * be assumed to be in Asynchronous, Narrow mode.
11664 */
11665 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
11666 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
11667 asc_dvc->wdtr_able);
11668 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
11669 asc_dvc->sdtr_able);
11670 }
1da177e4 11671
27c868c2
MW
11672 /*
11673 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
11674 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
11675 * bitmask. These values determine the maximum SDTR speed negotiated
11676 * with a device.
11677 *
11678 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
11679 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
11680 * without determining here whether the device supports SDTR.
11681 *
11682 * 4-bit speed SDTR speed name
11683 * =========== ===============
11684 * 0000b (0x0) SDTR disabled
11685 * 0001b (0x1) 5 Mhz
11686 * 0010b (0x2) 10 Mhz
11687 * 0011b (0x3) 20 Mhz (Ultra)
11688 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
11689 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
11690 * 0110b (0x6) Undefined
11691 * .
11692 * 1111b (0xF) Undefined
11693 */
11694 word = 0;
11695 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11696 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
11697 /* Set Ultra speed for TID 'tid'. */
11698 word |= (0x3 << (4 * (tid % 4)));
11699 } else {
11700 /* Set Fast speed for TID 'tid'. */
11701 word |= (0x2 << (4 * (tid % 4)));
11702 }
11703 if (tid == 3) { /* Check if done with sdtr_speed1. */
11704 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
11705 word = 0;
11706 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
11707 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
11708 word = 0;
11709 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
11710 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
11711 word = 0;
11712 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
11713 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
11714 /* End of loop. */
11715 }
11716 }
1da177e4 11717
27c868c2
MW
11718 /*
11719 * Set microcode operating variable for the disconnect per TID bitmask.
11720 */
11721 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
11722 asc_dvc->cfg->disc_enable);
11723
11724 /*
11725 * Set SCSI_CFG0 Microcode Default Value.
11726 *
11727 * The microcode will set the SCSI_CFG0 register using this value
11728 * after it is started below.
11729 */
11730 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
11731 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
11732 asc_dvc->chip_scsi_id);
11733
11734 /*
11735 * Determine SCSI_CFG1 Microcode Default Value.
11736 *
11737 * The microcode will set the SCSI_CFG1 register using this value
11738 * after it is started below.
11739 */
11740
11741 /* Read current SCSI_CFG1 Register value. */
11742 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
11743
11744 /*
11745 * If all three connectors are in use, return an error.
11746 */
11747 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
11748 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
11749 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
11750 return ADV_ERROR;
11751 }
1da177e4 11752
27c868c2
MW
11753 /*
11754 * If the internal narrow cable is reversed all of the SCSI_CTRL
11755 * register signals will be set. Check for and return an error if
11756 * this condition is found.
11757 */
11758 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
11759 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
11760 return ADV_ERROR;
11761 }
1da177e4 11762
27c868c2
MW
11763 /*
11764 * If this is a differential board and a single-ended device
11765 * is attached to one of the connectors, return an error.
11766 */
11767 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
11768 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
11769 return ADV_ERROR;
11770 }
1da177e4 11771
27c868c2
MW
11772 /*
11773 * If automatic termination control is enabled, then set the
11774 * termination value based on a table listed in a_condor.h.
11775 *
11776 * If manual termination was specified with an EEPROM setting
11777 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
11778 * is ready to be 'ored' into SCSI_CFG1.
11779 */
11780 if (asc_dvc->cfg->termination == 0) {
11781 /*
11782 * The software always controls termination by setting TERM_CTL_SEL.
11783 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
11784 */
11785 asc_dvc->cfg->termination |= TERM_CTL_SEL;
11786
11787 switch (scsi_cfg1 & CABLE_DETECT) {
11788 /* TERM_CTL_H: on, TERM_CTL_L: on */
11789 case 0x3:
11790 case 0x7:
11791 case 0xB:
11792 case 0xD:
11793 case 0xE:
11794 case 0xF:
11795 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
11796 break;
11797
11798 /* TERM_CTL_H: on, TERM_CTL_L: off */
11799 case 0x1:
11800 case 0x5:
11801 case 0x9:
11802 case 0xA:
11803 case 0xC:
11804 asc_dvc->cfg->termination |= TERM_CTL_H;
11805 break;
11806
11807 /* TERM_CTL_H: off, TERM_CTL_L: off */
11808 case 0x2:
11809 case 0x6:
11810 break;
11811 }
11812 }
1da177e4 11813
27c868c2
MW
11814 /*
11815 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
11816 */
11817 scsi_cfg1 &= ~TERM_CTL;
11818
11819 /*
11820 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
11821 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
11822 * referenced, because the hardware internally inverts
11823 * the Termination High and Low bits if TERM_POL is set.
11824 */
11825 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
11826
11827 /*
11828 * Set SCSI_CFG1 Microcode Default Value
11829 *
11830 * Set filter value and possibly modified termination control
11831 * bits in the Microcode SCSI_CFG1 Register Value.
11832 *
11833 * The microcode will set the SCSI_CFG1 register using this value
11834 * after it is started below.
11835 */
11836 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
11837 FLTR_DISABLE | scsi_cfg1);
11838
11839 /*
11840 * Set MEM_CFG Microcode Default Value
11841 *
11842 * The microcode will set the MEM_CFG register using this value
11843 * after it is started below.
11844 *
11845 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
11846 * are defined.
11847 *
11848 * ASC-3550 has 8KB internal memory.
11849 */
11850 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
11851 BIOS_EN | RAM_SZ_8KB);
11852
11853 /*
11854 * Set SEL_MASK Microcode Default Value
11855 *
11856 * The microcode will set the SEL_MASK register using this value
11857 * after it is started below.
11858 */
11859 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
11860 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
11861
a9f4a59a 11862 AdvBuildCarrierFreelist(asc_dvc);
1da177e4 11863
27c868c2
MW
11864 /*
11865 * Set-up the Host->RISC Initiator Command Queue (ICQ).
11866 */
1da177e4 11867
27c868c2
MW
11868 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
11869 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
11870 return ADV_ERROR;
11871 }
11872 asc_dvc->carr_freelist = (ADV_CARR_T *)
11873 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
11874
11875 /*
11876 * The first command issued will be placed in the stopper carrier.
11877 */
11878 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11879
11880 /*
11881 * Set RISC ICQ physical address start value.
11882 */
11883 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
11884
11885 /*
11886 * Set-up the RISC->Host Initiator Response Queue (IRQ).
11887 */
11888 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
11889 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
11890 return ADV_ERROR;
11891 }
11892 asc_dvc->carr_freelist = (ADV_CARR_T *)
11893 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
11894
11895 /*
11896 * The first command completed by the RISC will be placed in
11897 * the stopper.
11898 *
11899 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
11900 * completed the RISC will set the ASC_RQ_STOPPER bit.
11901 */
11902 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11903
11904 /*
11905 * Set RISC IRQ physical address start value.
11906 */
11907 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
11908 asc_dvc->carr_pending_cnt = 0;
11909
11910 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
11911 (ADV_INTR_ENABLE_HOST_INTR |
11912 ADV_INTR_ENABLE_GLOBAL_INTR));
11913
11914 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
11915 AdvWriteWordRegister(iop_base, IOPW_PC, word);
11916
11917 /* finally, finally, gentlemen, start your engine */
11918 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
11919
11920 /*
11921 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
11922 * Resets should be performed. The RISC has to be running
11923 * to issue a SCSI Bus Reset.
11924 */
11925 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
11926 /*
11927 * If the BIOS Signature is present in memory, restore the
11928 * BIOS Handshake Configuration Table and do not perform
11929 * a SCSI Bus Reset.
11930 */
11931 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
11932 0x55AA) {
11933 /*
11934 * Restore per TID negotiated values.
11935 */
11936 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11937 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11938 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
11939 tagqng_able);
11940 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11941 AdvWriteByteLram(iop_base,
11942 ASC_MC_NUMBER_OF_MAX_CMD + tid,
11943 max_cmd[tid]);
11944 }
11945 } else {
11946 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
11947 warn_code = ASC_WARN_BUSRESET_ERROR;
11948 }
11949 }
11950 }
1da177e4 11951
27c868c2
MW
11952 return warn_code;
11953}
1da177e4 11954
27c868c2
MW
11955/*
11956 * Initialize the ASC-38C0800.
11957 *
11958 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11959 *
11960 * For a non-fatal error return a warning code. If there are no warnings
11961 * then 0 is returned.
11962 *
11963 * Needed after initialization for error recovery.
11964 */
11965static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
11966{
11967 AdvPortAddr iop_base;
11968 ushort warn_code;
27c868c2
MW
11969 int begin_addr;
11970 int end_addr;
11971 ushort code_sum;
11972 int word;
27c868c2
MW
11973 int i;
11974 ushort scsi_cfg1;
11975 uchar byte;
11976 uchar tid;
11977 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
11978 ushort wdtr_able, sdtr_able, tagqng_able;
11979 uchar max_cmd[ADV_MAX_TID + 1];
11980
11981 /* If there is already an error, don't continue. */
b9d96614 11982 if (asc_dvc->err_code != 0)
27c868c2 11983 return ADV_ERROR;
1da177e4 11984
27c868c2
MW
11985 /*
11986 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
11987 */
11988 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
11989 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
11990 return ADV_ERROR;
11991 }
1da177e4 11992
27c868c2
MW
11993 warn_code = 0;
11994 iop_base = asc_dvc->iop_base;
11995
11996 /*
11997 * Save the RISC memory BIOS region before writing the microcode.
11998 * The BIOS may already be loaded and using its RISC LRAM region
11999 * so its region must be saved and restored.
12000 *
12001 * Note: This code makes the assumption, which is currently true,
12002 * that a chip reset does not clear RISC LRAM.
12003 */
12004 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12005 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12006 bios_mem[i]);
12007 }
1da177e4 12008
27c868c2
MW
12009 /*
12010 * Save current per TID negotiated values.
12011 */
12012 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12013 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12014 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
12015 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12016 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
12017 max_cmd[tid]);
12018 }
1da177e4 12019
27c868c2
MW
12020 /*
12021 * RAM BIST (RAM Built-In Self Test)
12022 *
12023 * Address : I/O base + offset 0x38h register (byte).
12024 * Function: Bit 7-6(RW) : RAM mode
12025 * Normal Mode : 0x00
12026 * Pre-test Mode : 0x40
12027 * RAM Test Mode : 0x80
12028 * Bit 5 : unused
12029 * Bit 4(RO) : Done bit
12030 * Bit 3-0(RO) : Status
12031 * Host Error : 0x08
12032 * Int_RAM Error : 0x04
12033 * RISC Error : 0x02
12034 * SCSI Error : 0x01
12035 * No Error : 0x00
12036 *
12037 * Note: RAM BIST code should be put right here, before loading the
12038 * microcode and after saving the RISC memory BIOS region.
12039 */
12040
12041 /*
12042 * LRAM Pre-test
12043 *
12044 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
12045 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
12046 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
12047 * to NORMAL_MODE, return an error too.
12048 */
12049 for (i = 0; i < 2; i++) {
12050 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
12051 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
12052 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12053 if ((byte & RAM_TEST_DONE) == 0
12054 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 12055 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12056 return ADV_ERROR;
12057 }
12058
12059 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12060 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
12061 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
12062 != NORMAL_VALUE) {
b9d96614 12063 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12064 return ADV_ERROR;
12065 }
12066 }
1da177e4 12067
27c868c2
MW
12068 /*
12069 * LRAM Test - It takes about 1.5 ms to run through the test.
12070 *
12071 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
12072 * If Done bit not set or Status not 0, save register byte, set the
12073 * err_code, and return an error.
12074 */
12075 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
12076 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
12077
12078 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12079 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
12080 /* Get here if Done bit not set or Status not 0. */
12081 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 12082 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
12083 return ADV_ERROR;
12084 }
1da177e4 12085
27c868c2
MW
12086 /* We need to reset back to normal mode after LRAM test passes. */
12087 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12088
b9d96614
MW
12089 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
12090 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
12091 _adv_asc38C0800_chksum);
12092 if (asc_dvc->err_code)
27c868c2 12093 return ADV_ERROR;
1da177e4 12094
27c868c2
MW
12095 /*
12096 * Restore the RISC memory BIOS region.
12097 */
12098 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12099 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12100 bios_mem[i]);
12101 }
1da177e4 12102
27c868c2
MW
12103 /*
12104 * Calculate and write the microcode code checksum to the microcode
12105 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
12106 */
12107 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
12108 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
12109 code_sum = 0;
12110 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
12111 for (word = begin_addr; word < end_addr; word += 2) {
12112 code_sum += AdvReadWordAutoIncLram(iop_base);
12113 }
12114 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
12115
12116 /*
12117 * Read microcode version and date.
12118 */
12119 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
12120 asc_dvc->cfg->mcode_date);
12121 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
12122 asc_dvc->cfg->mcode_version);
12123
12124 /*
12125 * Set the chip type to indicate the ASC38C0800.
12126 */
12127 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
12128
12129 /*
12130 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
12131 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
12132 * cable detection and then we are able to read C_DET[3:0].
12133 *
12134 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
12135 * Microcode Default Value' section below.
12136 */
12137 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12138 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
12139 scsi_cfg1 | DIS_TERM_DRV);
12140
12141 /*
12142 * If the PCI Configuration Command Register "Parity Error Response
12143 * Control" Bit was clear (0), then set the microcode variable
12144 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
12145 * to ignore DMA parity errors.
12146 */
12147 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
12148 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12149 word |= CONTROL_FLAG_IGNORE_PERR;
12150 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12151 }
1da177e4 12152
27c868c2
MW
12153 /*
12154 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
12155 * bits for the default FIFO threshold.
12156 *
12157 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
12158 *
12159 * For DMA Errata #4 set the BC_THRESH_ENB bit.
12160 */
12161 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
12162 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
12163 READ_CMD_MRM);
12164
12165 /*
12166 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 12167 * queuing will be set in slave_configure() based on what a
27c868c2
MW
12168 * device reports it is capable of in Inquiry byte 7.
12169 *
12170 * If SCSI Bus Resets have been disabled, then directly set
12171 * SDTR and WDTR from the EEPROM configuration. This will allow
12172 * the BIOS and warm boot to work without a SCSI bus hang on
12173 * the Inquiry caused by host and target mismatched DTR values.
12174 * Without the SCSI Bus Reset, before an Inquiry a device can't
12175 * be assumed to be in Asynchronous, Narrow mode.
12176 */
12177 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
12178 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
12179 asc_dvc->wdtr_able);
12180 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
12181 asc_dvc->sdtr_able);
12182 }
1da177e4 12183
27c868c2
MW
12184 /*
12185 * Set microcode operating variables for DISC and SDTR_SPEED1,
12186 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
12187 * configuration values.
12188 *
12189 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
12190 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
12191 * without determining here whether the device supports SDTR.
12192 */
12193 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
12194 asc_dvc->cfg->disc_enable);
12195 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
12196 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
12197 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
12198 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
12199
12200 /*
12201 * Set SCSI_CFG0 Microcode Default Value.
12202 *
12203 * The microcode will set the SCSI_CFG0 register using this value
12204 * after it is started below.
12205 */
12206 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
12207 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
12208 asc_dvc->chip_scsi_id);
12209
12210 /*
12211 * Determine SCSI_CFG1 Microcode Default Value.
12212 *
12213 * The microcode will set the SCSI_CFG1 register using this value
12214 * after it is started below.
12215 */
12216
12217 /* Read current SCSI_CFG1 Register value. */
12218 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12219
12220 /*
12221 * If the internal narrow cable is reversed all of the SCSI_CTRL
12222 * register signals will be set. Check for and return an error if
12223 * this condition is found.
12224 */
12225 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
12226 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
12227 return ADV_ERROR;
12228 }
1da177e4 12229
27c868c2 12230 /*
b9d96614
MW
12231 * All kind of combinations of devices attached to one of four
12232 * connectors are acceptable except HVD device attached. For example,
12233 * LVD device can be attached to SE connector while SE device attached
12234 * to LVD connector. If LVD device attached to SE connector, it only
12235 * runs up to Ultra speed.
27c868c2 12236 *
b9d96614
MW
12237 * If an HVD device is attached to one of LVD connectors, return an
12238 * error. However, there is no way to detect HVD device attached to
12239 * SE connectors.
27c868c2
MW
12240 */
12241 if (scsi_cfg1 & HVD) {
b9d96614 12242 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
27c868c2
MW
12243 return ADV_ERROR;
12244 }
1da177e4 12245
27c868c2
MW
12246 /*
12247 * If either SE or LVD automatic termination control is enabled, then
12248 * set the termination value based on a table listed in a_condor.h.
12249 *
12250 * If manual termination was specified with an EEPROM setting then
b9d96614
MW
12251 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
12252 * to be 'ored' into SCSI_CFG1.
27c868c2
MW
12253 */
12254 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
12255 /* SE automatic termination control is enabled. */
12256 switch (scsi_cfg1 & C_DET_SE) {
12257 /* TERM_SE_HI: on, TERM_SE_LO: on */
12258 case 0x1:
12259 case 0x2:
12260 case 0x3:
12261 asc_dvc->cfg->termination |= TERM_SE;
12262 break;
12263
12264 /* TERM_SE_HI: on, TERM_SE_LO: off */
12265 case 0x0:
12266 asc_dvc->cfg->termination |= TERM_SE_HI;
12267 break;
12268 }
12269 }
12270
12271 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
12272 /* LVD automatic termination control is enabled. */
12273 switch (scsi_cfg1 & C_DET_LVD) {
12274 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
12275 case 0x4:
12276 case 0x8:
12277 case 0xC:
12278 asc_dvc->cfg->termination |= TERM_LVD;
12279 break;
12280
12281 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
12282 case 0x0:
12283 break;
12284 }
12285 }
12286
12287 /*
12288 * Clear any set TERM_SE and TERM_LVD bits.
12289 */
12290 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
12291
12292 /*
12293 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
12294 */
12295 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
12296
12297 /*
b9d96614
MW
12298 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
12299 * bits and set possibly modified termination control bits in the
12300 * Microcode SCSI_CFG1 Register Value.
27c868c2
MW
12301 */
12302 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
12303
12304 /*
12305 * Set SCSI_CFG1 Microcode Default Value
12306 *
12307 * Set possibly modified termination control and reset DIS_TERM_DRV
12308 * bits in the Microcode SCSI_CFG1 Register Value.
12309 *
12310 * The microcode will set the SCSI_CFG1 register using this value
12311 * after it is started below.
12312 */
12313 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
12314
12315 /*
12316 * Set MEM_CFG Microcode Default Value
12317 *
12318 * The microcode will set the MEM_CFG register using this value
12319 * after it is started below.
12320 *
12321 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12322 * are defined.
12323 *
12324 * ASC-38C0800 has 16KB internal memory.
12325 */
12326 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12327 BIOS_EN | RAM_SZ_16KB);
12328
12329 /*
12330 * Set SEL_MASK Microcode Default Value
12331 *
12332 * The microcode will set the SEL_MASK register using this value
12333 * after it is started below.
12334 */
12335 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12336 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12337
a9f4a59a 12338 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
12339
12340 /*
12341 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12342 */
12343
12344 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12345 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12346 return ADV_ERROR;
12347 }
12348 asc_dvc->carr_freelist = (ADV_CARR_T *)
12349 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12350
12351 /*
12352 * The first command issued will be placed in the stopper carrier.
12353 */
12354 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12355
12356 /*
12357 * Set RISC ICQ physical address start value.
12358 * carr_pa is LE, must be native before write
12359 */
12360 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12361
12362 /*
12363 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12364 */
12365 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12366 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12367 return ADV_ERROR;
12368 }
12369 asc_dvc->carr_freelist = (ADV_CARR_T *)
12370 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12371
12372 /*
12373 * The first command completed by the RISC will be placed in
12374 * the stopper.
12375 *
12376 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12377 * completed the RISC will set the ASC_RQ_STOPPER bit.
12378 */
12379 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12380
12381 /*
12382 * Set RISC IRQ physical address start value.
12383 *
12384 * carr_pa is LE, must be native before write *
12385 */
12386 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12387 asc_dvc->carr_pending_cnt = 0;
12388
12389 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12390 (ADV_INTR_ENABLE_HOST_INTR |
12391 ADV_INTR_ENABLE_GLOBAL_INTR));
12392
12393 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12394 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12395
12396 /* finally, finally, gentlemen, start your engine */
12397 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12398
12399 /*
12400 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12401 * Resets should be performed. The RISC has to be running
12402 * to issue a SCSI Bus Reset.
12403 */
12404 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
12405 /*
12406 * If the BIOS Signature is present in memory, restore the
12407 * BIOS Handshake Configuration Table and do not perform
12408 * a SCSI Bus Reset.
12409 */
12410 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
12411 0x55AA) {
12412 /*
12413 * Restore per TID negotiated values.
12414 */
12415 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12416 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12417 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
12418 tagqng_able);
12419 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12420 AdvWriteByteLram(iop_base,
12421 ASC_MC_NUMBER_OF_MAX_CMD + tid,
12422 max_cmd[tid]);
12423 }
12424 } else {
12425 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
12426 warn_code = ASC_WARN_BUSRESET_ERROR;
12427 }
12428 }
12429 }
12430
12431 return warn_code;
1da177e4
LT
12432}
12433
12434/*
27c868c2 12435 * Initialize the ASC-38C1600.
1da177e4 12436 *
27c868c2 12437 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
12438 *
12439 * For a non-fatal error return a warning code. If there are no warnings
12440 * then 0 is returned.
12441 *
12442 * Needed after initialization for error recovery.
12443 */
27c868c2 12444static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 12445{
27c868c2
MW
12446 AdvPortAddr iop_base;
12447 ushort warn_code;
27c868c2
MW
12448 int begin_addr;
12449 int end_addr;
12450 ushort code_sum;
12451 long word;
27c868c2
MW
12452 int i;
12453 ushort scsi_cfg1;
12454 uchar byte;
12455 uchar tid;
12456 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
12457 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
12458 uchar max_cmd[ASC_MAX_TID + 1];
12459
12460 /* If there is already an error, don't continue. */
12461 if (asc_dvc->err_code != 0) {
12462 return ADV_ERROR;
12463 }
1da177e4 12464
27c868c2
MW
12465 /*
12466 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
12467 */
12468 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
12469 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
12470 return ADV_ERROR;
12471 }
1da177e4 12472
27c868c2
MW
12473 warn_code = 0;
12474 iop_base = asc_dvc->iop_base;
12475
12476 /*
12477 * Save the RISC memory BIOS region before writing the microcode.
12478 * The BIOS may already be loaded and using its RISC LRAM region
12479 * so its region must be saved and restored.
12480 *
12481 * Note: This code makes the assumption, which is currently true,
12482 * that a chip reset does not clear RISC LRAM.
12483 */
12484 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12485 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12486 bios_mem[i]);
12487 }
1da177e4 12488
27c868c2
MW
12489 /*
12490 * Save current per TID negotiated values.
12491 */
12492 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12493 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12494 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
12495 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
12496 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
12497 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
12498 max_cmd[tid]);
12499 }
1da177e4 12500
27c868c2
MW
12501 /*
12502 * RAM BIST (Built-In Self Test)
12503 *
12504 * Address : I/O base + offset 0x38h register (byte).
12505 * Function: Bit 7-6(RW) : RAM mode
12506 * Normal Mode : 0x00
12507 * Pre-test Mode : 0x40
12508 * RAM Test Mode : 0x80
12509 * Bit 5 : unused
12510 * Bit 4(RO) : Done bit
12511 * Bit 3-0(RO) : Status
12512 * Host Error : 0x08
12513 * Int_RAM Error : 0x04
12514 * RISC Error : 0x02
12515 * SCSI Error : 0x01
12516 * No Error : 0x00
12517 *
12518 * Note: RAM BIST code should be put right here, before loading the
12519 * microcode and after saving the RISC memory BIOS region.
12520 */
12521
12522 /*
12523 * LRAM Pre-test
12524 *
12525 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
12526 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
12527 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
12528 * to NORMAL_MODE, return an error too.
12529 */
12530 for (i = 0; i < 2; i++) {
12531 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
12532 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
12533 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12534 if ((byte & RAM_TEST_DONE) == 0
12535 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 12536 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12537 return ADV_ERROR;
12538 }
12539
12540 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12541 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
12542 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
12543 != NORMAL_VALUE) {
b9d96614 12544 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12545 return ADV_ERROR;
12546 }
12547 }
1da177e4 12548
27c868c2
MW
12549 /*
12550 * LRAM Test - It takes about 1.5 ms to run through the test.
12551 *
12552 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
12553 * If Done bit not set or Status not 0, save register byte, set the
12554 * err_code, and return an error.
12555 */
12556 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
12557 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
12558
12559 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12560 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
12561 /* Get here if Done bit not set or Status not 0. */
12562 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 12563 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
12564 return ADV_ERROR;
12565 }
1da177e4 12566
27c868c2
MW
12567 /* We need to reset back to normal mode after LRAM test passes. */
12568 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12569
b9d96614
MW
12570 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
12571 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
12572 _adv_asc38C1600_chksum);
12573 if (asc_dvc->err_code)
27c868c2 12574 return ADV_ERROR;
1da177e4 12575
27c868c2
MW
12576 /*
12577 * Restore the RISC memory BIOS region.
12578 */
12579 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12580 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12581 bios_mem[i]);
12582 }
1da177e4 12583
27c868c2
MW
12584 /*
12585 * Calculate and write the microcode code checksum to the microcode
12586 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
12587 */
12588 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
12589 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
12590 code_sum = 0;
12591 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
12592 for (word = begin_addr; word < end_addr; word += 2) {
12593 code_sum += AdvReadWordAutoIncLram(iop_base);
12594 }
12595 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
12596
12597 /*
12598 * Read microcode version and date.
12599 */
12600 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
12601 asc_dvc->cfg->mcode_date);
12602 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
12603 asc_dvc->cfg->mcode_version);
12604
12605 /*
12606 * Set the chip type to indicate the ASC38C1600.
12607 */
12608 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
12609
12610 /*
12611 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
12612 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
12613 * cable detection and then we are able to read C_DET[3:0].
12614 *
12615 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
12616 * Microcode Default Value' section below.
12617 */
12618 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12619 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
12620 scsi_cfg1 | DIS_TERM_DRV);
12621
12622 /*
12623 * If the PCI Configuration Command Register "Parity Error Response
12624 * Control" Bit was clear (0), then set the microcode variable
12625 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
12626 * to ignore DMA parity errors.
12627 */
12628 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
12629 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12630 word |= CONTROL_FLAG_IGNORE_PERR;
12631 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12632 }
1da177e4 12633
27c868c2
MW
12634 /*
12635 * If the BIOS control flag AIPP (Asynchronous Information
12636 * Phase Protection) disable bit is not set, then set the firmware
12637 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
12638 * AIPP checking and encoding.
12639 */
12640 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
12641 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12642 word |= CONTROL_FLAG_ENABLE_AIPP;
12643 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12644 }
1da177e4 12645
27c868c2
MW
12646 /*
12647 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
12648 * and START_CTL_TH [3:2].
12649 */
12650 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
12651 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
12652
12653 /*
12654 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 12655 * queuing will be set in slave_configure() based on what a
27c868c2
MW
12656 * device reports it is capable of in Inquiry byte 7.
12657 *
12658 * If SCSI Bus Resets have been disabled, then directly set
12659 * SDTR and WDTR from the EEPROM configuration. This will allow
12660 * the BIOS and warm boot to work without a SCSI bus hang on
12661 * the Inquiry caused by host and target mismatched DTR values.
12662 * Without the SCSI Bus Reset, before an Inquiry a device can't
12663 * be assumed to be in Asynchronous, Narrow mode.
12664 */
12665 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
12666 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
12667 asc_dvc->wdtr_able);
12668 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
12669 asc_dvc->sdtr_able);
12670 }
1da177e4 12671
27c868c2
MW
12672 /*
12673 * Set microcode operating variables for DISC and SDTR_SPEED1,
12674 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
12675 * configuration values.
12676 *
12677 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
12678 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
12679 * without determining here whether the device supports SDTR.
12680 */
12681 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
12682 asc_dvc->cfg->disc_enable);
12683 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
12684 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
12685 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
12686 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
12687
12688 /*
12689 * Set SCSI_CFG0 Microcode Default Value.
12690 *
12691 * The microcode will set the SCSI_CFG0 register using this value
12692 * after it is started below.
12693 */
12694 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
12695 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
12696 asc_dvc->chip_scsi_id);
12697
12698 /*
12699 * Calculate SCSI_CFG1 Microcode Default Value.
12700 *
12701 * The microcode will set the SCSI_CFG1 register using this value
12702 * after it is started below.
12703 *
12704 * Each ASC-38C1600 function has only two cable detect bits.
12705 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
12706 */
12707 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12708
12709 /*
12710 * If the cable is reversed all of the SCSI_CTRL register signals
12711 * will be set. Check for and return an error if this condition is
12712 * found.
12713 */
12714 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
12715 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
12716 return ADV_ERROR;
12717 }
1da177e4 12718
27c868c2
MW
12719 /*
12720 * Each ASC-38C1600 function has two connectors. Only an HVD device
12721 * can not be connected to either connector. An LVD device or SE device
12722 * may be connected to either connecor. If an SE device is connected,
12723 * then at most Ultra speed (20 Mhz) can be used on both connectors.
12724 *
12725 * If an HVD device is attached, return an error.
12726 */
12727 if (scsi_cfg1 & HVD) {
12728 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
12729 return ADV_ERROR;
12730 }
1da177e4 12731
27c868c2
MW
12732 /*
12733 * Each function in the ASC-38C1600 uses only the SE cable detect and
12734 * termination because there are two connectors for each function. Each
12735 * function may use either LVD or SE mode. Corresponding the SE automatic
12736 * termination control EEPROM bits are used for each function. Each
12737 * function has its own EEPROM. If SE automatic control is enabled for
12738 * the function, then set the termination value based on a table listed
12739 * in a_condor.h.
12740 *
12741 * If manual termination is specified in the EEPROM for the function,
12742 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
12743 * ready to be 'ored' into SCSI_CFG1.
12744 */
12745 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
13ac2d9c 12746 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2
MW
12747 /* SE automatic termination control is enabled. */
12748 switch (scsi_cfg1 & C_DET_SE) {
12749 /* TERM_SE_HI: on, TERM_SE_LO: on */
12750 case 0x1:
12751 case 0x2:
12752 case 0x3:
12753 asc_dvc->cfg->termination |= TERM_SE;
12754 break;
12755
12756 case 0x0:
13ac2d9c 12757 if (PCI_FUNC(pdev->devfn) == 0) {
27c868c2
MW
12758 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
12759 } else {
12760 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
12761 asc_dvc->cfg->termination |= TERM_SE_HI;
12762 }
12763 break;
12764 }
12765 }
1da177e4 12766
27c868c2
MW
12767 /*
12768 * Clear any set TERM_SE bits.
12769 */
12770 scsi_cfg1 &= ~TERM_SE;
12771
12772 /*
12773 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
12774 */
12775 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
12776
12777 /*
12778 * Clear Big Endian and Terminator Polarity bits and set possibly
12779 * modified termination control bits in the Microcode SCSI_CFG1
12780 * Register Value.
12781 *
12782 * Big Endian bit is not used even on big endian machines.
12783 */
12784 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
12785
12786 /*
12787 * Set SCSI_CFG1 Microcode Default Value
12788 *
12789 * Set possibly modified termination control bits in the Microcode
12790 * SCSI_CFG1 Register Value.
12791 *
12792 * The microcode will set the SCSI_CFG1 register using this value
12793 * after it is started below.
12794 */
12795 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
12796
12797 /*
12798 * Set MEM_CFG Microcode Default Value
12799 *
12800 * The microcode will set the MEM_CFG register using this value
12801 * after it is started below.
12802 *
12803 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12804 * are defined.
12805 *
12806 * ASC-38C1600 has 32KB internal memory.
12807 *
12808 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
12809 * out a special 16K Adv Library and Microcode version. After the issue
12810 * resolved, we should turn back to the 32K support. Both a_condor.h and
12811 * mcode.sas files also need to be updated.
12812 *
12813 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12814 * BIOS_EN | RAM_SZ_32KB);
12815 */
12816 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12817 BIOS_EN | RAM_SZ_16KB);
12818
12819 /*
12820 * Set SEL_MASK Microcode Default Value
12821 *
12822 * The microcode will set the SEL_MASK register using this value
12823 * after it is started below.
12824 */
12825 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12826 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12827
a9f4a59a 12828 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
12829
12830 /*
12831 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12832 */
12833 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12834 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12835 return ADV_ERROR;
12836 }
12837 asc_dvc->carr_freelist = (ADV_CARR_T *)
12838 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12839
12840 /*
12841 * The first command issued will be placed in the stopper carrier.
12842 */
12843 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12844
12845 /*
12846 * Set RISC ICQ physical address start value. Initialize the
12847 * COMMA register to the same value otherwise the RISC will
12848 * prematurely detect a command is available.
12849 */
12850 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12851 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
12852 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
12853
12854 /*
12855 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12856 */
12857 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12858 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12859 return ADV_ERROR;
12860 }
12861 asc_dvc->carr_freelist = (ADV_CARR_T *)
12862 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12863
12864 /*
12865 * The first command completed by the RISC will be placed in
12866 * the stopper.
12867 *
12868 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12869 * completed the RISC will set the ASC_RQ_STOPPER bit.
12870 */
12871 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12872
12873 /*
12874 * Set RISC IRQ physical address start value.
12875 */
12876 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12877 asc_dvc->carr_pending_cnt = 0;
12878
12879 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12880 (ADV_INTR_ENABLE_HOST_INTR |
12881 ADV_INTR_ENABLE_GLOBAL_INTR));
12882 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12883 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12884
12885 /* finally, finally, gentlemen, start your engine */
12886 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12887
12888 /*
12889 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12890 * Resets should be performed. The RISC has to be running
12891 * to issue a SCSI Bus Reset.
12892 */
12893 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
12894 /*
12895 * If the BIOS Signature is present in memory, restore the
12896 * per TID microcode operating variables.
12897 */
12898 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
12899 0x55AA) {
12900 /*
12901 * Restore per TID negotiated values.
12902 */
12903 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12904 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12905 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
12906 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
12907 tagqng_able);
12908 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
12909 AdvWriteByteLram(iop_base,
12910 ASC_MC_NUMBER_OF_MAX_CMD + tid,
12911 max_cmd[tid]);
12912 }
12913 } else {
12914 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
12915 warn_code = ASC_WARN_BUSRESET_ERROR;
12916 }
12917 }
12918 }
1da177e4 12919
27c868c2
MW
12920 return warn_code;
12921}
1da177e4 12922
27c868c2
MW
12923/*
12924 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12925 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12926 * all of this is done.
12927 *
12928 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12929 *
12930 * For a non-fatal error return a warning code. If there are no warnings
12931 * then 0 is returned.
12932 *
12933 * Note: Chip is stopped on entry.
12934 */
78e77d8b 12935static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
12936{
12937 AdvPortAddr iop_base;
12938 ushort warn_code;
12939 ADVEEP_3550_CONFIG eep_config;
1da177e4 12940
27c868c2 12941 iop_base = asc_dvc->iop_base;
1da177e4 12942
27c868c2 12943 warn_code = 0;
1da177e4 12944
27c868c2
MW
12945 /*
12946 * Read the board's EEPROM configuration.
12947 *
12948 * Set default values if a bad checksum is found.
12949 */
12950 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12951 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 12952
27c868c2
MW
12953 /*
12954 * Set EEPROM default values.
12955 */
d68f4321
MW
12956 memcpy(&eep_config, &Default_3550_EEPROM_Config,
12957 sizeof(ADVEEP_3550_CONFIG));
1da177e4 12958
27c868c2 12959 /*
d68f4321
MW
12960 * Assume the 6 byte board serial number that was read from
12961 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
12962 */
12963 eep_config.serial_number_word3 =
12964 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 12965
27c868c2
MW
12966 eep_config.serial_number_word2 =
12967 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 12968
27c868c2
MW
12969 eep_config.serial_number_word1 =
12970 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 12971
27c868c2
MW
12972 AdvSet3550EEPConfig(iop_base, &eep_config);
12973 }
12974 /*
12975 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12976 * EEPROM configuration that was read.
12977 *
12978 * This is the mapping of EEPROM fields to Adv Library fields.
12979 */
12980 asc_dvc->wdtr_able = eep_config.wdtr_able;
12981 asc_dvc->sdtr_able = eep_config.sdtr_able;
12982 asc_dvc->ultra_able = eep_config.ultra_able;
12983 asc_dvc->tagqng_able = eep_config.tagqng_able;
12984 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12985 asc_dvc->max_host_qng = eep_config.max_host_qng;
12986 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12987 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12988 asc_dvc->start_motor = eep_config.start_motor;
12989 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12990 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12991 asc_dvc->no_scam = eep_config.scam_tolerant;
12992 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12993 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12994 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12995
12996 /*
12997 * Set the host maximum queuing (max. 253, min. 16) and the per device
12998 * maximum queuing (max. 63, min. 4).
12999 */
13000 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13001 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13002 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13003 /* If the value is zero, assume it is uninitialized. */
13004 if (eep_config.max_host_qng == 0) {
13005 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13006 } else {
13007 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13008 }
13009 }
1da177e4 13010
27c868c2
MW
13011 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13012 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13013 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13014 /* If the value is zero, assume it is uninitialized. */
13015 if (eep_config.max_dvc_qng == 0) {
13016 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13017 } else {
13018 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13019 }
13020 }
1da177e4 13021
27c868c2
MW
13022 /*
13023 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13024 * set 'max_dvc_qng' to 'max_host_qng'.
13025 */
13026 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13027 eep_config.max_dvc_qng = eep_config.max_host_qng;
13028 }
1da177e4 13029
27c868c2
MW
13030 /*
13031 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13032 * values based on possibly adjusted EEPROM values.
13033 */
13034 asc_dvc->max_host_qng = eep_config.max_host_qng;
13035 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13036
13037 /*
13038 * If the EEPROM 'termination' field is set to automatic (0), then set
13039 * the ADV_DVC_CFG 'termination' field to automatic also.
13040 *
13041 * If the termination is specified with a non-zero 'termination'
13042 * value check that a legal value is set and set the ADV_DVC_CFG
13043 * 'termination' field appropriately.
13044 */
13045 if (eep_config.termination == 0) {
13046 asc_dvc->cfg->termination = 0; /* auto termination */
13047 } else {
13048 /* Enable manual control with low off / high off. */
13049 if (eep_config.termination == 1) {
13050 asc_dvc->cfg->termination = TERM_CTL_SEL;
13051
13052 /* Enable manual control with low off / high on. */
13053 } else if (eep_config.termination == 2) {
13054 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
13055
13056 /* Enable manual control with low on / high on. */
13057 } else if (eep_config.termination == 3) {
13058 asc_dvc->cfg->termination =
13059 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
13060 } else {
13061 /*
13062 * The EEPROM 'termination' field contains a bad value. Use
13063 * automatic termination instead.
13064 */
13065 asc_dvc->cfg->termination = 0;
13066 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13067 }
13068 }
1da177e4 13069
27c868c2
MW
13070 return warn_code;
13071}
1da177e4 13072
27c868c2
MW
13073/*
13074 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
13075 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
13076 * all of this is done.
13077 *
13078 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13079 *
13080 * For a non-fatal error return a warning code. If there are no warnings
13081 * then 0 is returned.
13082 *
13083 * Note: Chip is stopped on entry.
13084 */
78e77d8b 13085static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
13086{
13087 AdvPortAddr iop_base;
13088 ushort warn_code;
13089 ADVEEP_38C0800_CONFIG eep_config;
27c868c2
MW
13090 uchar tid, termination;
13091 ushort sdtr_speed = 0;
13092
13093 iop_base = asc_dvc->iop_base;
13094
13095 warn_code = 0;
13096
13097 /*
13098 * Read the board's EEPROM configuration.
13099 *
13100 * Set default values if a bad checksum is found.
13101 */
13102 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
13103 eep_config.check_sum) {
13104 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13105
27c868c2
MW
13106 /*
13107 * Set EEPROM default values.
13108 */
d68f4321
MW
13109 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
13110 sizeof(ADVEEP_38C0800_CONFIG));
1da177e4 13111
27c868c2 13112 /*
d68f4321
MW
13113 * Assume the 6 byte board serial number that was read from
13114 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13115 */
13116 eep_config.serial_number_word3 =
13117 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 13118
27c868c2
MW
13119 eep_config.serial_number_word2 =
13120 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 13121
27c868c2
MW
13122 eep_config.serial_number_word1 =
13123 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13124
27c868c2
MW
13125 AdvSet38C0800EEPConfig(iop_base, &eep_config);
13126 }
13127 /*
13128 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
13129 * EEPROM configuration that was read.
13130 *
13131 * This is the mapping of EEPROM fields to Adv Library fields.
13132 */
13133 asc_dvc->wdtr_able = eep_config.wdtr_able;
13134 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13135 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13136 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13137 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13138 asc_dvc->tagqng_able = eep_config.tagqng_able;
13139 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13140 asc_dvc->max_host_qng = eep_config.max_host_qng;
13141 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13142 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13143 asc_dvc->start_motor = eep_config.start_motor;
13144 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13145 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13146 asc_dvc->no_scam = eep_config.scam_tolerant;
13147 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13148 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13149 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13150
13151 /*
13152 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13153 * are set, then set an 'sdtr_able' bit for it.
13154 */
13155 asc_dvc->sdtr_able = 0;
13156 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13157 if (tid == 0) {
13158 sdtr_speed = asc_dvc->sdtr_speed1;
13159 } else if (tid == 4) {
13160 sdtr_speed = asc_dvc->sdtr_speed2;
13161 } else if (tid == 8) {
13162 sdtr_speed = asc_dvc->sdtr_speed3;
13163 } else if (tid == 12) {
13164 sdtr_speed = asc_dvc->sdtr_speed4;
13165 }
13166 if (sdtr_speed & ADV_MAX_TID) {
13167 asc_dvc->sdtr_able |= (1 << tid);
13168 }
13169 sdtr_speed >>= 4;
13170 }
1da177e4 13171
27c868c2
MW
13172 /*
13173 * Set the host maximum queuing (max. 253, min. 16) and the per device
13174 * maximum queuing (max. 63, min. 4).
13175 */
13176 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13177 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13178 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13179 /* If the value is zero, assume it is uninitialized. */
13180 if (eep_config.max_host_qng == 0) {
13181 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13182 } else {
13183 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13184 }
13185 }
1da177e4 13186
27c868c2
MW
13187 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13188 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13189 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13190 /* If the value is zero, assume it is uninitialized. */
13191 if (eep_config.max_dvc_qng == 0) {
13192 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13193 } else {
13194 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13195 }
13196 }
1da177e4 13197
27c868c2
MW
13198 /*
13199 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13200 * set 'max_dvc_qng' to 'max_host_qng'.
13201 */
13202 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13203 eep_config.max_dvc_qng = eep_config.max_host_qng;
13204 }
1da177e4 13205
27c868c2
MW
13206 /*
13207 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13208 * values based on possibly adjusted EEPROM values.
13209 */
13210 asc_dvc->max_host_qng = eep_config.max_host_qng;
13211 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13212
13213 /*
13214 * If the EEPROM 'termination' field is set to automatic (0), then set
13215 * the ADV_DVC_CFG 'termination' field to automatic also.
13216 *
13217 * If the termination is specified with a non-zero 'termination'
13218 * value check that a legal value is set and set the ADV_DVC_CFG
13219 * 'termination' field appropriately.
13220 */
13221 if (eep_config.termination_se == 0) {
13222 termination = 0; /* auto termination for SE */
13223 } else {
13224 /* Enable manual control with low off / high off. */
13225 if (eep_config.termination_se == 1) {
13226 termination = 0;
13227
13228 /* Enable manual control with low off / high on. */
13229 } else if (eep_config.termination_se == 2) {
13230 termination = TERM_SE_HI;
13231
13232 /* Enable manual control with low on / high on. */
13233 } else if (eep_config.termination_se == 3) {
13234 termination = TERM_SE;
13235 } else {
13236 /*
13237 * The EEPROM 'termination_se' field contains a bad value.
13238 * Use automatic termination instead.
13239 */
13240 termination = 0;
13241 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13242 }
13243 }
1da177e4 13244
27c868c2
MW
13245 if (eep_config.termination_lvd == 0) {
13246 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13247 } else {
13248 /* Enable manual control with low off / high off. */
13249 if (eep_config.termination_lvd == 1) {
13250 asc_dvc->cfg->termination = termination;
13251
13252 /* Enable manual control with low off / high on. */
13253 } else if (eep_config.termination_lvd == 2) {
13254 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13255
13256 /* Enable manual control with low on / high on. */
13257 } else if (eep_config.termination_lvd == 3) {
13258 asc_dvc->cfg->termination = termination | TERM_LVD;
13259 } else {
13260 /*
13261 * The EEPROM 'termination_lvd' field contains a bad value.
13262 * Use automatic termination instead.
13263 */
13264 asc_dvc->cfg->termination = termination;
13265 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13266 }
13267 }
1da177e4 13268
27c868c2 13269 return warn_code;
1da177e4
LT
13270}
13271
13272/*
27c868c2
MW
13273 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13274 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13275 * all of this is done.
1da177e4
LT
13276 *
13277 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13278 *
13279 * For a non-fatal error return a warning code. If there are no warnings
13280 * then 0 is returned.
13281 *
27c868c2 13282 * Note: Chip is stopped on entry.
1da177e4 13283 */
78e77d8b 13284static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13285{
27c868c2
MW
13286 AdvPortAddr iop_base;
13287 ushort warn_code;
13288 ADVEEP_38C1600_CONFIG eep_config;
27c868c2
MW
13289 uchar tid, termination;
13290 ushort sdtr_speed = 0;
13291
13292 iop_base = asc_dvc->iop_base;
13293
13294 warn_code = 0;
13295
13296 /*
13297 * Read the board's EEPROM configuration.
13298 *
13299 * Set default values if a bad checksum is found.
13300 */
13301 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13302 eep_config.check_sum) {
13ac2d9c 13303 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2 13304 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13305
27c868c2
MW
13306 /*
13307 * Set EEPROM default values.
13308 */
d68f4321
MW
13309 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13310 sizeof(ADVEEP_38C1600_CONFIG));
27c868c2 13311
d68f4321
MW
13312 if (PCI_FUNC(pdev->devfn) != 0) {
13313 u8 ints;
13314 /*
13315 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13316 * and old Mac system booting problem. The Expansion
13317 * ROM must be disabled in Function 1 for these systems
13318 */
13319 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13320 /*
13321 * Clear the INTAB (bit 11) if the GPIO 0 input
13322 * indicates the Function 1 interrupt line is wired
13323 * to INTB.
13324 *
13325 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13326 * 1 - Function 1 interrupt line wired to INT A.
13327 * 0 - Function 1 interrupt line wired to INT B.
13328 *
13329 * Note: Function 0 is always wired to INTA.
13330 * Put all 5 GPIO bits in input mode and then read
13331 * their input values.
13332 */
13333 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13334 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13335 if ((ints & 0x01) == 0)
13336 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
27c868c2 13337 }
1da177e4 13338
27c868c2 13339 /*
d68f4321
MW
13340 * Assume the 6 byte board serial number that was read from
13341 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13342 */
13343 eep_config.serial_number_word3 =
d68f4321 13344 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
27c868c2 13345 eep_config.serial_number_word2 =
d68f4321 13346 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 13347 eep_config.serial_number_word1 =
d68f4321 13348 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13349
27c868c2
MW
13350 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13351 }
1da177e4 13352
27c868c2
MW
13353 /*
13354 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13355 * EEPROM configuration that was read.
13356 *
13357 * This is the mapping of EEPROM fields to Adv Library fields.
13358 */
13359 asc_dvc->wdtr_able = eep_config.wdtr_able;
13360 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13361 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13362 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13363 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13364 asc_dvc->ppr_able = 0;
13365 asc_dvc->tagqng_able = eep_config.tagqng_able;
13366 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13367 asc_dvc->max_host_qng = eep_config.max_host_qng;
13368 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13369 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13370 asc_dvc->start_motor = eep_config.start_motor;
13371 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13372 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13373 asc_dvc->no_scam = eep_config.scam_tolerant;
13374
13375 /*
13376 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13377 * are set, then set an 'sdtr_able' bit for it.
13378 */
13379 asc_dvc->sdtr_able = 0;
13380 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13381 if (tid == 0) {
13382 sdtr_speed = asc_dvc->sdtr_speed1;
13383 } else if (tid == 4) {
13384 sdtr_speed = asc_dvc->sdtr_speed2;
13385 } else if (tid == 8) {
13386 sdtr_speed = asc_dvc->sdtr_speed3;
13387 } else if (tid == 12) {
13388 sdtr_speed = asc_dvc->sdtr_speed4;
13389 }
13390 if (sdtr_speed & ASC_MAX_TID) {
13391 asc_dvc->sdtr_able |= (1 << tid);
13392 }
13393 sdtr_speed >>= 4;
13394 }
1da177e4 13395
27c868c2
MW
13396 /*
13397 * Set the host maximum queuing (max. 253, min. 16) and the per device
13398 * maximum queuing (max. 63, min. 4).
13399 */
13400 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13401 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13402 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13403 /* If the value is zero, assume it is uninitialized. */
13404 if (eep_config.max_host_qng == 0) {
13405 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13406 } else {
13407 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13408 }
13409 }
1da177e4 13410
27c868c2
MW
13411 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13412 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13413 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13414 /* If the value is zero, assume it is uninitialized. */
13415 if (eep_config.max_dvc_qng == 0) {
13416 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13417 } else {
13418 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13419 }
13420 }
1da177e4 13421
27c868c2
MW
13422 /*
13423 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13424 * set 'max_dvc_qng' to 'max_host_qng'.
13425 */
13426 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13427 eep_config.max_dvc_qng = eep_config.max_host_qng;
13428 }
1da177e4 13429
27c868c2
MW
13430 /*
13431 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13432 * values based on possibly adjusted EEPROM values.
13433 */
13434 asc_dvc->max_host_qng = eep_config.max_host_qng;
13435 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13436
13437 /*
13438 * If the EEPROM 'termination' field is set to automatic (0), then set
13439 * the ASC_DVC_CFG 'termination' field to automatic also.
13440 *
13441 * If the termination is specified with a non-zero 'termination'
13442 * value check that a legal value is set and set the ASC_DVC_CFG
13443 * 'termination' field appropriately.
13444 */
13445 if (eep_config.termination_se == 0) {
13446 termination = 0; /* auto termination for SE */
13447 } else {
13448 /* Enable manual control with low off / high off. */
13449 if (eep_config.termination_se == 1) {
13450 termination = 0;
13451
13452 /* Enable manual control with low off / high on. */
13453 } else if (eep_config.termination_se == 2) {
13454 termination = TERM_SE_HI;
13455
13456 /* Enable manual control with low on / high on. */
13457 } else if (eep_config.termination_se == 3) {
13458 termination = TERM_SE;
13459 } else {
13460 /*
13461 * The EEPROM 'termination_se' field contains a bad value.
13462 * Use automatic termination instead.
13463 */
13464 termination = 0;
13465 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13466 }
13467 }
1da177e4 13468
27c868c2
MW
13469 if (eep_config.termination_lvd == 0) {
13470 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13471 } else {
13472 /* Enable manual control with low off / high off. */
13473 if (eep_config.termination_lvd == 1) {
13474 asc_dvc->cfg->termination = termination;
13475
13476 /* Enable manual control with low off / high on. */
13477 } else if (eep_config.termination_lvd == 2) {
13478 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13479
13480 /* Enable manual control with low on / high on. */
13481 } else if (eep_config.termination_lvd == 3) {
13482 asc_dvc->cfg->termination = termination | TERM_LVD;
13483 } else {
13484 /*
13485 * The EEPROM 'termination_lvd' field contains a bad value.
13486 * Use automatic termination instead.
13487 */
13488 asc_dvc->cfg->termination = termination;
13489 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13490 }
13491 }
1da177e4 13492
27c868c2 13493 return warn_code;
1da177e4
LT
13494}
13495
13496/*
13497 * Read EEPROM configuration into the specified buffer.
13498 *
13499 * Return a checksum based on the EEPROM configuration read.
13500 */
78e77d8b 13501static ushort __devinit
1da177e4
LT
13502AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
13503{
27c868c2
MW
13504 ushort wval, chksum;
13505 ushort *wbuf;
13506 int eep_addr;
13507 ushort *charfields;
13508
13509 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
13510 wbuf = (ushort *)cfg_buf;
13511 chksum = 0;
13512
13513 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13514 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13515 wval = AdvReadEEPWord(iop_base, eep_addr);
13516 chksum += wval; /* Checksum is calculated from word values. */
13517 if (*charfields++) {
13518 *wbuf = le16_to_cpu(wval);
13519 } else {
13520 *wbuf = wval;
13521 }
13522 }
13523 /* Read checksum word. */
13524 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13525 wbuf++;
13526 charfields++;
13527
13528 /* Read rest of EEPROM not covered by the checksum. */
13529 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13530 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13531 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13532 if (*charfields++) {
13533 *wbuf = le16_to_cpu(*wbuf);
13534 }
13535 }
13536 return chksum;
1da177e4
LT
13537}
13538
13539/*
13540 * Read EEPROM configuration into the specified buffer.
13541 *
13542 * Return a checksum based on the EEPROM configuration read.
13543 */
78e77d8b 13544static ushort __devinit
27c868c2 13545AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 13546{
27c868c2
MW
13547 ushort wval, chksum;
13548 ushort *wbuf;
13549 int eep_addr;
13550 ushort *charfields;
13551
13552 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
13553 wbuf = (ushort *)cfg_buf;
13554 chksum = 0;
13555
13556 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13557 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13558 wval = AdvReadEEPWord(iop_base, eep_addr);
13559 chksum += wval; /* Checksum is calculated from word values. */
13560 if (*charfields++) {
13561 *wbuf = le16_to_cpu(wval);
13562 } else {
13563 *wbuf = wval;
13564 }
13565 }
13566 /* Read checksum word. */
13567 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13568 wbuf++;
13569 charfields++;
13570
13571 /* Read rest of EEPROM not covered by the checksum. */
13572 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13573 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13574 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13575 if (*charfields++) {
13576 *wbuf = le16_to_cpu(*wbuf);
13577 }
13578 }
13579 return chksum;
1da177e4
LT
13580}
13581
13582/*
13583 * Read EEPROM configuration into the specified buffer.
13584 *
13585 * Return a checksum based on the EEPROM configuration read.
13586 */
78e77d8b 13587static ushort __devinit
27c868c2 13588AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 13589{
27c868c2
MW
13590 ushort wval, chksum;
13591 ushort *wbuf;
13592 int eep_addr;
13593 ushort *charfields;
13594
13595 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
13596 wbuf = (ushort *)cfg_buf;
13597 chksum = 0;
13598
13599 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13600 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13601 wval = AdvReadEEPWord(iop_base, eep_addr);
13602 chksum += wval; /* Checksum is calculated from word values. */
13603 if (*charfields++) {
13604 *wbuf = le16_to_cpu(wval);
13605 } else {
13606 *wbuf = wval;
13607 }
13608 }
13609 /* Read checksum word. */
13610 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13611 wbuf++;
13612 charfields++;
13613
13614 /* Read rest of EEPROM not covered by the checksum. */
13615 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13616 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13617 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13618 if (*charfields++) {
13619 *wbuf = le16_to_cpu(*wbuf);
13620 }
13621 }
13622 return chksum;
1da177e4
LT
13623}
13624
13625/*
13626 * Read the EEPROM from specified location
13627 */
78e77d8b 13628static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 13629{
27c868c2
MW
13630 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13631 ASC_EEP_CMD_READ | eep_word_addr);
13632 AdvWaitEEPCmd(iop_base);
13633 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
13634}
13635
13636/*
13637 * Wait for EEPROM command to complete
13638 */
78e77d8b 13639static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 13640{
27c868c2
MW
13641 int eep_delay_ms;
13642
13643 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
13644 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
13645 ASC_EEP_CMD_DONE) {
13646 break;
13647 }
13648 DvcSleepMilliSecond(1);
13649 }
13650 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
13651 0) {
13652 ASC_ASSERT(0);
13653 }
13654 return;
1da177e4
LT
13655}
13656
13657/*
13658 * Write the EEPROM from 'cfg_buf'.
13659 */
78e77d8b 13660void __devinit
1da177e4
LT
13661AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
13662{
27c868c2
MW
13663 ushort *wbuf;
13664 ushort addr, chksum;
13665 ushort *charfields;
13666
13667 wbuf = (ushort *)cfg_buf;
13668 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
13669 chksum = 0;
13670
13671 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13672 AdvWaitEEPCmd(iop_base);
13673
13674 /*
13675 * Write EEPROM from word 0 to word 20.
13676 */
13677 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13678 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13679 ushort word;
13680
13681 if (*charfields++) {
13682 word = cpu_to_le16(*wbuf);
13683 } else {
13684 word = *wbuf;
13685 }
13686 chksum += *wbuf; /* Checksum is calculated from word values. */
13687 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13688 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13689 ASC_EEP_CMD_WRITE | addr);
13690 AdvWaitEEPCmd(iop_base);
13691 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
13692 }
1da177e4 13693
27c868c2
MW
13694 /*
13695 * Write EEPROM checksum at word 21.
13696 */
13697 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13698 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13699 AdvWaitEEPCmd(iop_base);
13700 wbuf++;
13701 charfields++;
13702
13703 /*
13704 * Write EEPROM OEM name at words 22 to 29.
13705 */
13706 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13707 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13708 ushort word;
13709
13710 if (*charfields++) {
13711 word = cpu_to_le16(*wbuf);
13712 } else {
13713 word = *wbuf;
13714 }
13715 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13716 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13717 ASC_EEP_CMD_WRITE | addr);
13718 AdvWaitEEPCmd(iop_base);
13719 }
13720 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13721 AdvWaitEEPCmd(iop_base);
13722 return;
1da177e4
LT
13723}
13724
13725/*
13726 * Write the EEPROM from 'cfg_buf'.
13727 */
78e77d8b 13728void __devinit
27c868c2 13729AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 13730{
27c868c2
MW
13731 ushort *wbuf;
13732 ushort *charfields;
13733 ushort addr, chksum;
13734
13735 wbuf = (ushort *)cfg_buf;
13736 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
13737 chksum = 0;
13738
13739 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13740 AdvWaitEEPCmd(iop_base);
13741
13742 /*
13743 * Write EEPROM from word 0 to word 20.
13744 */
13745 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13746 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13747 ushort word;
13748
13749 if (*charfields++) {
13750 word = cpu_to_le16(*wbuf);
13751 } else {
13752 word = *wbuf;
13753 }
13754 chksum += *wbuf; /* Checksum is calculated from word values. */
13755 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13756 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13757 ASC_EEP_CMD_WRITE | addr);
13758 AdvWaitEEPCmd(iop_base);
13759 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
13760 }
1da177e4 13761
27c868c2
MW
13762 /*
13763 * Write EEPROM checksum at word 21.
13764 */
13765 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13766 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13767 AdvWaitEEPCmd(iop_base);
13768 wbuf++;
13769 charfields++;
13770
13771 /*
13772 * Write EEPROM OEM name at words 22 to 29.
13773 */
13774 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13775 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13776 ushort word;
13777
13778 if (*charfields++) {
13779 word = cpu_to_le16(*wbuf);
13780 } else {
13781 word = *wbuf;
13782 }
13783 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13784 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13785 ASC_EEP_CMD_WRITE | addr);
13786 AdvWaitEEPCmd(iop_base);
13787 }
13788 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13789 AdvWaitEEPCmd(iop_base);
13790 return;
1da177e4
LT
13791}
13792
13793/*
13794 * Write the EEPROM from 'cfg_buf'.
13795 */
78e77d8b 13796void __devinit
27c868c2 13797AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 13798{
27c868c2
MW
13799 ushort *wbuf;
13800 ushort *charfields;
13801 ushort addr, chksum;
13802
13803 wbuf = (ushort *)cfg_buf;
13804 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
13805 chksum = 0;
13806
13807 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13808 AdvWaitEEPCmd(iop_base);
13809
13810 /*
13811 * Write EEPROM from word 0 to word 20.
13812 */
13813 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13814 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13815 ushort word;
13816
13817 if (*charfields++) {
13818 word = cpu_to_le16(*wbuf);
13819 } else {
13820 word = *wbuf;
13821 }
13822 chksum += *wbuf; /* Checksum is calculated from word values. */
13823 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13824 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13825 ASC_EEP_CMD_WRITE | addr);
13826 AdvWaitEEPCmd(iop_base);
13827 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
13828 }
1da177e4 13829
27c868c2
MW
13830 /*
13831 * Write EEPROM checksum at word 21.
13832 */
13833 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13834 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13835 AdvWaitEEPCmd(iop_base);
13836 wbuf++;
13837 charfields++;
13838
13839 /*
13840 * Write EEPROM OEM name at words 22 to 29.
13841 */
13842 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13843 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13844 ushort word;
13845
13846 if (*charfields++) {
13847 word = cpu_to_le16(*wbuf);
13848 } else {
13849 word = *wbuf;
13850 }
13851 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13852 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13853 ASC_EEP_CMD_WRITE | addr);
13854 AdvWaitEEPCmd(iop_base);
13855 }
13856 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13857 AdvWaitEEPCmd(iop_base);
13858 return;
1da177e4
LT
13859}
13860
13861/* a_advlib.c */
13862/*
13863 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
13864 *
13865 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
13866 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
13867 * RISC to notify it a new command is ready to be executed.
13868 *
13869 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
13870 * set to SCSI_MAX_RETRY.
13871 *
13872 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
13873 * for DMA addresses or math operations are byte swapped to little-endian
13874 * order.
13875 *
13876 * Return:
13877 * ADV_SUCCESS(1) - The request was successfully queued.
13878 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
13879 * request completes.
13880 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
13881 * host IC error.
13882 */
27c868c2 13883static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 13884{
27c868c2
MW
13885 ulong last_int_level;
13886 AdvPortAddr iop_base;
13887 ADV_DCNT req_size;
13888 ADV_PADDR req_paddr;
13889 ADV_CARR_T *new_carrp;
13890
13891 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
13892
13893 /*
13894 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
13895 */
13896 if (scsiq->target_id > ADV_MAX_TID) {
13897 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
13898 scsiq->done_status = QD_WITH_ERROR;
13899 return ADV_ERROR;
13900 }
1da177e4 13901
27c868c2 13902 iop_base = asc_dvc->iop_base;
1da177e4 13903
27c868c2 13904 last_int_level = DvcEnterCritical();
1da177e4 13905
27c868c2
MW
13906 /*
13907 * Allocate a carrier ensuring at least one carrier always
13908 * remains on the freelist and initialize fields.
13909 */
13910 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
13911 DvcLeaveCritical(last_int_level);
13912 return ADV_BUSY;
13913 }
13914 asc_dvc->carr_freelist = (ADV_CARR_T *)
13915 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
13916 asc_dvc->carr_pending_cnt++;
13917
13918 /*
13919 * Set the carrier to be a stopper by setting 'next_vpa'
13920 * to the stopper value. The current stopper will be changed
13921 * below to point to the new stopper.
13922 */
13923 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13924
13925 /*
13926 * Clear the ADV_SCSI_REQ_Q done flag.
13927 */
13928 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
13929
13930 req_size = sizeof(ADV_SCSI_REQ_Q);
13931 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
13932 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
13933
13934 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
13935 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
13936
13937 /* Wait for assertion before making little-endian */
13938 req_paddr = cpu_to_le32(req_paddr);
13939
13940 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
13941 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
13942 scsiq->scsiq_rptr = req_paddr;
13943
13944 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
13945 /*
13946 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
13947 * order during initialization.
13948 */
13949 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
13950
13951 /*
13952 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
13953 * the microcode. The newly allocated stopper will become the new
13954 * stopper.
13955 */
13956 asc_dvc->icq_sp->areq_vpa = req_paddr;
13957
13958 /*
13959 * Set the 'next_vpa' pointer for the old stopper to be the
13960 * physical address of the new stopper. The RISC can only
13961 * follow physical addresses.
13962 */
13963 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
13964
13965 /*
13966 * Set the host adapter stopper pointer to point to the new carrier.
13967 */
13968 asc_dvc->icq_sp = new_carrp;
13969
13970 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
13971 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13972 /*
13973 * Tickle the RISC to tell it to read its Command Queue Head pointer.
13974 */
13975 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
13976 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
13977 /*
13978 * Clear the tickle value. In the ASC-3550 the RISC flag
13979 * command 'clr_tickle_a' does not work unless the host
13980 * value is cleared.
13981 */
13982 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
13983 ADV_TICKLE_NOP);
13984 }
13985 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13986 /*
13987 * Notify the RISC a carrier is ready by writing the physical
13988 * address of the new carrier stopper to the COMMA register.
13989 */
13990 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
13991 le32_to_cpu(new_carrp->carr_pa));
13992 }
1da177e4 13993
27c868c2 13994 DvcLeaveCritical(last_int_level);
1da177e4 13995
27c868c2 13996 return ADV_SUCCESS;
1da177e4
LT
13997}
13998
13999/*
14000 * Reset SCSI Bus and purge all outstanding requests.
14001 *
14002 * Return Value:
14003 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
14004 * ADV_FALSE(0) - Microcode command failed.
14005 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
14006 * may be hung which requires driver recovery.
14007 */
27c868c2 14008static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 14009{
27c868c2
MW
14010 int status;
14011
14012 /*
14013 * Send the SCSI Bus Reset idle start idle command which asserts
14014 * the SCSI Bus Reset signal.
14015 */
14016 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
14017 if (status != ADV_TRUE) {
14018 return status;
14019 }
1da177e4 14020
27c868c2
MW
14021 /*
14022 * Delay for the specified SCSI Bus Reset hold time.
14023 *
14024 * The hold time delay is done on the host because the RISC has no
14025 * microsecond accurate timer.
14026 */
14027 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
14028
14029 /*
14030 * Send the SCSI Bus Reset end idle command which de-asserts
14031 * the SCSI Bus Reset signal and purges any pending requests.
14032 */
14033 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
14034 if (status != ADV_TRUE) {
14035 return status;
14036 }
14037
14038 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
1da177e4 14039
27c868c2 14040 return status;
1da177e4
LT
14041}
14042
14043/*
14044 * Reset chip and SCSI Bus.
14045 *
14046 * Return Value:
14047 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
14048 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
14049 */
27c868c2 14050static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 14051{
27c868c2
MW
14052 int status;
14053 ushort wdtr_able, sdtr_able, tagqng_able;
14054 ushort ppr_able = 0;
14055 uchar tid, max_cmd[ADV_MAX_TID + 1];
14056 AdvPortAddr iop_base;
14057 ushort bios_sig;
14058
14059 iop_base = asc_dvc->iop_base;
14060
14061 /*
14062 * Save current per TID negotiated values.
14063 */
14064 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14065 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14066 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14067 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14068 }
14069 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14070 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14071 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14072 max_cmd[tid]);
14073 }
1da177e4 14074
27c868c2
MW
14075 /*
14076 * Force the AdvInitAsc3550/38C0800Driver() function to
14077 * perform a SCSI Bus Reset by clearing the BIOS signature word.
14078 * The initialization functions assumes a SCSI Bus Reset is not
14079 * needed if the BIOS signature word is present.
14080 */
14081 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
14082 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
14083
14084 /*
14085 * Stop chip and reset it.
14086 */
14087 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
14088 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
14089 DvcSleepMilliSecond(100);
14090 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14091 ADV_CTRL_REG_CMD_WR_IO_REG);
14092
14093 /*
14094 * Reset Adv Library error code, if any, and try
14095 * re-initializing the chip.
14096 */
14097 asc_dvc->err_code = 0;
14098 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14099 status = AdvInitAsc38C1600Driver(asc_dvc);
14100 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14101 status = AdvInitAsc38C0800Driver(asc_dvc);
14102 } else {
14103 status = AdvInitAsc3550Driver(asc_dvc);
14104 }
1da177e4 14105
27c868c2
MW
14106 /* Translate initialization return value to status value. */
14107 if (status == 0) {
14108 status = ADV_TRUE;
14109 } else {
14110 status = ADV_FALSE;
14111 }
1da177e4 14112
27c868c2
MW
14113 /*
14114 * Restore the BIOS signature word.
14115 */
14116 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
14117
14118 /*
14119 * Restore per TID negotiated values.
14120 */
14121 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14122 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14123 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14124 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14125 }
14126 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14127 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14128 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14129 max_cmd[tid]);
14130 }
1da177e4 14131
27c868c2 14132 return status;
1da177e4
LT
14133}
14134
14135/*
14136 * Adv Library Interrupt Service Routine
14137 *
14138 * This function is called by a driver's interrupt service routine.
14139 * The function disables and re-enables interrupts.
14140 *
14141 * When a microcode idle command is completed, the ADV_DVC_VAR
14142 * 'idle_cmd_done' field is set to ADV_TRUE.
14143 *
14144 * Note: AdvISR() can be called when interrupts are disabled or even
14145 * when there is no hardware interrupt condition present. It will
14146 * always check for completed idle commands and microcode requests.
14147 * This is an important feature that shouldn't be changed because it
14148 * allows commands to be completed from polling mode loops.
14149 *
14150 * Return:
14151 * ADV_TRUE(1) - interrupt was pending
14152 * ADV_FALSE(0) - no interrupt was pending
14153 */
27c868c2 14154static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 14155{
27c868c2
MW
14156 AdvPortAddr iop_base;
14157 uchar int_stat;
14158 ushort target_bit;
14159 ADV_CARR_T *free_carrp;
14160 ADV_VADDR irq_next_vpa;
14161 int flags;
14162 ADV_SCSI_REQ_Q *scsiq;
1da177e4 14163
27c868c2 14164 flags = DvcEnterCritical();
1da177e4 14165
27c868c2
MW
14166 iop_base = asc_dvc->iop_base;
14167
14168 /* Reading the register clears the interrupt. */
14169 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
14170
14171 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
14172 ADV_INTR_STATUS_INTRC)) == 0) {
14173 DvcLeaveCritical(flags);
14174 return ADV_FALSE;
14175 }
14176
14177 /*
14178 * Notify the driver of an asynchronous microcode condition by
895d6b4c 14179 * calling the adv_async_callback function. The function
27c868c2
MW
14180 * is passed the microcode ASC_MC_INTRB_CODE byte value.
14181 */
14182 if (int_stat & ADV_INTR_STATUS_INTRB) {
14183 uchar intrb_code;
14184
14185 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
14186
14187 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
14188 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14189 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
14190 asc_dvc->carr_pending_cnt != 0) {
14191 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
14192 ADV_TICKLE_A);
14193 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14194 AdvWriteByteRegister(iop_base,
14195 IOPB_TICKLE,
14196 ADV_TICKLE_NOP);
14197 }
14198 }
14199 }
14200
895d6b4c 14201 adv_async_callback(asc_dvc, intrb_code);
27c868c2
MW
14202 }
14203
14204 /*
14205 * Check if the IRQ stopper carrier contains a completed request.
14206 */
14207 while (((irq_next_vpa =
14208 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
14209 /*
14210 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
14211 * The RISC will have set 'areq_vpa' to a virtual address.
14212 *
14213 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
14214 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
14215 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
14216 * in AdvExeScsiQueue().
14217 */
14218 scsiq = (ADV_SCSI_REQ_Q *)
14219 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
14220
14221 /*
14222 * Request finished with good status and the queue was not
14223 * DMAed to host memory by the firmware. Set all status fields
14224 * to indicate good status.
14225 */
14226 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
14227 scsiq->done_status = QD_NO_ERROR;
14228 scsiq->host_status = scsiq->scsi_status = 0;
14229 scsiq->data_cnt = 0L;
14230 }
14231
14232 /*
14233 * Advance the stopper pointer to the next carrier
14234 * ignoring the lower four bits. Free the previous
14235 * stopper carrier.
14236 */
14237 free_carrp = asc_dvc->irq_sp;
14238 asc_dvc->irq_sp = (ADV_CARR_T *)
14239 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
14240
14241 free_carrp->next_vpa =
14242 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14243 asc_dvc->carr_freelist = free_carrp;
14244 asc_dvc->carr_pending_cnt--;
14245
14246 ASC_ASSERT(scsiq != NULL);
14247 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
14248
14249 /*
14250 * Clear request microcode control flag.
14251 */
14252 scsiq->cntl = 0;
14253
27c868c2
MW
14254 /*
14255 * Notify the driver of the completed request by passing
14256 * the ADV_SCSI_REQ_Q pointer to its callback function.
14257 */
14258 scsiq->a_flag |= ADV_SCSIQ_DONE;
895d6b4c 14259 adv_isr_callback(asc_dvc, scsiq);
27c868c2
MW
14260 /*
14261 * Note: After the driver callback function is called, 'scsiq'
14262 * can no longer be referenced.
14263 *
14264 * Fall through and continue processing other completed
14265 * requests...
14266 */
14267
14268 /*
14269 * Disable interrupts again in case the driver inadvertently
14270 * enabled interrupts in its callback function.
14271 *
14272 * The DvcEnterCritical() return value is ignored, because
14273 * the 'flags' saved when AdvISR() was first entered will be
14274 * used to restore the interrupt flag on exit.
14275 */
14276 (void)DvcEnterCritical();
14277 }
14278 DvcLeaveCritical(flags);
14279 return ADV_TRUE;
1da177e4
LT
14280}
14281
14282/*
14283 * Send an idle command to the chip and wait for completion.
14284 *
14285 * Command completion is polled for once per microsecond.
14286 *
14287 * The function can be called from anywhere including an interrupt handler.
14288 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
14289 * functions to prevent reentrancy.
14290 *
14291 * Return Values:
14292 * ADV_TRUE - command completed successfully
14293 * ADV_FALSE - command failed
14294 * ADV_ERROR - command timed out
14295 */
27c868c2 14296static int
1da177e4 14297AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 14298 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 14299{
27c868c2
MW
14300 ulong last_int_level;
14301 int result;
14302 ADV_DCNT i, j;
14303 AdvPortAddr iop_base;
14304
14305 last_int_level = DvcEnterCritical();
14306
14307 iop_base = asc_dvc->iop_base;
14308
14309 /*
14310 * Clear the idle command status which is set by the microcode
14311 * to a non-zero value to indicate when the command is completed.
14312 * The non-zero result is one of the IDLE_CMD_STATUS_* values
14313 * defined in a_advlib.h.
14314 */
14315 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
14316
14317 /*
14318 * Write the idle command value after the idle command parameter
14319 * has been written to avoid a race condition. If the order is not
14320 * followed, the microcode may process the idle command before the
14321 * parameters have been written to LRAM.
14322 */
14323 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
14324 cpu_to_le32(idle_cmd_parameter));
14325 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
14326
14327 /*
14328 * Tickle the RISC to tell it to process the idle command.
14329 */
14330 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
14331 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14332 /*
14333 * Clear the tickle value. In the ASC-3550 the RISC flag
14334 * command 'clr_tickle_b' does not work unless the host
14335 * value is cleared.
14336 */
14337 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
14338 }
1da177e4 14339
27c868c2
MW
14340 /* Wait for up to 100 millisecond for the idle command to timeout. */
14341 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
14342 /* Poll once each microsecond for command completion. */
14343 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
14344 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
14345 result);
14346 if (result != 0) {
14347 DvcLeaveCritical(last_int_level);
14348 return result;
14349 }
14350 DvcDelayMicroSecond(asc_dvc, (ushort)1);
14351 }
14352 }
1da177e4 14353
27c868c2
MW
14354 ASC_ASSERT(0); /* The idle command should never timeout. */
14355 DvcLeaveCritical(last_int_level);
14356 return ADV_ERROR;
1da177e4
LT
14357}
14358
b2c16f58
MW
14359static int __devinit
14360advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
14361{
14362 int req_cnt = 0;
14363 adv_req_t *reqp = NULL;
14364 int sg_cnt = 0;
14365 adv_sgblk_t *sgp;
14366 int warn_code, err_code;
14367
14368 /*
14369 * Allocate buffer carrier structures. The total size
14370 * is about 4 KB, so allocate all at once.
14371 */
14372 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
14373 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
14374
14375 if (!boardp->carrp)
14376 goto kmalloc_failed;
14377
14378 /*
14379 * Allocate up to 'max_host_qng' request structures for the Wide
14380 * board. The total size is about 16 KB, so allocate all at once.
14381 * If the allocation fails decrement and try again.
14382 */
14383 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
14384 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
14385
14386 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
14387 "bytes %lu\n", reqp, req_cnt,
14388 (ulong)sizeof(adv_req_t) * req_cnt);
14389
14390 if (reqp)
14391 break;
14392 }
14393
14394 if (!reqp)
14395 goto kmalloc_failed;
14396
14397 boardp->orig_reqp = reqp;
14398
14399 /*
14400 * Allocate up to ADV_TOT_SG_BLOCK request structures for
14401 * the Wide board. Each structure is about 136 bytes.
14402 */
14403 boardp->adv_sgblkp = NULL;
14404 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
14405 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
14406
14407 if (!sgp)
14408 break;
14409
14410 sgp->next_sgblkp = boardp->adv_sgblkp;
14411 boardp->adv_sgblkp = sgp;
14412
14413 }
14414
14415 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
14416 sg_cnt, sizeof(adv_sgblk_t),
14417 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
14418
14419 if (!boardp->adv_sgblkp)
14420 goto kmalloc_failed;
14421
14422 adv_dvc_varp->carrier_buf = boardp->carrp;
14423
14424 /*
14425 * Point 'adv_reqp' to the request structures and
14426 * link them together.
14427 */
14428 req_cnt--;
14429 reqp[req_cnt].next_reqp = NULL;
14430 for (; req_cnt > 0; req_cnt--) {
14431 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
14432 }
14433 boardp->adv_reqp = &reqp[0];
14434
14435 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
14436 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
14437 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
14438 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14439 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
14440 "\n");
14441 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
14442 } else {
14443 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
14444 "\n");
14445 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
14446 }
14447 err_code = adv_dvc_varp->err_code;
14448
14449 if (warn_code || err_code) {
14450 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
14451 " error 0x%x\n", boardp->id, warn_code, err_code);
14452 }
14453
14454 goto exit;
14455
14456 kmalloc_failed:
14457 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
14458 "failed\n", boardp->id);
14459 err_code = ADV_ERROR;
14460 exit:
14461 return err_code;
14462}
14463
14464static void advansys_wide_free_mem(asc_board_t *boardp)
14465{
14466 kfree(boardp->carrp);
14467 boardp->carrp = NULL;
14468 kfree(boardp->orig_reqp);
14469 boardp->orig_reqp = boardp->adv_reqp = NULL;
14470 while (boardp->adv_sgblkp) {
14471 adv_sgblk_t *sgp = boardp->adv_sgblkp;
14472 boardp->adv_sgblkp = sgp->next_sgblkp;
14473 kfree(sgp);
14474 }
14475}
14476
27c868c2
MW
14477static struct Scsi_Host *__devinit
14478advansys_board_found(int iop, struct device *dev, int bus_type)
14479{
14480 struct Scsi_Host *shost;
14481 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
14482 asc_board_t *boardp;
14483 ASC_DVC_VAR *asc_dvc_varp = NULL;
14484 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 14485 int share_irq;
27c868c2
MW
14486 int warn_code, err_code;
14487 int ret;
14488
14489 /*
27c868c2
MW
14490 * Register the adapter, get its configuration, and
14491 * initialize it.
14492 */
8dfb5379
MW
14493 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
14494 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
14495 if (!shost)
14496 return NULL;
14497
27c868c2
MW
14498 /* Initialize private per board data */
14499 boardp = ASC_BOARDP(shost);
14500 memset(boardp, 0, sizeof(asc_board_t));
78e77d8b 14501 boardp->id = asc_board_count++;
27c868c2 14502 spin_lock_init(&boardp->lock);
394dbf3f 14503 boardp->dev = dev;
27c868c2
MW
14504
14505 /*
14506 * Handle both narrow and wide boards.
14507 *
14508 * If a Wide board was detected, set the board structure
14509 * wide board flag. Set-up the board structure based on
14510 * the board type.
14511 */
14512#ifdef CONFIG_PCI
14513 if (bus_type == ASC_IS_PCI &&
14514 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14515 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14516 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
14517 boardp->flags |= ASC_IS_WIDE_BOARD;
14518 }
14519#endif /* CONFIG_PCI */
14520
14521 if (ASC_NARROW_BOARD(boardp)) {
14522 ASC_DBG(1, "advansys_board_found: narrow board\n");
14523 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
14524 asc_dvc_varp->bus_type = bus_type;
14525 asc_dvc_varp->drv_ptr = boardp;
14526 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
14527 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
14528 asc_dvc_varp->iop_base = iop;
27c868c2 14529 } else {
57ba5fe9 14530#ifdef CONFIG_PCI
27c868c2
MW
14531 ASC_DBG(1, "advansys_board_found: wide board\n");
14532 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
14533 adv_dvc_varp->drv_ptr = boardp;
14534 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
27c868c2
MW
14535 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
14536 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
14537 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
14538 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
14539 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
14540 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
14541 } else {
14542 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
14543 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
14544 }
27c868c2 14545
57ba5fe9
MW
14546 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
14547 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
14548 boardp->asc_n_io_port);
14549 if (!boardp->ioremap_addr) {
27c868c2
MW
14550 ASC_PRINT3
14551 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
57ba5fe9
MW
14552 boardp->id, pci_resource_start(pdev, 1),
14553 boardp->asc_n_io_port);
b2c16f58 14554 goto err_shost;
27c868c2 14555 }
57ba5fe9 14556 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
71f36115 14557 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
27c868c2 14558 adv_dvc_varp->iop_base);
27c868c2
MW
14559
14560 /*
14561 * Even though it isn't used to access wide boards, other
14562 * than for the debug line below, save I/O Port address so
14563 * that it can be reported.
14564 */
14565 boardp->ioport = iop;
14566
57ba5fe9
MW
14567 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
14568 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
14569 (ushort)inpw(iop));
14570#endif /* CONFIG_PCI */
27c868c2
MW
14571 }
14572
14573#ifdef CONFIG_PROC_FS
14574 /*
14575 * Allocate buffer for printing information from
14576 * /proc/scsi/advansys/[0...].
14577 */
b2c16f58
MW
14578 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
14579 if (!boardp->prtbuf) {
14580 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
14581 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
14582 goto err_unmap;
27c868c2
MW
14583 }
14584#endif /* CONFIG_PROC_FS */
14585
14586 if (ASC_NARROW_BOARD(boardp)) {
27c868c2
MW
14587 /*
14588 * Set the board bus type and PCI IRQ before
14589 * calling AscInitGetConfig().
14590 */
14591 switch (asc_dvc_varp->bus_type) {
14592#ifdef CONFIG_ISA
14593 case ASC_IS_ISA:
14594 shost->unchecked_isa_dma = TRUE;
074c8fe4 14595 share_irq = 0;
27c868c2
MW
14596 break;
14597 case ASC_IS_VL:
14598 shost->unchecked_isa_dma = FALSE;
074c8fe4 14599 share_irq = 0;
27c868c2
MW
14600 break;
14601 case ASC_IS_EISA:
14602 shost->unchecked_isa_dma = FALSE;
074c8fe4 14603 share_irq = IRQF_SHARED;
27c868c2
MW
14604 break;
14605#endif /* CONFIG_ISA */
14606#ifdef CONFIG_PCI
14607 case ASC_IS_PCI:
14608 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
27c868c2 14609 shost->unchecked_isa_dma = FALSE;
074c8fe4 14610 share_irq = IRQF_SHARED;
27c868c2
MW
14611 break;
14612#endif /* CONFIG_PCI */
14613 default:
14614 ASC_PRINT2
14615 ("advansys_board_found: board %d: unknown adapter type: %d\n",
14616 boardp->id, asc_dvc_varp->bus_type);
14617 shost->unchecked_isa_dma = TRUE;
074c8fe4 14618 share_irq = 0;
27c868c2
MW
14619 break;
14620 }
27c868c2 14621
27c868c2
MW
14622 /*
14623 * NOTE: AscInitGetConfig() may change the board's
14624 * bus_type value. The bus_type value should no
14625 * longer be used. If the bus_type field must be
14626 * referenced only use the bit-wise AND operator "&".
14627 */
14628 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
c2dce2fa 14629 err_code = AscInitGetConfig(boardp);
27c868c2 14630 } else {
c2dce2fa
MW
14631#ifdef CONFIG_PCI
14632 /*
14633 * For Wide boards set PCI information before calling
14634 * AdvInitGetConfig().
14635 */
14636 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
14637 shost->unchecked_isa_dma = FALSE;
14638 share_irq = IRQF_SHARED;
27c868c2 14639 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
394dbf3f 14640
c2dce2fa
MW
14641 err_code = AdvInitGetConfig(pdev, boardp);
14642#endif /* CONFIG_PCI */
27c868c2
MW
14643 }
14644
b2c16f58
MW
14645 if (err_code != 0)
14646 goto err_free_proc;
27c868c2
MW
14647
14648 /*
14649 * Save the EEPROM configuration so that it can be displayed
14650 * from /proc/scsi/advansys/[0...].
14651 */
14652 if (ASC_NARROW_BOARD(boardp)) {
14653
14654 ASCEEP_CONFIG *ep;
14655
14656 /*
14657 * Set the adapter's target id bit in the 'init_tidmask' field.
14658 */
14659 boardp->init_tidmask |=
14660 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
14661
14662 /*
14663 * Save EEPROM settings for the board.
14664 */
14665 ep = &boardp->eep_config.asc_eep;
14666
14667 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
14668 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
14669 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
14670 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
14671 ep->start_motor = asc_dvc_varp->start_motor;
14672 ep->cntl = asc_dvc_varp->dvc_cntl;
14673 ep->no_scam = asc_dvc_varp->no_scam;
14674 ep->max_total_qng = asc_dvc_varp->max_total_qng;
14675 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
14676 /* 'max_tag_qng' is set to the same value for every device. */
14677 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
14678 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
14679 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
14680 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
14681 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
14682 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
14683 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
14684
14685 /*
14686 * Modify board configuration.
14687 */
14688 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
c2dce2fa
MW
14689 err_code = AscInitSetConfig(pdev, boardp);
14690 if (err_code)
b2c16f58 14691 goto err_free_proc;
27c868c2
MW
14692
14693 /*
14694 * Finish initializing the 'Scsi_Host' structure.
14695 */
14696 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
14697 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
14698 shost->irq = asc_dvc_varp->irq_no;
14699 }
14700 } else {
14701 ADVEEP_3550_CONFIG *ep_3550;
14702 ADVEEP_38C0800_CONFIG *ep_38C0800;
14703 ADVEEP_38C1600_CONFIG *ep_38C1600;
14704
14705 /*
14706 * Save Wide EEP Configuration Information.
14707 */
14708 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
14709 ep_3550 = &boardp->eep_config.adv_3550_eep;
14710
14711 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
14712 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
14713 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14714 ep_3550->termination = adv_dvc_varp->cfg->termination;
14715 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
14716 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
14717 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
14718 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
14719 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
14720 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
14721 ep_3550->start_motor = adv_dvc_varp->start_motor;
14722 ep_3550->scsi_reset_delay =
14723 adv_dvc_varp->scsi_reset_wait;
14724 ep_3550->serial_number_word1 =
14725 adv_dvc_varp->cfg->serial1;
14726 ep_3550->serial_number_word2 =
14727 adv_dvc_varp->cfg->serial2;
14728 ep_3550->serial_number_word3 =
14729 adv_dvc_varp->cfg->serial3;
14730 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14731 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
14732
14733 ep_38C0800->adapter_scsi_id =
14734 adv_dvc_varp->chip_scsi_id;
14735 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
14736 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14737 ep_38C0800->termination_lvd =
14738 adv_dvc_varp->cfg->termination;
14739 ep_38C0800->disc_enable =
14740 adv_dvc_varp->cfg->disc_enable;
14741 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
14742 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
14743 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14744 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14745 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14746 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14747 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14748 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14749 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
14750 ep_38C0800->scsi_reset_delay =
14751 adv_dvc_varp->scsi_reset_wait;
14752 ep_38C0800->serial_number_word1 =
14753 adv_dvc_varp->cfg->serial1;
14754 ep_38C0800->serial_number_word2 =
14755 adv_dvc_varp->cfg->serial2;
14756 ep_38C0800->serial_number_word3 =
14757 adv_dvc_varp->cfg->serial3;
14758 } else {
14759 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
14760
14761 ep_38C1600->adapter_scsi_id =
14762 adv_dvc_varp->chip_scsi_id;
14763 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
14764 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14765 ep_38C1600->termination_lvd =
14766 adv_dvc_varp->cfg->termination;
14767 ep_38C1600->disc_enable =
14768 adv_dvc_varp->cfg->disc_enable;
14769 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
14770 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
14771 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14772 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14773 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14774 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14775 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14776 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14777 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
14778 ep_38C1600->scsi_reset_delay =
14779 adv_dvc_varp->scsi_reset_wait;
14780 ep_38C1600->serial_number_word1 =
14781 adv_dvc_varp->cfg->serial1;
14782 ep_38C1600->serial_number_word2 =
14783 adv_dvc_varp->cfg->serial2;
14784 ep_38C1600->serial_number_word3 =
14785 adv_dvc_varp->cfg->serial3;
14786 }
14787
14788 /*
14789 * Set the adapter's target id bit in the 'init_tidmask' field.
14790 */
14791 boardp->init_tidmask |=
14792 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
27c868c2
MW
14793 }
14794
14795 /*
14796 * Channels are numbered beginning with 0. For AdvanSys one host
14797 * structure supports one channel. Multi-channel boards have a
14798 * separate host structure for each channel.
14799 */
14800 shost->max_channel = 0;
14801 if (ASC_NARROW_BOARD(boardp)) {
14802 shost->max_id = ASC_MAX_TID + 1;
14803 shost->max_lun = ASC_MAX_LUN + 1;
f05ec594 14804 shost->max_cmd_len = ASC_MAX_CDB_LEN;
27c868c2
MW
14805
14806 shost->io_port = asc_dvc_varp->iop_base;
14807 boardp->asc_n_io_port = ASC_IOADR_GAP;
14808 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
14809
14810 /* Set maximum number of queues the adapter can handle. */
14811 shost->can_queue = asc_dvc_varp->max_total_qng;
14812 } else {
14813 shost->max_id = ADV_MAX_TID + 1;
14814 shost->max_lun = ADV_MAX_LUN + 1;
f05ec594 14815 shost->max_cmd_len = ADV_MAX_CDB_LEN;
27c868c2
MW
14816
14817 /*
14818 * Save the I/O Port address and length even though
14819 * I/O ports are not used to access Wide boards.
14820 * Instead the Wide boards are accessed with
14821 * PCI Memory Mapped I/O.
14822 */
14823 shost->io_port = iop;
27c868c2
MW
14824
14825 shost->this_id = adv_dvc_varp->chip_scsi_id;
14826
14827 /* Set maximum number of queues the adapter can handle. */
14828 shost->can_queue = adv_dvc_varp->max_host_qng;
14829 }
14830
27c868c2
MW
14831 /*
14832 * Following v1.3.89, 'cmd_per_lun' is no longer needed
14833 * and should be set to zero.
14834 *
14835 * But because of a bug introduced in v1.3.89 if the driver is
14836 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
14837 * SCSI function 'allocate_device' will panic. To allow the driver
14838 * to work as a module in these kernels set 'cmd_per_lun' to 1.
14839 *
14840 * Note: This is wrong. cmd_per_lun should be set to the depth
14841 * you want on untagged devices always.
14842 #ifdef MODULE
14843 */
14844 shost->cmd_per_lun = 1;
14845/* #else
14846 shost->cmd_per_lun = 0;
14847#endif */
14848
14849 /*
14850 * Set the maximum number of scatter-gather elements the
14851 * adapter can handle.
14852 */
14853 if (ASC_NARROW_BOARD(boardp)) {
14854 /*
14855 * Allow two commands with 'sg_tablesize' scatter-gather
14856 * elements to be executed simultaneously. This value is
14857 * the theoretical hardware limit. It may be decreased
14858 * below.
14859 */
14860 shost->sg_tablesize =
14861 (((asc_dvc_varp->max_total_qng - 2) / 2) *
14862 ASC_SG_LIST_PER_Q) + 1;
14863 } else {
14864 shost->sg_tablesize = ADV_MAX_SG_LIST;
14865 }
14866
14867 /*
14868 * The value of 'sg_tablesize' can not exceed the SCSI
14869 * mid-level driver definition of SG_ALL. SG_ALL also
14870 * must not be exceeded, because it is used to define the
14871 * size of the scatter-gather table in 'struct asc_sg_head'.
14872 */
14873 if (shost->sg_tablesize > SG_ALL) {
14874 shost->sg_tablesize = SG_ALL;
14875 }
14876
14877 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
14878
14879 /* BIOS start address. */
14880 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
14881 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
14882 asc_dvc_varp->bus_type);
27c868c2
MW
14883 } else {
14884 /*
14885 * Fill-in BIOS board variables. The Wide BIOS saves
14886 * information in LRAM that is used by the driver.
14887 */
14888 AdvReadWordLram(adv_dvc_varp->iop_base,
14889 BIOS_SIGNATURE, boardp->bios_signature);
14890 AdvReadWordLram(adv_dvc_varp->iop_base,
14891 BIOS_VERSION, boardp->bios_version);
14892 AdvReadWordLram(adv_dvc_varp->iop_base,
14893 BIOS_CODESEG, boardp->bios_codeseg);
14894 AdvReadWordLram(adv_dvc_varp->iop_base,
14895 BIOS_CODELEN, boardp->bios_codelen);
14896
14897 ASC_DBG2(1,
14898 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
14899 boardp->bios_signature, boardp->bios_version);
14900
14901 ASC_DBG2(1,
14902 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
14903 boardp->bios_codeseg, boardp->bios_codelen);
14904
14905 /*
14906 * If the BIOS saved a valid signature, then fill in
14907 * the BIOS code segment base address.
14908 */
14909 if (boardp->bios_signature == 0x55AA) {
14910 /*
14911 * Convert x86 realmode code segment to a linear
14912 * address by shifting left 4.
14913 */
14914 shost->base = ((ulong)boardp->bios_codeseg << 4);
14915 } else {
14916 shost->base = 0;
14917 }
14918 }
14919
14920 /*
14921 * Register Board Resources - I/O Port, DMA, IRQ
14922 */
14923
27c868c2
MW
14924 /* Register DMA Channel for Narrow boards. */
14925 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
14926#ifdef CONFIG_ISA
14927 if (ASC_NARROW_BOARD(boardp)) {
14928 /* Register DMA channel for ISA bus. */
14929 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
14930 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
b2c16f58
MW
14931 ret = request_dma(shost->dma_channel, "advansys");
14932 if (ret) {
27c868c2
MW
14933 ASC_PRINT3
14934 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
14935 boardp->id, shost->dma_channel, ret);
71f36115 14936 goto err_free_proc;
27c868c2
MW
14937 }
14938 AscEnableIsaDma(shost->dma_channel);
14939 }
14940 }
14941#endif /* CONFIG_ISA */
14942
14943 /* Register IRQ Number. */
14944 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
14945
14946 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
14947 "advansys", shost);
14948
14949 if (ret) {
27c868c2
MW
14950 if (ret == -EBUSY) {
14951 ASC_PRINT2
14952 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14953 boardp->id, shost->irq);
14954 } else if (ret == -EINVAL) {
14955 ASC_PRINT2
14956 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14957 boardp->id, shost->irq);
14958 } else {
14959 ASC_PRINT3
14960 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14961 boardp->id, shost->irq, ret);
14962 }
b2c16f58 14963 goto err_free_dma;
27c868c2
MW
14964 }
14965
14966 /*
14967 * Initialize board RISC chip and enable interrupts.
14968 */
14969 if (ASC_NARROW_BOARD(boardp)) {
14970 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
14971 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14972 err_code = asc_dvc_varp->err_code;
14973
14974 if (warn_code || err_code) {
14975 ASC_PRINT4
14976 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
14977 boardp->id,
14978 asc_dvc_varp->init_state, warn_code, err_code);
14979 }
14980 } else {
b2c16f58 14981 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
14982 }
14983
b2c16f58
MW
14984 if (err_code != 0)
14985 goto err_free_wide_mem;
14986
27c868c2
MW
14987 ASC_DBG_PRT_SCSI_HOST(2, shost);
14988
8dfb5379
MW
14989 ret = scsi_add_host(shost, dev);
14990 if (ret)
14991 goto err_free_wide_mem;
14992
14993 scsi_scan_host(shost);
27c868c2 14994 return shost;
b2c16f58
MW
14995
14996 err_free_wide_mem:
14997 advansys_wide_free_mem(boardp);
14998 free_irq(shost->irq, shost);
14999 err_free_dma:
15000 if (shost->dma_channel != NO_ISA_DMA)
15001 free_dma(shost->dma_channel);
b2c16f58
MW
15002 err_free_proc:
15003 kfree(boardp->prtbuf);
15004 err_unmap:
15005 if (boardp->ioremap_addr)
15006 iounmap(boardp->ioremap_addr);
15007 err_shost:
8dfb5379 15008 scsi_host_put(shost);
b2c16f58 15009 return NULL;
27c868c2
MW
15010}
15011
27c868c2
MW
15012/*
15013 * advansys_release()
15014 *
15015 * Release resources allocated for a single AdvanSys adapter.
15016 */
15017static int advansys_release(struct Scsi_Host *shost)
15018{
15019 asc_board_t *boardp;
15020
15021 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 15022 scsi_remove_host(shost);
27c868c2 15023 boardp = ASC_BOARDP(shost);
074c8fe4 15024 free_irq(shost->irq, shost);
27c868c2
MW
15025 if (shost->dma_channel != NO_ISA_DMA) {
15026 ASC_DBG(1, "advansys_release: free_dma()\n");
15027 free_dma(shost->dma_channel);
15028 }
27c868c2 15029 if (ASC_WIDE_BOARD(boardp)) {
27c868c2 15030 iounmap(boardp->ioremap_addr);
b2c16f58 15031 advansys_wide_free_mem(boardp);
27c868c2 15032 }
27c868c2 15033 kfree(boardp->prtbuf);
8dfb5379 15034 scsi_host_put(shost);
27c868c2
MW
15035 ASC_DBG(1, "advansys_release: end\n");
15036 return 0;
15037}
15038
c304ec94
MW
15039static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
15040 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
15041 0x0210, 0x0230, 0x0250, 0x0330
15042};
15043
15044static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
15045{
15046 PortAddr iop_base = _asc_def_iop_base[id];
15047 struct Scsi_Host *shost;
15048
15049 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
15050 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
15051 iop_base);
c304ec94
MW
15052 return -ENODEV;
15053 }
15054 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
15055 if (!AscFindSignature(iop_base))
15056 goto nodev;
15057 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
15058 goto nodev;
15059
15060 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
c304ec94
MW
15061 if (!shost)
15062 goto nodev;
15063
15064 dev_set_drvdata(dev, shost);
15065 return 0;
15066
15067 nodev:
71f36115 15068 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
15069 return -ENODEV;
15070}
15071
15072static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
15073{
71f36115 15074 int ioport = _asc_def_iop_base[id];
c304ec94 15075 advansys_release(dev_get_drvdata(dev));
71f36115 15076 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
15077 return 0;
15078}
15079
15080static struct isa_driver advansys_isa_driver = {
15081 .probe = advansys_isa_probe,
15082 .remove = __devexit_p(advansys_isa_remove),
15083 .driver = {
15084 .owner = THIS_MODULE,
15085 .name = "advansys",
15086 },
15087};
15088
15089static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
15090{
15091 PortAddr iop_base = _asc_def_iop_base[id];
15092 struct Scsi_Host *shost;
15093
15094 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
15095 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
15096 iop_base);
c304ec94
MW
15097 return -ENODEV;
15098 }
15099 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
15100 if (!AscFindSignature(iop_base))
15101 goto nodev;
15102 /*
15103 * I don't think this condition can actually happen, but the old
15104 * driver did it, and the chances of finding a VLB setup in 2007
15105 * to do testing with is slight to none.
15106 */
15107 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
15108 goto nodev;
15109
15110 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
c304ec94
MW
15111 if (!shost)
15112 goto nodev;
15113
15114 dev_set_drvdata(dev, shost);
15115 return 0;
15116
15117 nodev:
71f36115 15118 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
15119 return -ENODEV;
15120}
15121
15122static struct isa_driver advansys_vlb_driver = {
15123 .probe = advansys_vlb_probe,
15124 .remove = __devexit_p(advansys_isa_remove),
15125 .driver = {
15126 .owner = THIS_MODULE,
b8e5152b 15127 .name = "advansys_vlb",
c304ec94
MW
15128 },
15129};
15130
b09e05a7
MW
15131static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
15132 { "ABP7401" },
15133 { "ABP7501" },
15134 { "" }
15135};
15136
15137MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
15138
15139/*
15140 * EISA is a little more tricky than PCI; each EISA device may have two
15141 * channels, and this driver is written to make each channel its own Scsi_Host
15142 */
15143struct eisa_scsi_data {
15144 struct Scsi_Host *host[2];
15145};
15146
15147static int __devinit advansys_eisa_probe(struct device *dev)
15148{
15149 int i, ioport;
15150 int err;
15151 struct eisa_device *edev = to_eisa_device(dev);
15152 struct eisa_scsi_data *data;
15153
15154 err = -ENOMEM;
15155 data = kzalloc(sizeof(*data), GFP_KERNEL);
15156 if (!data)
15157 goto fail;
15158 ioport = edev->base_addr + 0xc30;
15159
15160 err = -ENODEV;
15161 for (i = 0; i < 2; i++, ioport += 0x20) {
71f36115
MW
15162 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
15163 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
15164 ioport + ASC_IOADR_GAP - 1);
15165 continue;
15166 }
15167 if (!AscFindSignature(ioport)) {
15168 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 15169 continue;
71f36115
MW
15170 }
15171
b09e05a7
MW
15172 /*
15173 * I don't know why we need to do this for EISA chips, but
15174 * not for any others. It looks to be equivalent to
15175 * AscGetChipCfgMsw, but I may have overlooked something,
15176 * so I'm not converting it until I get an EISA board to
15177 * test with.
15178 */
15179 inw(ioport + 4);
15180 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
71f36115 15181 if (data->host[i]) {
b09e05a7 15182 err = 0;
71f36115
MW
15183 } else {
15184 release_region(ioport, ASC_IOADR_GAP);
15185 }
b09e05a7
MW
15186 }
15187
15188 if (err) {
15189 kfree(data);
15190 } else {
15191 dev_set_drvdata(dev, data);
15192 }
15193
15194 fail:
15195 return err;
15196}
15197
15198static __devexit int advansys_eisa_remove(struct device *dev)
15199{
15200 int i;
15201 struct eisa_scsi_data *data = dev_get_drvdata(dev);
15202
15203 for (i = 0; i < 2; i++) {
71f36115 15204 int ioport;
b09e05a7
MW
15205 struct Scsi_Host *shost = data->host[i];
15206 if (!shost)
15207 continue;
71f36115 15208 ioport = shost->io_port;
b09e05a7 15209 advansys_release(shost);
71f36115 15210 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
15211 }
15212
15213 kfree(data);
15214 return 0;
15215}
15216
15217static struct eisa_driver advansys_eisa_driver = {
15218 .id_table = advansys_eisa_table,
15219 .driver = {
15220 .name = "advansys",
15221 .probe = advansys_eisa_probe,
15222 .remove = __devexit_p(advansys_eisa_remove),
15223 }
15224};
15225
2672ea86
DJ
15226/* PCI Devices supported by this driver */
15227static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
15228 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
15229 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15230 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
15231 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15232 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
15233 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15234 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
15235 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15236 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
15237 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15238 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
15239 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15240 {}
2672ea86 15241};
27c868c2 15242
2672ea86 15243MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b 15244
9649af39
MW
15245static void __devinit advansys_set_latency(struct pci_dev *pdev)
15246{
15247 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
15248 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
15249 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
15250 } else {
15251 u8 latency;
15252 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
15253 if (latency < 0x20)
15254 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
15255 }
15256}
15257
78e77d8b
MW
15258static int __devinit
15259advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
15260{
15261 int err, ioport;
15262 struct Scsi_Host *shost;
15263
15264 err = pci_enable_device(pdev);
15265 if (err)
15266 goto fail;
71f36115
MW
15267 err = pci_request_regions(pdev, "advansys");
15268 if (err)
15269 goto disable_device;
9649af39
MW
15270 pci_set_master(pdev);
15271 advansys_set_latency(pdev);
78e77d8b
MW
15272
15273 if (pci_resource_len(pdev, 0) == 0)
15274 goto nodev;
15275
15276 ioport = pci_resource_start(pdev, 0);
15277 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
15278
15279 if (!shost)
15280 goto nodev;
15281
15282 pci_set_drvdata(pdev, shost);
15283 return 0;
15284
15285 nodev:
15286 err = -ENODEV;
71f36115
MW
15287 pci_release_regions(pdev);
15288 disable_device:
78e77d8b
MW
15289 pci_disable_device(pdev);
15290 fail:
15291 return err;
15292}
15293
15294static void __devexit advansys_pci_remove(struct pci_dev *pdev)
15295{
15296 advansys_release(pci_get_drvdata(pdev));
71f36115 15297 pci_release_regions(pdev);
78e77d8b
MW
15298 pci_disable_device(pdev);
15299}
15300
15301static struct pci_driver advansys_pci_driver = {
15302 .name = "advansys",
15303 .id_table = advansys_pci_tbl,
15304 .probe = advansys_pci_probe,
15305 .remove = __devexit_p(advansys_pci_remove),
15306};
8c6af9e1 15307
8dfb5379
MW
15308static int __init advansys_init(void)
15309{
c304ec94 15310 int error;
b09e05a7 15311
c304ec94
MW
15312 error = isa_register_driver(&advansys_isa_driver,
15313 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
15314 if (error)
15315 goto fail;
8dfb5379 15316
c304ec94
MW
15317 error = isa_register_driver(&advansys_vlb_driver,
15318 ASC_IOADR_TABLE_MAX_IX);
15319 if (error)
15320 goto unregister_isa;
15321
15322 error = eisa_driver_register(&advansys_eisa_driver);
15323 if (error)
15324 goto unregister_vlb;
15325
b09e05a7
MW
15326 error = pci_register_driver(&advansys_pci_driver);
15327 if (error)
15328 goto unregister_eisa;
15329
8dfb5379 15330 return 0;
78e77d8b 15331
b09e05a7
MW
15332 unregister_eisa:
15333 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15334 unregister_vlb:
15335 isa_unregister_driver(&advansys_vlb_driver);
15336 unregister_isa:
15337 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 15338 fail:
78e77d8b 15339 return error;
8dfb5379
MW
15340}
15341
15342static void __exit advansys_exit(void)
15343{
78e77d8b 15344 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 15345 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15346 isa_unregister_driver(&advansys_vlb_driver);
15347 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
15348}
15349
15350module_init(advansys_init);
15351module_exit(advansys_exit);
15352
8c6af9e1 15353MODULE_LICENSE("GPL");