[SCSI] advansys: Remove ASC_WIDE_BOARD predicate
[deliverable/linux.git] / drivers / scsi / advansys.c
CommitLineData
01fbfe0b 1#define DRV_NAME "advansys"
8c6af9e1 2#define ASC_VERSION "3.4" /* AdvanSys Driver Version */
1da177e4
LT
3
4/*
5 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6 *
7 * Copyright (c) 1995-2000 Advanced System Products, Inc.
8 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8c6af9e1 9 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
1da177e4
LT
10 * All Rights Reserved.
11 *
8c6af9e1
MW
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 */
17
18/*
1da177e4
LT
19 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
20 * changed its name to ConnectCom Solutions, Inc.
8c6af9e1 21 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
1da177e4
LT
22 */
23
1da177e4 24#include <linux/module.h>
1da177e4
LT
25#include <linux/string.h>
26#include <linux/kernel.h>
27#include <linux/types.h>
28#include <linux/ioport.h>
29#include <linux/interrupt.h>
30#include <linux/delay.h>
31#include <linux/slab.h>
32#include <linux/mm.h>
33#include <linux/proc_fs.h>
34#include <linux/init.h>
35#include <linux/blkdev.h>
c304ec94 36#include <linux/isa.h>
b09e05a7 37#include <linux/eisa.h>
8c6af9e1 38#include <linux/pci.h>
1da177e4
LT
39#include <linux/spinlock.h>
40#include <linux/dma-mapping.h>
41
42#include <asm/io.h>
43#include <asm/system.h>
44#include <asm/dma.h>
45
8c6af9e1
MW
46#include <scsi/scsi_cmnd.h>
47#include <scsi/scsi_device.h>
48#include <scsi/scsi_tcq.h>
49#include <scsi/scsi.h>
50#include <scsi/scsi_host.h>
51
4bd6d7f3 52/* FIXME:
1da177e4 53 *
4bd6d7f3
MW
54 * 1. Although all of the necessary command mapping places have the
55 * appropriate dma_map.. APIs, the driver still processes its internal
56 * queue using bus_to_virt() and virt_to_bus() which are illegal under
57 * the API. The entire queue processing structure will need to be
58 * altered to fix this.
59 * 2. Need to add memory mapping workaround. Test the memory mapping.
60 * If it doesn't work revert to I/O port access. Can a test be done
61 * safely?
62 * 3. Handle an interrupt not working. Keep an interrupt counter in
63 * the interrupt handler. In the timeout function if the interrupt
64 * has not occurred then print a message and run in polled mode.
65 * 4. Need to add support for target mode commands, cf. CAM XPT.
66 * 5. check DMA mapping functions for failure
349d2c44
MW
67 * 6. Use scsi_transport_spi
68 * 7. advansys_info is not safe against multiple simultaneous callers
69 * 8. Kill boardp->id
70 * 9. Add module_param to override ISA/VLB ioport array
1da177e4
LT
71 */
72#warning this driver is still not properly converted to the DMA API
73
1da177e4
LT
74/* Enable driver /proc statistics. */
75#define ADVANSYS_STATS
76
77/* Enable driver tracing. */
78/* #define ADVANSYS_DEBUG */
79
1da177e4
LT
80#define ASC_LIB_VERSION_MAJOR 1
81#define ASC_LIB_VERSION_MINOR 24
82#define ASC_LIB_SERIAL_NUMBER 123
83
84/*
85 * Portable Data Types
86 *
87 * Any instance where a 32-bit long or pointer type is assumed
88 * for precision or HW defined structures, the following define
89 * types must be used. In Linux the char, short, and int types
90 * are all consistent at 8, 16, and 32 bits respectively. Pointers
91 * and long types are 64 bits on Alpha and UltraSPARC.
92 */
27c868c2
MW
93#define ASC_PADDR __u32 /* Physical/Bus address data type. */
94#define ASC_VADDR __u32 /* Virtual address data type. */
95#define ASC_DCNT __u32 /* Unsigned Data count type. */
96#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
97
98/*
99 * These macros are used to convert a virtual address to a
100 * 32-bit value. This currently can be used on Linux Alpha
101 * which uses 64-bit virtual address but a 32-bit bus address.
102 * This is likely to break in the future, but doing this now
103 * will give us time to change the HW and FW to handle 64-bit
104 * addresses.
105 */
106#define ASC_VADDR_TO_U32 virt_to_bus
107#define ASC_U32_TO_VADDR bus_to_virt
108
109typedef unsigned char uchar;
110
111#ifndef TRUE
112#define TRUE (1)
113#endif
114#ifndef FALSE
115#define FALSE (0)
116#endif
117
1da177e4
LT
118#define ERR (-1)
119#define UW_ERR (uint)(0xFFFF)
120#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
1da177e4 121
2672ea86
DJ
122#define PCI_VENDOR_ID_ASP 0x10cd
123#define PCI_DEVICE_ID_ASP_1200A 0x1100
124#define PCI_DEVICE_ID_ASP_ABP940 0x1200
125#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
126#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
127#define PCI_DEVICE_ID_38C0800_REV1 0x2500
128#define PCI_DEVICE_ID_38C1600_REV1 0x2700
129
1da177e4
LT
130/*
131 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
132 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
133 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
134 * SRB structure.
135 */
136#define CC_VERY_LONG_SG_LIST 0
137#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
138
27c868c2 139#define PortAddr unsigned short /* port address size */
1da177e4
LT
140#define inp(port) inb(port)
141#define outp(port, byte) outb((byte), (port))
142
143#define inpw(port) inw(port)
144#define outpw(port, word) outw((word), (port))
145
146#define ASC_MAX_SG_QUEUE 7
147#define ASC_MAX_SG_LIST 255
148
149#define ASC_CS_TYPE unsigned short
150
151#define ASC_IS_ISA (0x0001)
152#define ASC_IS_ISAPNP (0x0081)
153#define ASC_IS_EISA (0x0002)
154#define ASC_IS_PCI (0x0004)
155#define ASC_IS_PCI_ULTRA (0x0104)
156#define ASC_IS_PCMCIA (0x0008)
157#define ASC_IS_MCA (0x0020)
158#define ASC_IS_VL (0x0040)
1da177e4
LT
159#define ASC_IS_WIDESCSI_16 (0x0100)
160#define ASC_IS_WIDESCSI_32 (0x0200)
161#define ASC_IS_BIG_ENDIAN (0x8000)
95c9f162 162
1da177e4
LT
163#define ASC_CHIP_MIN_VER_VL (0x01)
164#define ASC_CHIP_MAX_VER_VL (0x07)
165#define ASC_CHIP_MIN_VER_PCI (0x09)
166#define ASC_CHIP_MAX_VER_PCI (0x0F)
167#define ASC_CHIP_VER_PCI_BIT (0x08)
168#define ASC_CHIP_MIN_VER_ISA (0x11)
169#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
170#define ASC_CHIP_MAX_VER_ISA (0x27)
171#define ASC_CHIP_VER_ISA_BIT (0x30)
172#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
173#define ASC_CHIP_VER_ASYN_BUG (0x21)
174#define ASC_CHIP_VER_PCI 0x08
175#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
176#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
177#define ASC_CHIP_MIN_VER_EISA (0x41)
178#define ASC_CHIP_MAX_VER_EISA (0x47)
179#define ASC_CHIP_VER_EISA_BIT (0x40)
180#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
1da177e4 181#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
1da177e4 182#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
1da177e4 183#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
1da177e4
LT
184
185#define ASC_SCSI_ID_BITS 3
186#define ASC_SCSI_TIX_TYPE uchar
187#define ASC_ALL_DEVICE_BIT_SET 0xFF
188#define ASC_SCSI_BIT_ID_TYPE uchar
189#define ASC_MAX_TID 7
190#define ASC_MAX_LUN 7
191#define ASC_SCSI_WIDTH_BIT_SET 0xFF
192#define ASC_MAX_SENSE_LEN 32
193#define ASC_MIN_SENSE_LEN 14
1da177e4
LT
194#define ASC_SCSI_RESET_HOLD_TIME_US 60
195
f05ec594
MW
196/*
197 * Narrow boards only support 12-byte commands, while wide boards
198 * extend to 16-byte commands.
199 */
200#define ASC_MAX_CDB_LEN 12
201#define ADV_MAX_CDB_LEN 16
202
1da177e4 203#define MS_SDTR_LEN 0x03
1da177e4 204#define MS_WDTR_LEN 0x02
1da177e4
LT
205
206#define ASC_SG_LIST_PER_Q 7
207#define QS_FREE 0x00
208#define QS_READY 0x01
209#define QS_DISC1 0x02
210#define QS_DISC2 0x04
211#define QS_BUSY 0x08
212#define QS_ABORTED 0x40
213#define QS_DONE 0x80
214#define QC_NO_CALLBACK 0x01
215#define QC_SG_SWAP_QUEUE 0x02
216#define QC_SG_HEAD 0x04
217#define QC_DATA_IN 0x08
218#define QC_DATA_OUT 0x10
219#define QC_URGENT 0x20
220#define QC_MSG_OUT 0x40
221#define QC_REQ_SENSE 0x80
222#define QCSG_SG_XFER_LIST 0x02
223#define QCSG_SG_XFER_MORE 0x04
224#define QCSG_SG_XFER_END 0x08
225#define QD_IN_PROGRESS 0x00
226#define QD_NO_ERROR 0x01
227#define QD_ABORTED_BY_HOST 0x02
228#define QD_WITH_ERROR 0x04
229#define QD_INVALID_REQUEST 0x80
230#define QD_INVALID_HOST_NUM 0x81
231#define QD_INVALID_DEVICE 0x82
232#define QD_ERR_INTERNAL 0xFF
233#define QHSTA_NO_ERROR 0x00
234#define QHSTA_M_SEL_TIMEOUT 0x11
235#define QHSTA_M_DATA_OVER_RUN 0x12
236#define QHSTA_M_DATA_UNDER_RUN 0x12
237#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
238#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
239#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
240#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
241#define QHSTA_D_HOST_ABORT_FAILED 0x23
242#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
243#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
244#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
245#define QHSTA_M_WTM_TIMEOUT 0x41
246#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
247#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
248#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
249#define QHSTA_M_TARGET_STATUS_BUSY 0x45
250#define QHSTA_M_BAD_TAG_CODE 0x46
251#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
252#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
253#define QHSTA_D_LRAM_CMP_ERROR 0x81
254#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
255#define ASC_FLAG_SCSIQ_REQ 0x01
256#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
257#define ASC_FLAG_BIOS_ASYNC_IO 0x04
258#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
259#define ASC_FLAG_WIN16 0x10
260#define ASC_FLAG_WIN32 0x20
261#define ASC_FLAG_ISA_OVER_16MB 0x40
262#define ASC_FLAG_DOS_VM_CALLBACK 0x80
263#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
264#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
265#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
266#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
267#define ASC_SCSIQ_CPY_BEG 4
268#define ASC_SCSIQ_SGHD_CPY_BEG 2
269#define ASC_SCSIQ_B_FWD 0
270#define ASC_SCSIQ_B_BWD 1
271#define ASC_SCSIQ_B_STATUS 2
272#define ASC_SCSIQ_B_QNO 3
273#define ASC_SCSIQ_B_CNTL 4
274#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
275#define ASC_SCSIQ_D_DATA_ADDR 8
276#define ASC_SCSIQ_D_DATA_CNT 12
277#define ASC_SCSIQ_B_SENSE_LEN 20
278#define ASC_SCSIQ_DONE_INFO_BEG 22
279#define ASC_SCSIQ_D_SRBPTR 22
280#define ASC_SCSIQ_B_TARGET_IX 26
281#define ASC_SCSIQ_B_CDB_LEN 28
282#define ASC_SCSIQ_B_TAG_CODE 29
283#define ASC_SCSIQ_W_VM_ID 30
284#define ASC_SCSIQ_DONE_STATUS 32
285#define ASC_SCSIQ_HOST_STATUS 33
286#define ASC_SCSIQ_SCSI_STATUS 34
287#define ASC_SCSIQ_CDB_BEG 36
288#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
289#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
290#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
291#define ASC_SCSIQ_B_SG_WK_QP 49
292#define ASC_SCSIQ_B_SG_WK_IX 50
293#define ASC_SCSIQ_W_ALT_DC1 52
294#define ASC_SCSIQ_B_LIST_CNT 6
295#define ASC_SCSIQ_B_CUR_LIST_CNT 7
296#define ASC_SGQ_B_SG_CNTL 4
297#define ASC_SGQ_B_SG_HEAD_QP 5
298#define ASC_SGQ_B_SG_LIST_CNT 6
299#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
300#define ASC_SGQ_LIST_BEG 8
301#define ASC_DEF_SCSI1_QNG 4
302#define ASC_MAX_SCSI1_QNG 4
303#define ASC_DEF_SCSI2_QNG 16
304#define ASC_MAX_SCSI2_QNG 32
305#define ASC_TAG_CODE_MASK 0x23
306#define ASC_STOP_REQ_RISC_STOP 0x01
307#define ASC_STOP_ACK_RISC_STOP 0x03
308#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
309#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
310#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
311#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
312#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
313#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
314#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
315#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
316#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
317#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
318
319typedef struct asc_scsiq_1 {
27c868c2
MW
320 uchar status;
321 uchar q_no;
322 uchar cntl;
323 uchar sg_queue_cnt;
324 uchar target_id;
325 uchar target_lun;
326 ASC_PADDR data_addr;
327 ASC_DCNT data_cnt;
328 ASC_PADDR sense_addr;
329 uchar sense_len;
330 uchar extra_bytes;
1da177e4
LT
331} ASC_SCSIQ_1;
332
333typedef struct asc_scsiq_2 {
27c868c2
MW
334 ASC_VADDR srb_ptr;
335 uchar target_ix;
336 uchar flag;
337 uchar cdb_len;
338 uchar tag_code;
339 ushort vm_id;
1da177e4
LT
340} ASC_SCSIQ_2;
341
342typedef struct asc_scsiq_3 {
27c868c2
MW
343 uchar done_stat;
344 uchar host_stat;
345 uchar scsi_stat;
346 uchar scsi_msg;
1da177e4
LT
347} ASC_SCSIQ_3;
348
349typedef struct asc_scsiq_4 {
27c868c2
MW
350 uchar cdb[ASC_MAX_CDB_LEN];
351 uchar y_first_sg_list_qp;
352 uchar y_working_sg_qp;
353 uchar y_working_sg_ix;
354 uchar y_res;
355 ushort x_req_count;
356 ushort x_reconnect_rtn;
357 ASC_PADDR x_saved_data_addr;
358 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
359} ASC_SCSIQ_4;
360
361typedef struct asc_q_done_info {
27c868c2
MW
362 ASC_SCSIQ_2 d2;
363 ASC_SCSIQ_3 d3;
364 uchar q_status;
365 uchar q_no;
366 uchar cntl;
367 uchar sense_len;
368 uchar extra_bytes;
369 uchar res;
370 ASC_DCNT remain_bytes;
1da177e4
LT
371} ASC_QDONE_INFO;
372
373typedef struct asc_sg_list {
27c868c2
MW
374 ASC_PADDR addr;
375 ASC_DCNT bytes;
1da177e4
LT
376} ASC_SG_LIST;
377
378typedef struct asc_sg_head {
27c868c2
MW
379 ushort entry_cnt;
380 ushort queue_cnt;
381 ushort entry_to_copy;
382 ushort res;
05848b6e 383 ASC_SG_LIST sg_list[0];
1da177e4
LT
384} ASC_SG_HEAD;
385
1da177e4 386typedef struct asc_scsi_q {
27c868c2
MW
387 ASC_SCSIQ_1 q1;
388 ASC_SCSIQ_2 q2;
389 uchar *cdbptr;
390 ASC_SG_HEAD *sg_head;
391 ushort remain_sg_entry_cnt;
392 ushort next_sg_index;
1da177e4
LT
393} ASC_SCSI_Q;
394
395typedef struct asc_scsi_req_q {
27c868c2
MW
396 ASC_SCSIQ_1 r1;
397 ASC_SCSIQ_2 r2;
398 uchar *cdbptr;
399 ASC_SG_HEAD *sg_head;
400 uchar *sense_ptr;
401 ASC_SCSIQ_3 r3;
402 uchar cdb[ASC_MAX_CDB_LEN];
403 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
404} ASC_SCSI_REQ_Q;
405
406typedef struct asc_scsi_bios_req_q {
27c868c2
MW
407 ASC_SCSIQ_1 r1;
408 ASC_SCSIQ_2 r2;
409 uchar *cdbptr;
410 ASC_SG_HEAD *sg_head;
411 uchar *sense_ptr;
412 ASC_SCSIQ_3 r3;
413 uchar cdb[ASC_MAX_CDB_LEN];
414 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
415} ASC_SCSI_BIOS_REQ_Q;
416
417typedef struct asc_risc_q {
27c868c2
MW
418 uchar fwd;
419 uchar bwd;
420 ASC_SCSIQ_1 i1;
421 ASC_SCSIQ_2 i2;
422 ASC_SCSIQ_3 i3;
423 ASC_SCSIQ_4 i4;
1da177e4
LT
424} ASC_RISC_Q;
425
426typedef struct asc_sg_list_q {
27c868c2
MW
427 uchar seq_no;
428 uchar q_no;
429 uchar cntl;
430 uchar sg_head_qp;
431 uchar sg_list_cnt;
432 uchar sg_cur_list_cnt;
1da177e4
LT
433} ASC_SG_LIST_Q;
434
435typedef struct asc_risc_sg_list_q {
27c868c2
MW
436 uchar fwd;
437 uchar bwd;
438 ASC_SG_LIST_Q sg;
439 ASC_SG_LIST sg_list[7];
1da177e4
LT
440} ASC_RISC_SG_LIST_Q;
441
1da177e4 442#define ASCQ_ERR_Q_STATUS 0x0D
1da177e4
LT
443#define ASCQ_ERR_CUR_QNG 0x17
444#define ASCQ_ERR_SG_Q_LINKS 0x18
1da177e4
LT
445#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
446#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
447#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1da177e4
LT
448
449/*
450 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
451 */
452#define ASC_WARN_NO_ERROR 0x0000
453#define ASC_WARN_IO_PORT_ROTATE 0x0001
454#define ASC_WARN_EEPROM_CHKSUM 0x0002
455#define ASC_WARN_IRQ_MODIFIED 0x0004
456#define ASC_WARN_AUTO_CONFIG 0x0008
457#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
458#define ASC_WARN_EEPROM_RECOVER 0x0020
459#define ASC_WARN_CFG_MSW_RECOVER 0x0040
1da177e4
LT
460
461/*
462 * Error code values are set in ASC_DVC_VAR 'err_code'.
463 */
464#define ASC_IERR_WRITE_EEPROM 0x0001
465#define ASC_IERR_MCODE_CHKSUM 0x0002
466#define ASC_IERR_SET_PC_ADDR 0x0004
467#define ASC_IERR_START_STOP_CHIP 0x0008
468#define ASC_IERR_IRQ_NO 0x0010
469#define ASC_IERR_SET_IRQ_NO 0x0020
470#define ASC_IERR_CHIP_VERSION 0x0040
471#define ASC_IERR_SET_SCSI_ID 0x0080
472#define ASC_IERR_GET_PHY_ADDR 0x0100
473#define ASC_IERR_BAD_SIGNATURE 0x0200
474#define ASC_IERR_NO_BUS_TYPE 0x0400
475#define ASC_IERR_SCAM 0x0800
476#define ASC_IERR_SET_SDTR 0x1000
477#define ASC_IERR_RW_LRAM 0x8000
478
1da177e4
LT
479#define ASC_MAX_IRQ_NO 15
480#define ASC_MIN_IRQ_NO 10
1da177e4
LT
481#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
482#define ASC_MIN_TAG_Q_PER_DVC (0x04)
95c9f162 483#define ASC_MIN_FREE_Q (0x02)
1da177e4
LT
484#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
485#define ASC_MAX_TOTAL_QNG 240
486#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
487#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
488#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
489#define ASC_MAX_INRAM_TAG_QNG 16
1da177e4 490#define ASC_IOADR_GAP 0x10
1da177e4
LT
491#define ASC_MAX_SYN_XFER_NO 16
492#define ASC_SYN_MAX_OFFSET 0x0F
493#define ASC_DEF_SDTR_OFFSET 0x0F
1da177e4
LT
494#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
495#define SYN_XFER_NS_0 25
496#define SYN_XFER_NS_1 30
497#define SYN_XFER_NS_2 35
498#define SYN_XFER_NS_3 40
499#define SYN_XFER_NS_4 50
500#define SYN_XFER_NS_5 60
501#define SYN_XFER_NS_6 70
502#define SYN_XFER_NS_7 85
503#define SYN_ULTRA_XFER_NS_0 12
504#define SYN_ULTRA_XFER_NS_1 19
505#define SYN_ULTRA_XFER_NS_2 25
506#define SYN_ULTRA_XFER_NS_3 32
507#define SYN_ULTRA_XFER_NS_4 38
508#define SYN_ULTRA_XFER_NS_5 44
509#define SYN_ULTRA_XFER_NS_6 50
510#define SYN_ULTRA_XFER_NS_7 57
511#define SYN_ULTRA_XFER_NS_8 63
512#define SYN_ULTRA_XFER_NS_9 69
513#define SYN_ULTRA_XFER_NS_10 75
514#define SYN_ULTRA_XFER_NS_11 82
515#define SYN_ULTRA_XFER_NS_12 88
516#define SYN_ULTRA_XFER_NS_13 94
517#define SYN_ULTRA_XFER_NS_14 100
518#define SYN_ULTRA_XFER_NS_15 107
519
520typedef struct ext_msg {
27c868c2
MW
521 uchar msg_type;
522 uchar msg_len;
523 uchar msg_req;
524 union {
525 struct {
526 uchar sdtr_xfer_period;
527 uchar sdtr_req_ack_offset;
528 } sdtr;
529 struct {
530 uchar wdtr_width;
531 } wdtr;
532 struct {
533 uchar mdp_b3;
534 uchar mdp_b2;
535 uchar mdp_b1;
536 uchar mdp_b0;
537 } mdp;
538 } u_ext_msg;
539 uchar res;
1da177e4
LT
540} EXT_MSG;
541
542#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
543#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
544#define wdtr_width u_ext_msg.wdtr.wdtr_width
545#define mdp_b3 u_ext_msg.mdp_b3
546#define mdp_b2 u_ext_msg.mdp_b2
547#define mdp_b1 u_ext_msg.mdp_b1
548#define mdp_b0 u_ext_msg.mdp_b0
549
550typedef struct asc_dvc_cfg {
27c868c2
MW
551 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
552 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
553 ASC_SCSI_BIT_ID_TYPE disc_enable;
554 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
555 uchar chip_scsi_id;
556 uchar isa_dma_speed;
557 uchar isa_dma_channel;
558 uchar chip_version;
559 ushort lib_serial_no;
560 ushort lib_version;
561 ushort mcode_date;
562 ushort mcode_version;
563 uchar max_tag_qng[ASC_MAX_TID + 1];
564 uchar *overrun_buf;
565 uchar sdtr_period_offset[ASC_MAX_TID + 1];
27c868c2 566 uchar adapter_info[6];
1da177e4
LT
567} ASC_DVC_CFG;
568
569#define ASC_DEF_DVC_CNTL 0xFFFF
570#define ASC_DEF_CHIP_SCSI_ID 7
571#define ASC_DEF_ISA_DMA_SPEED 4
1da177e4
LT
572#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
573#define ASC_INIT_STATE_END_GET_CFG 0x0002
574#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
575#define ASC_INIT_STATE_END_SET_CFG 0x0008
576#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
577#define ASC_INIT_STATE_END_LOAD_MC 0x0020
578#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
579#define ASC_INIT_STATE_END_INQUIRY 0x0080
580#define ASC_INIT_RESET_SCSI_DONE 0x0100
581#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
582#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
583#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
584#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
585#define ASC_MIN_TAGGED_CMD 7
586#define ASC_MAX_SCSI_RESET_WAIT 30
587
27c868c2 588struct asc_dvc_var; /* Forward Declaration. */
1da177e4 589
1da177e4 590typedef struct asc_dvc_var {
27c868c2
MW
591 PortAddr iop_base;
592 ushort err_code;
593 ushort dvc_cntl;
594 ushort bug_fix_cntl;
595 ushort bus_type;
27c868c2
MW
596 ASC_SCSI_BIT_ID_TYPE init_sdtr;
597 ASC_SCSI_BIT_ID_TYPE sdtr_done;
598 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
599 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
600 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
601 ASC_SCSI_BIT_ID_TYPE start_motor;
602 uchar scsi_reset_wait;
603 uchar chip_no;
604 char is_in_int;
605 uchar max_total_qng;
606 uchar cur_total_qng;
607 uchar in_critical_cnt;
608 uchar irq_no;
609 uchar last_q_shortage;
610 ushort init_state;
611 uchar cur_dvc_qng[ASC_MAX_TID + 1];
612 uchar max_dvc_qng[ASC_MAX_TID + 1];
613 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
614 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
615 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
616 ASC_DVC_CFG *cfg;
617 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
618 char redo_scam;
619 ushort res2;
620 uchar dos_int13_table[ASC_MAX_TID + 1];
621 ASC_DCNT max_dma_count;
622 ASC_SCSI_BIT_ID_TYPE no_scam;
623 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
624 uchar max_sdtr_index;
625 uchar host_init_sdtr_index;
626 struct asc_board *drv_ptr;
627 ASC_DCNT uc_break;
1da177e4
LT
628} ASC_DVC_VAR;
629
630typedef struct asc_dvc_inq_info {
27c868c2 631 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
632} ASC_DVC_INQ_INFO;
633
634typedef struct asc_cap_info {
27c868c2
MW
635 ASC_DCNT lba;
636 ASC_DCNT blk_size;
1da177e4
LT
637} ASC_CAP_INFO;
638
639typedef struct asc_cap_info_array {
27c868c2 640 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
641} ASC_CAP_INFO_ARRAY;
642
643#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
644#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
645#define ASC_CNTL_INITIATOR (ushort)0x0001
646#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
647#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
648#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
649#define ASC_CNTL_NO_SCAM (ushort)0x0010
650#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
651#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
652#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
653#define ASC_CNTL_RESET_SCSI (ushort)0x0200
654#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
655#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
656#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
657#define ASC_CNTL_BURST_MODE (ushort)0x2000
658#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
659#define ASC_EEP_DVC_CFG_BEG_VL 2
660#define ASC_EEP_MAX_DVC_ADDR_VL 15
661#define ASC_EEP_DVC_CFG_BEG 32
662#define ASC_EEP_MAX_DVC_ADDR 45
1da177e4 663#define ASC_EEP_MAX_RETRY 20
1da177e4
LT
664
665/*
666 * These macros keep the chip SCSI id and ISA DMA speed
667 * bitfields in board order. C bitfields aren't portable
668 * between big and little-endian platforms so they are
669 * not used.
670 */
671
672#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
673#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
674#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
675 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
676#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
677 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
678
679typedef struct asceep_config {
27c868c2
MW
680 ushort cfg_lsw;
681 ushort cfg_msw;
682 uchar init_sdtr;
683 uchar disc_enable;
684 uchar use_cmd_qng;
685 uchar start_motor;
686 uchar max_total_qng;
687 uchar max_tag_qng;
688 uchar bios_scan;
689 uchar power_up_wait;
690 uchar no_scam;
691 uchar id_speed; /* low order 4 bits is chip scsi id */
692 /* high order 4 bits is isa dma speed */
693 uchar dos_int13_table[ASC_MAX_TID + 1];
694 uchar adapter_info[6];
695 ushort cntl;
696 ushort chksum;
1da177e4
LT
697} ASCEEP_CONFIG;
698
1da177e4
LT
699#define ASC_EEP_CMD_READ 0x80
700#define ASC_EEP_CMD_WRITE 0x40
701#define ASC_EEP_CMD_WRITE_ABLE 0x30
702#define ASC_EEP_CMD_WRITE_DISABLE 0x00
703#define ASC_OVERRUN_BSIZE 0x00000048UL
1da177e4
LT
704#define ASCV_MSGOUT_BEG 0x0000
705#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
706#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
707#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
708#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
709#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
710#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
711#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
712#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
713#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
714#define ASCV_BREAK_ADDR (ushort)0x0028
715#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
716#define ASCV_BREAK_CONTROL (ushort)0x002C
717#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
718
719#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
720#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
721#define ASCV_MCODE_SIZE_W (ushort)0x0034
722#define ASCV_STOP_CODE_B (ushort)0x0036
723#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
724#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
725#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
726#define ASCV_HALTCODE_W (ushort)0x0040
727#define ASCV_CHKSUM_W (ushort)0x0042
728#define ASCV_MC_DATE_W (ushort)0x0044
729#define ASCV_MC_VER_W (ushort)0x0046
730#define ASCV_NEXTRDY_B (ushort)0x0048
731#define ASCV_DONENEXT_B (ushort)0x0049
732#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
733#define ASCV_SCSIBUSY_B (ushort)0x004B
734#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
735#define ASCV_CURCDB_B (ushort)0x004D
736#define ASCV_RCLUN_B (ushort)0x004E
737#define ASCV_BUSY_QHEAD_B (ushort)0x004F
738#define ASCV_DISC1_QHEAD_B (ushort)0x0050
739#define ASCV_DISC_ENABLE_B (ushort)0x0052
740#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
741#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
742#define ASCV_MCODE_CNTL_B (ushort)0x0056
743#define ASCV_NULL_TARGET_B (ushort)0x0057
744#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
745#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
746#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
747#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
748#define ASCV_HOST_FLAG_B (ushort)0x005D
749#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
750#define ASCV_VER_SERIAL_B (ushort)0x0065
751#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
752#define ASCV_WTM_FLAG_B (ushort)0x0068
753#define ASCV_RISC_FLAG_B (ushort)0x006A
754#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
755#define ASC_HOST_FLAG_IN_ISR 0x01
756#define ASC_HOST_FLAG_ACK_INT 0x02
757#define ASC_RISC_FLAG_GEN_INT 0x01
758#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
759#define IOP_CTRL (0x0F)
760#define IOP_STATUS (0x0E)
761#define IOP_INT_ACK IOP_STATUS
762#define IOP_REG_IFC (0x0D)
763#define IOP_SYN_OFFSET (0x0B)
764#define IOP_EXTRA_CONTROL (0x0D)
765#define IOP_REG_PC (0x0C)
766#define IOP_RAM_ADDR (0x0A)
767#define IOP_RAM_DATA (0x08)
768#define IOP_EEP_DATA (0x06)
769#define IOP_EEP_CMD (0x07)
770#define IOP_VERSION (0x03)
771#define IOP_CONFIG_HIGH (0x04)
772#define IOP_CONFIG_LOW (0x02)
773#define IOP_SIG_BYTE (0x01)
774#define IOP_SIG_WORD (0x00)
775#define IOP_REG_DC1 (0x0E)
776#define IOP_REG_DC0 (0x0C)
777#define IOP_REG_SB (0x0B)
778#define IOP_REG_DA1 (0x0A)
779#define IOP_REG_DA0 (0x08)
780#define IOP_REG_SC (0x09)
781#define IOP_DMA_SPEED (0x07)
782#define IOP_REG_FLAG (0x07)
783#define IOP_FIFO_H (0x06)
784#define IOP_FIFO_L (0x04)
785#define IOP_REG_ID (0x05)
786#define IOP_REG_QP (0x03)
787#define IOP_REG_IH (0x02)
788#define IOP_REG_IX (0x01)
789#define IOP_REG_AX (0x00)
790#define IFC_REG_LOCK (0x00)
791#define IFC_REG_UNLOCK (0x09)
792#define IFC_WR_EN_FILTER (0x10)
793#define IFC_RD_NO_EEPROM (0x10)
794#define IFC_SLEW_RATE (0x20)
795#define IFC_ACT_NEG (0x40)
796#define IFC_INP_FILTER (0x80)
797#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
798#define SC_SEL (uchar)(0x80)
799#define SC_BSY (uchar)(0x40)
800#define SC_ACK (uchar)(0x20)
801#define SC_REQ (uchar)(0x10)
802#define SC_ATN (uchar)(0x08)
803#define SC_IO (uchar)(0x04)
804#define SC_CD (uchar)(0x02)
805#define SC_MSG (uchar)(0x01)
806#define SEC_SCSI_CTL (uchar)(0x80)
807#define SEC_ACTIVE_NEGATE (uchar)(0x40)
808#define SEC_SLEW_RATE (uchar)(0x20)
809#define SEC_ENABLE_FILTER (uchar)(0x10)
810#define ASC_HALT_EXTMSG_IN (ushort)0x8000
811#define ASC_HALT_CHK_CONDITION (ushort)0x8100
812#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
813#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
814#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
815#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
816#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
817#define ASC_MAX_QNO 0xF8
818#define ASC_DATA_SEC_BEG (ushort)0x0080
819#define ASC_DATA_SEC_END (ushort)0x0080
820#define ASC_CODE_SEC_BEG (ushort)0x0080
821#define ASC_CODE_SEC_END (ushort)0x0080
822#define ASC_QADR_BEG (0x4000)
823#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
824#define ASC_QADR_END (ushort)0x7FFF
825#define ASC_QLAST_ADR (ushort)0x7FC0
826#define ASC_QBLK_SIZE 0x40
827#define ASC_BIOS_DATA_QBEG 0xF8
828#define ASC_MIN_ACTIVE_QNO 0x01
829#define ASC_QLINK_END 0xFF
830#define ASC_EEPROM_WORDS 0x10
831#define ASC_MAX_MGS_LEN 0x10
832#define ASC_BIOS_ADDR_DEF 0xDC00
833#define ASC_BIOS_SIZE 0x3800
834#define ASC_BIOS_RAM_OFF 0x3800
835#define ASC_BIOS_RAM_SIZE 0x800
836#define ASC_BIOS_MIN_ADDR 0xC000
837#define ASC_BIOS_MAX_ADDR 0xEC00
838#define ASC_BIOS_BANK_SIZE 0x0400
839#define ASC_MCODE_START_ADDR 0x0080
840#define ASC_CFG0_HOST_INT_ON 0x0020
841#define ASC_CFG0_BIOS_ON 0x0040
842#define ASC_CFG0_VERA_BURST_ON 0x0080
843#define ASC_CFG0_SCSI_PARITY_ON 0x0800
844#define ASC_CFG1_SCSI_TARGET_ON 0x0080
845#define ASC_CFG1_LRAM_8BITS_ON 0x0800
846#define ASC_CFG_MSW_CLR_MASK 0x3080
847#define CSW_TEST1 (ASC_CS_TYPE)0x8000
848#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
849#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
850#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
851#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
852#define CSW_TEST2 (ASC_CS_TYPE)0x0400
853#define CSW_TEST3 (ASC_CS_TYPE)0x0200
854#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
855#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
856#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
857#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
858#define CSW_HALTED (ASC_CS_TYPE)0x0010
859#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
860#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
861#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
862#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
863#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
864#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
865#define CIW_TEST1 (ASC_CS_TYPE)0x0200
866#define CIW_TEST2 (ASC_CS_TYPE)0x0400
867#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
868#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
869#define CC_CHIP_RESET (uchar)0x80
870#define CC_SCSI_RESET (uchar)0x40
871#define CC_HALT (uchar)0x20
872#define CC_SINGLE_STEP (uchar)0x10
873#define CC_DMA_ABLE (uchar)0x08
874#define CC_TEST (uchar)0x04
875#define CC_BANK_ONE (uchar)0x02
876#define CC_DIAG (uchar)0x01
877#define ASC_1000_ID0W 0x04C1
878#define ASC_1000_ID0W_FIX 0x00C1
879#define ASC_1000_ID1B 0x25
1da177e4 880#define ASC_EISA_REV_IOP_MASK (0x0C83)
1da177e4
LT
881#define ASC_EISA_CFG_IOP_MASK (0x0C86)
882#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1da177e4
LT
883#define INS_HALTINT (ushort)0x6281
884#define INS_HALT (ushort)0x6280
885#define INS_SINT (ushort)0x6200
886#define INS_RFLAG_WTM (ushort)0x7380
887#define ASC_MC_SAVE_CODE_WSIZE 0x500
888#define ASC_MC_SAVE_DATA_WSIZE 0x40
889
890typedef struct asc_mc_saved {
27c868c2
MW
891 ushort data[ASC_MC_SAVE_DATA_WSIZE];
892 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
893} ASC_MC_SAVED;
894
895#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
896#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
897#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
898#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
899#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
900#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
901#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
902#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
903#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
904#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
51219358
MW
905#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
906#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
907#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
908#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
1da177e4
LT
909#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
910#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
911#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
912#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
913#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
914#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
915#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
916#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
917#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
918#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
919#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
920#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
921#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
922#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
923#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
924#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
925#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
926#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
927#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
928#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
929#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
930#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
931#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
932#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
933#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
934#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
935#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
936#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
937#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
938#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
939#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
940#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
941#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
942#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
943#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
944#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
945#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
946#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
947#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
948#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
949#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
950#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
951#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
952#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
953#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
954#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
955#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
956#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
957#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
958#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
959#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
960#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
961#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
962#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
963
1da177e4
LT
964#define ADV_LIB_VERSION_MAJOR 5
965#define ADV_LIB_VERSION_MINOR 14
966
967/*
968 * Define Adv Library required special types.
969 */
970
971/*
972 * Portable Data Types
973 *
974 * Any instance where a 32-bit long or pointer type is assumed
975 * for precision or HW defined structures, the following define
976 * types must be used. In Linux the char, short, and int types
977 * are all consistent at 8, 16, and 32 bits respectively. Pointers
978 * and long types are 64 bits on Alpha and UltraSPARC.
979 */
27c868c2
MW
980#define ADV_PADDR __u32 /* Physical address data type. */
981#define ADV_VADDR __u32 /* Virtual address data type. */
982#define ADV_DCNT __u32 /* Unsigned Data count type. */
983#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
984
985/*
986 * These macros are used to convert a virtual address to a
987 * 32-bit value. This currently can be used on Linux Alpha
988 * which uses 64-bit virtual address but a 32-bit bus address.
989 * This is likely to break in the future, but doing this now
990 * will give us time to change the HW and FW to handle 64-bit
991 * addresses.
992 */
993#define ADV_VADDR_TO_U32 virt_to_bus
994#define ADV_U32_TO_VADDR bus_to_virt
995
27c868c2 996#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
997
998/*
999 * Define Adv Library required memory access macros.
1000 */
1001#define ADV_MEM_READB(addr) readb(addr)
1002#define ADV_MEM_READW(addr) readw(addr)
1003#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1004#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1005#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1006
1007#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1008
1da177e4
LT
1009/*
1010 * Define total number of simultaneous maximum element scatter-gather
1011 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1012 * maximum number of outstanding commands per wide host adapter. Each
1013 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1014 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1015 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1016 * structures or 255 scatter-gather elements.
1017 *
1018 */
1019#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1020
1021/*
1022 * Define Adv Library required maximum number of scatter-gather
1023 * elements per request.
1024 */
1025#define ADV_MAX_SG_LIST 255
1026
1027/* Number of SG blocks needed. */
1028#define ADV_NUM_SG_BLOCK \
1029 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1030
1031/* Total contiguous memory needed for SG blocks. */
1032#define ADV_SG_TOTAL_MEM_SIZE \
1033 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1034
1035#define ADV_PAGE_SIZE PAGE_SIZE
1036
1037#define ADV_NUM_PAGE_CROSSING \
1038 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1039
1da177e4
LT
1040#define ADV_EEP_DVC_CFG_BEGIN (0x00)
1041#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 1042#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
1043#define ADV_EEP_MAX_WORD_ADDR (0x1E)
1044
1045#define ADV_EEP_DELAY_MS 100
1046
27c868c2
MW
1047#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1048#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
1049/*
1050 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1051 * For later ICs Bit 13 controls whether the CIS (Card Information
1052 * Service Section) is loaded from EEPROM.
1053 */
27c868c2
MW
1054#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1055#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
1056/*
1057 * ASC38C1600 Bit 11
1058 *
1059 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1060 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1061 * Function 0 will specify INT B.
1062 *
1063 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1064 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1065 * Function 1 will specify INT A.
1066 */
27c868c2
MW
1067#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1068
1069typedef struct adveep_3550_config {
1070 /* Word Offset, Description */
1071
1072 ushort cfg_lsw; /* 00 power up initialization */
1073 /* bit 13 set - Term Polarity Control */
1074 /* bit 14 set - BIOS Enable */
1075 /* bit 15 set - Big Endian Mode */
1076 ushort cfg_msw; /* 01 unused */
1077 ushort disc_enable; /* 02 disconnect enable */
1078 ushort wdtr_able; /* 03 Wide DTR able */
1079 ushort sdtr_able; /* 04 Synchronous DTR able */
1080 ushort start_motor; /* 05 send start up motor */
1081 ushort tagqng_able; /* 06 tag queuing able */
1082 ushort bios_scan; /* 07 BIOS device control */
1083 ushort scam_tolerant; /* 08 no scam */
1084
1085 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1086 uchar bios_boot_delay; /* power up wait */
1087
1088 uchar scsi_reset_delay; /* 10 reset delay */
1089 uchar bios_id_lun; /* first boot device scsi id & lun */
1090 /* high nibble is lun */
1091 /* low nibble is scsi id */
1092
1093 uchar termination; /* 11 0 - automatic */
1094 /* 1 - low off / high off */
1095 /* 2 - low off / high on */
1096 /* 3 - low on / high on */
1097 /* There is no low on / high off */
1098
1099 uchar reserved1; /* reserved byte (not used) */
1100
1101 ushort bios_ctrl; /* 12 BIOS control bits */
1102 /* bit 0 BIOS don't act as initiator. */
1103 /* bit 1 BIOS > 1 GB support */
1104 /* bit 2 BIOS > 2 Disk Support */
1105 /* bit 3 BIOS don't support removables */
1106 /* bit 4 BIOS support bootable CD */
1107 /* bit 5 BIOS scan enabled */
1108 /* bit 6 BIOS support multiple LUNs */
1109 /* bit 7 BIOS display of message */
1110 /* bit 8 SCAM disabled */
1111 /* bit 9 Reset SCSI bus during init. */
1112 /* bit 10 */
1113 /* bit 11 No verbose initialization. */
1114 /* bit 12 SCSI parity enabled */
1115 /* bit 13 */
1116 /* bit 14 */
1117 /* bit 15 */
1118 ushort ultra_able; /* 13 ULTRA speed able */
1119 ushort reserved2; /* 14 reserved */
1120 uchar max_host_qng; /* 15 maximum host queuing */
1121 uchar max_dvc_qng; /* maximum per device queuing */
1122 ushort dvc_cntl; /* 16 control bit for driver */
1123 ushort bug_fix; /* 17 control bit for bug fix */
1124 ushort serial_number_word1; /* 18 Board serial number word 1 */
1125 ushort serial_number_word2; /* 19 Board serial number word 2 */
1126 ushort serial_number_word3; /* 20 Board serial number word 3 */
1127 ushort check_sum; /* 21 EEP check sum */
1128 uchar oem_name[16]; /* 22 OEM name */
1129 ushort dvc_err_code; /* 30 last device driver error code */
1130 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1131 ushort adv_err_addr; /* 32 last uc error address */
1132 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1133 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1134 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1135 ushort num_of_err; /* 36 number of error */
1da177e4
LT
1136} ADVEEP_3550_CONFIG;
1137
27c868c2
MW
1138typedef struct adveep_38C0800_config {
1139 /* Word Offset, Description */
1140
1141 ushort cfg_lsw; /* 00 power up initialization */
1142 /* bit 13 set - Load CIS */
1143 /* bit 14 set - BIOS Enable */
1144 /* bit 15 set - Big Endian Mode */
1145 ushort cfg_msw; /* 01 unused */
1146 ushort disc_enable; /* 02 disconnect enable */
1147 ushort wdtr_able; /* 03 Wide DTR able */
1148 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1149 ushort start_motor; /* 05 send start up motor */
1150 ushort tagqng_able; /* 06 tag queuing able */
1151 ushort bios_scan; /* 07 BIOS device control */
1152 ushort scam_tolerant; /* 08 no scam */
1153
1154 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1155 uchar bios_boot_delay; /* power up wait */
1156
1157 uchar scsi_reset_delay; /* 10 reset delay */
1158 uchar bios_id_lun; /* first boot device scsi id & lun */
1159 /* high nibble is lun */
1160 /* low nibble is scsi id */
1161
1162 uchar termination_se; /* 11 0 - automatic */
1163 /* 1 - low off / high off */
1164 /* 2 - low off / high on */
1165 /* 3 - low on / high on */
1166 /* There is no low on / high off */
1167
1168 uchar termination_lvd; /* 11 0 - automatic */
1169 /* 1 - low off / high off */
1170 /* 2 - low off / high on */
1171 /* 3 - low on / high on */
1172 /* There is no low on / high off */
1173
1174 ushort bios_ctrl; /* 12 BIOS control bits */
1175 /* bit 0 BIOS don't act as initiator. */
1176 /* bit 1 BIOS > 1 GB support */
1177 /* bit 2 BIOS > 2 Disk Support */
1178 /* bit 3 BIOS don't support removables */
1179 /* bit 4 BIOS support bootable CD */
1180 /* bit 5 BIOS scan enabled */
1181 /* bit 6 BIOS support multiple LUNs */
1182 /* bit 7 BIOS display of message */
1183 /* bit 8 SCAM disabled */
1184 /* bit 9 Reset SCSI bus during init. */
1185 /* bit 10 */
1186 /* bit 11 No verbose initialization. */
1187 /* bit 12 SCSI parity enabled */
1188 /* bit 13 */
1189 /* bit 14 */
1190 /* bit 15 */
1191 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1192 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1193 uchar max_host_qng; /* 15 maximum host queueing */
1194 uchar max_dvc_qng; /* maximum per device queuing */
1195 ushort dvc_cntl; /* 16 control bit for driver */
1196 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1197 ushort serial_number_word1; /* 18 Board serial number word 1 */
1198 ushort serial_number_word2; /* 19 Board serial number word 2 */
1199 ushort serial_number_word3; /* 20 Board serial number word 3 */
1200 ushort check_sum; /* 21 EEP check sum */
1201 uchar oem_name[16]; /* 22 OEM name */
1202 ushort dvc_err_code; /* 30 last device driver error code */
1203 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1204 ushort adv_err_addr; /* 32 last uc error address */
1205 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1206 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1207 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1208 ushort reserved36; /* 36 reserved */
1209 ushort reserved37; /* 37 reserved */
1210 ushort reserved38; /* 38 reserved */
1211 ushort reserved39; /* 39 reserved */
1212 ushort reserved40; /* 40 reserved */
1213 ushort reserved41; /* 41 reserved */
1214 ushort reserved42; /* 42 reserved */
1215 ushort reserved43; /* 43 reserved */
1216 ushort reserved44; /* 44 reserved */
1217 ushort reserved45; /* 45 reserved */
1218 ushort reserved46; /* 46 reserved */
1219 ushort reserved47; /* 47 reserved */
1220 ushort reserved48; /* 48 reserved */
1221 ushort reserved49; /* 49 reserved */
1222 ushort reserved50; /* 50 reserved */
1223 ushort reserved51; /* 51 reserved */
1224 ushort reserved52; /* 52 reserved */
1225 ushort reserved53; /* 53 reserved */
1226 ushort reserved54; /* 54 reserved */
1227 ushort reserved55; /* 55 reserved */
1228 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1229 ushort cisprt_msw; /* 57 CIS PTR MSW */
1230 ushort subsysvid; /* 58 SubSystem Vendor ID */
1231 ushort subsysid; /* 59 SubSystem ID */
1232 ushort reserved60; /* 60 reserved */
1233 ushort reserved61; /* 61 reserved */
1234 ushort reserved62; /* 62 reserved */
1235 ushort reserved63; /* 63 reserved */
1da177e4
LT
1236} ADVEEP_38C0800_CONFIG;
1237
27c868c2
MW
1238typedef struct adveep_38C1600_config {
1239 /* Word Offset, Description */
1240
1241 ushort cfg_lsw; /* 00 power up initialization */
1242 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1243 /* clear - Func. 0 INTA, Func. 1 INTB */
1244 /* bit 13 set - Load CIS */
1245 /* bit 14 set - BIOS Enable */
1246 /* bit 15 set - Big Endian Mode */
1247 ushort cfg_msw; /* 01 unused */
1248 ushort disc_enable; /* 02 disconnect enable */
1249 ushort wdtr_able; /* 03 Wide DTR able */
1250 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1251 ushort start_motor; /* 05 send start up motor */
1252 ushort tagqng_able; /* 06 tag queuing able */
1253 ushort bios_scan; /* 07 BIOS device control */
1254 ushort scam_tolerant; /* 08 no scam */
1255
1256 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1257 uchar bios_boot_delay; /* power up wait */
1258
1259 uchar scsi_reset_delay; /* 10 reset delay */
1260 uchar bios_id_lun; /* first boot device scsi id & lun */
1261 /* high nibble is lun */
1262 /* low nibble is scsi id */
1263
1264 uchar termination_se; /* 11 0 - automatic */
1265 /* 1 - low off / high off */
1266 /* 2 - low off / high on */
1267 /* 3 - low on / high on */
1268 /* There is no low on / high off */
1269
1270 uchar termination_lvd; /* 11 0 - automatic */
1271 /* 1 - low off / high off */
1272 /* 2 - low off / high on */
1273 /* 3 - low on / high on */
1274 /* There is no low on / high off */
1275
1276 ushort bios_ctrl; /* 12 BIOS control bits */
1277 /* bit 0 BIOS don't act as initiator. */
1278 /* bit 1 BIOS > 1 GB support */
1279 /* bit 2 BIOS > 2 Disk Support */
1280 /* bit 3 BIOS don't support removables */
1281 /* bit 4 BIOS support bootable CD */
1282 /* bit 5 BIOS scan enabled */
1283 /* bit 6 BIOS support multiple LUNs */
1284 /* bit 7 BIOS display of message */
1285 /* bit 8 SCAM disabled */
1286 /* bit 9 Reset SCSI bus during init. */
1287 /* bit 10 Basic Integrity Checking disabled */
1288 /* bit 11 No verbose initialization. */
1289 /* bit 12 SCSI parity enabled */
1290 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1291 /* bit 14 */
1292 /* bit 15 */
1293 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1294 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1295 uchar max_host_qng; /* 15 maximum host queueing */
1296 uchar max_dvc_qng; /* maximum per device queuing */
1297 ushort dvc_cntl; /* 16 control bit for driver */
1298 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1299 ushort serial_number_word1; /* 18 Board serial number word 1 */
1300 ushort serial_number_word2; /* 19 Board serial number word 2 */
1301 ushort serial_number_word3; /* 20 Board serial number word 3 */
1302 ushort check_sum; /* 21 EEP check sum */
1303 uchar oem_name[16]; /* 22 OEM name */
1304 ushort dvc_err_code; /* 30 last device driver error code */
1305 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1306 ushort adv_err_addr; /* 32 last uc error address */
1307 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1308 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1309 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1310 ushort reserved36; /* 36 reserved */
1311 ushort reserved37; /* 37 reserved */
1312 ushort reserved38; /* 38 reserved */
1313 ushort reserved39; /* 39 reserved */
1314 ushort reserved40; /* 40 reserved */
1315 ushort reserved41; /* 41 reserved */
1316 ushort reserved42; /* 42 reserved */
1317 ushort reserved43; /* 43 reserved */
1318 ushort reserved44; /* 44 reserved */
1319 ushort reserved45; /* 45 reserved */
1320 ushort reserved46; /* 46 reserved */
1321 ushort reserved47; /* 47 reserved */
1322 ushort reserved48; /* 48 reserved */
1323 ushort reserved49; /* 49 reserved */
1324 ushort reserved50; /* 50 reserved */
1325 ushort reserved51; /* 51 reserved */
1326 ushort reserved52; /* 52 reserved */
1327 ushort reserved53; /* 53 reserved */
1328 ushort reserved54; /* 54 reserved */
1329 ushort reserved55; /* 55 reserved */
1330 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1331 ushort cisprt_msw; /* 57 CIS PTR MSW */
1332 ushort subsysvid; /* 58 SubSystem Vendor ID */
1333 ushort subsysid; /* 59 SubSystem ID */
1334 ushort reserved60; /* 60 reserved */
1335 ushort reserved61; /* 61 reserved */
1336 ushort reserved62; /* 62 reserved */
1337 ushort reserved63; /* 63 reserved */
1da177e4
LT
1338} ADVEEP_38C1600_CONFIG;
1339
1340/*
1341 * EEPROM Commands
1342 */
1343#define ASC_EEP_CMD_DONE 0x0200
1da177e4
LT
1344
1345/* bios_ctrl */
1346#define BIOS_CTRL_BIOS 0x0001
1347#define BIOS_CTRL_EXTENDED_XLAT 0x0002
1348#define BIOS_CTRL_GT_2_DISK 0x0004
1349#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1350#define BIOS_CTRL_BOOTABLE_CD 0x0010
1351#define BIOS_CTRL_MULTIPLE_LUN 0x0040
1352#define BIOS_CTRL_DISPLAY_MSG 0x0080
1353#define BIOS_CTRL_NO_SCAM 0x0100
1354#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1355#define BIOS_CTRL_INIT_VERBOSE 0x0800
1356#define BIOS_CTRL_SCSI_PARITY 0x1000
1357#define BIOS_CTRL_AIPP_DIS 0x2000
1358
27c868c2 1359#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1da177e4 1360
27c868c2 1361#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1362
1363/*
1364 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1365 * a special 16K Adv Library and Microcode version. After the issue is
1366 * resolved, should restore 32K support.
1367 *
1368 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1369 */
27c868c2 1370#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1371
1372/*
1373 * Byte I/O register address from base of 'iop_base'.
1374 */
1375#define IOPB_INTR_STATUS_REG 0x00
1376#define IOPB_CHIP_ID_1 0x01
1377#define IOPB_INTR_ENABLES 0x02
1378#define IOPB_CHIP_TYPE_REV 0x03
1379#define IOPB_RES_ADDR_4 0x04
1380#define IOPB_RES_ADDR_5 0x05
1381#define IOPB_RAM_DATA 0x06
1382#define IOPB_RES_ADDR_7 0x07
1383#define IOPB_FLAG_REG 0x08
1384#define IOPB_RES_ADDR_9 0x09
1385#define IOPB_RISC_CSR 0x0A
1386#define IOPB_RES_ADDR_B 0x0B
1387#define IOPB_RES_ADDR_C 0x0C
1388#define IOPB_RES_ADDR_D 0x0D
1389#define IOPB_SOFT_OVER_WR 0x0E
1390#define IOPB_RES_ADDR_F 0x0F
1391#define IOPB_MEM_CFG 0x10
1392#define IOPB_RES_ADDR_11 0x11
1393#define IOPB_GPIO_DATA 0x12
1394#define IOPB_RES_ADDR_13 0x13
1395#define IOPB_FLASH_PAGE 0x14
1396#define IOPB_RES_ADDR_15 0x15
1397#define IOPB_GPIO_CNTL 0x16
1398#define IOPB_RES_ADDR_17 0x17
1399#define IOPB_FLASH_DATA 0x18
1400#define IOPB_RES_ADDR_19 0x19
1401#define IOPB_RES_ADDR_1A 0x1A
1402#define IOPB_RES_ADDR_1B 0x1B
1403#define IOPB_RES_ADDR_1C 0x1C
1404#define IOPB_RES_ADDR_1D 0x1D
1405#define IOPB_RES_ADDR_1E 0x1E
1406#define IOPB_RES_ADDR_1F 0x1F
1407#define IOPB_DMA_CFG0 0x20
1408#define IOPB_DMA_CFG1 0x21
1409#define IOPB_TICKLE 0x22
1410#define IOPB_DMA_REG_WR 0x23
1411#define IOPB_SDMA_STATUS 0x24
1412#define IOPB_SCSI_BYTE_CNT 0x25
1413#define IOPB_HOST_BYTE_CNT 0x26
1414#define IOPB_BYTE_LEFT_TO_XFER 0x27
1415#define IOPB_BYTE_TO_XFER_0 0x28
1416#define IOPB_BYTE_TO_XFER_1 0x29
1417#define IOPB_BYTE_TO_XFER_2 0x2A
1418#define IOPB_BYTE_TO_XFER_3 0x2B
1419#define IOPB_ACC_GRP 0x2C
1420#define IOPB_RES_ADDR_2D 0x2D
1421#define IOPB_DEV_ID 0x2E
1422#define IOPB_RES_ADDR_2F 0x2F
1423#define IOPB_SCSI_DATA 0x30
1424#define IOPB_RES_ADDR_31 0x31
1425#define IOPB_RES_ADDR_32 0x32
1426#define IOPB_SCSI_DATA_HSHK 0x33
1427#define IOPB_SCSI_CTRL 0x34
1428#define IOPB_RES_ADDR_35 0x35
1429#define IOPB_RES_ADDR_36 0x36
1430#define IOPB_RES_ADDR_37 0x37
1431#define IOPB_RAM_BIST 0x38
1432#define IOPB_PLL_TEST 0x39
1433#define IOPB_PCI_INT_CFG 0x3A
1434#define IOPB_RES_ADDR_3B 0x3B
1435#define IOPB_RFIFO_CNT 0x3C
1436#define IOPB_RES_ADDR_3D 0x3D
1437#define IOPB_RES_ADDR_3E 0x3E
1438#define IOPB_RES_ADDR_3F 0x3F
1439
1440/*
1441 * Word I/O register address from base of 'iop_base'.
1442 */
27c868c2
MW
1443#define IOPW_CHIP_ID_0 0x00 /* CID0 */
1444#define IOPW_CTRL_REG 0x02 /* CC */
1445#define IOPW_RAM_ADDR 0x04 /* LA */
1446#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 1447#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
1448#define IOPW_RISC_CSR 0x0A /* CSR */
1449#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1450#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 1451#define IOPW_RES_ADDR_10 0x10
27c868c2 1452#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 1453#define IOPW_RES_ADDR_14 0x14
27c868c2 1454#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 1455#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
1456#define IOPW_EE_CMD 0x1A /* EC */
1457#define IOPW_EE_DATA 0x1C /* ED */
1458#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 1459#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
1460#define IOPW_Q_BASE 0x22 /* QB */
1461#define IOPW_QP 0x24 /* QP */
1462#define IOPW_IX 0x26 /* IX */
1463#define IOPW_SP 0x28 /* SP */
1464#define IOPW_PC 0x2A /* PC */
1da177e4
LT
1465#define IOPW_RES_ADDR_2C 0x2C
1466#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
1467#define IOPW_SCSI_DATA 0x30 /* SD */
1468#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1469#define IOPW_SCSI_CTRL 0x34 /* SC */
1470#define IOPW_HSHK_CFG 0x36 /* HCFG */
1471#define IOPW_SXFR_STATUS 0x36 /* SXS */
1472#define IOPW_SXFR_CNTL 0x38 /* SXL */
1473#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 1474#define IOPW_RES_ADDR_3C 0x3C
27c868c2 1475#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
1476
1477/*
1478 * Doubleword I/O register address from base of 'iop_base'.
1479 */
1480#define IOPDW_RES_ADDR_0 0x00
1481#define IOPDW_RAM_DATA 0x04
1482#define IOPDW_RES_ADDR_8 0x08
1483#define IOPDW_RES_ADDR_C 0x0C
1484#define IOPDW_RES_ADDR_10 0x10
1485#define IOPDW_COMMA 0x14
1486#define IOPDW_COMMB 0x18
1487#define IOPDW_RES_ADDR_1C 0x1C
1488#define IOPDW_SDMA_ADDR0 0x20
1489#define IOPDW_SDMA_ADDR1 0x24
1490#define IOPDW_SDMA_COUNT 0x28
1491#define IOPDW_SDMA_ERROR 0x2C
1492#define IOPDW_RDMA_ADDR0 0x30
1493#define IOPDW_RDMA_ADDR1 0x34
1494#define IOPDW_RDMA_COUNT 0x38
1495#define IOPDW_RDMA_ERROR 0x3C
1496
1497#define ADV_CHIP_ID_BYTE 0x25
1498#define ADV_CHIP_ID_WORD 0x04C1
1499
1da177e4
LT
1500#define ADV_INTR_ENABLE_HOST_INTR 0x01
1501#define ADV_INTR_ENABLE_SEL_INTR 0x02
1502#define ADV_INTR_ENABLE_DPR_INTR 0x04
1503#define ADV_INTR_ENABLE_RTA_INTR 0x08
1504#define ADV_INTR_ENABLE_RMA_INTR 0x10
1505#define ADV_INTR_ENABLE_RST_INTR 0x20
1506#define ADV_INTR_ENABLE_DPE_INTR 0x40
1507#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1508
1509#define ADV_INTR_STATUS_INTRA 0x01
1510#define ADV_INTR_STATUS_INTRB 0x02
1511#define ADV_INTR_STATUS_INTRC 0x04
1512
1513#define ADV_RISC_CSR_STOP (0x0000)
1514#define ADV_RISC_TEST_COND (0x2000)
1515#define ADV_RISC_CSR_RUN (0x4000)
1516#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1517
1518#define ADV_CTRL_REG_HOST_INTR 0x0100
1519#define ADV_CTRL_REG_SEL_INTR 0x0200
1520#define ADV_CTRL_REG_DPR_INTR 0x0400
1521#define ADV_CTRL_REG_RTA_INTR 0x0800
1522#define ADV_CTRL_REG_RMA_INTR 0x1000
1523#define ADV_CTRL_REG_RES_BIT14 0x2000
1524#define ADV_CTRL_REG_DPE_INTR 0x4000
1525#define ADV_CTRL_REG_POWER_DONE 0x8000
1526#define ADV_CTRL_REG_ANY_INTR 0xFF00
1527
1528#define ADV_CTRL_REG_CMD_RESET 0x00C6
1529#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1530#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1531#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1532#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1533
1534#define ADV_TICKLE_NOP 0x00
1535#define ADV_TICKLE_A 0x01
1536#define ADV_TICKLE_B 0x02
1537#define ADV_TICKLE_C 0x03
1538
1da177e4
LT
1539#define AdvIsIntPending(port) \
1540 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1541
1542/*
1543 * SCSI_CFG0 Register bit definitions
1544 */
27c868c2
MW
1545#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1546#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1547#define EVEN_PARITY 0x1000 /* Select Even Parity */
1548#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1549#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1550#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1551#define SCAM_EN 0x0080 /* Enable SCAM selection */
1552#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1553#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1554#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1555#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
1556
1557/*
1558 * SCSI_CFG1 Register bit definitions
1559 */
27c868c2
MW
1560#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1561#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1562#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1563#define FILTER_SEL 0x0C00 /* Filter Period Selection */
1564#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1565#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1566#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1567#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1568#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1569#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1570#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1571#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1572#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1573#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1574#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
1575
1576/*
1577 * Addendum for ASC-38C0800 Chip
1578 *
1579 * The ASC-38C1600 Chip uses the same definitions except that the
1580 * bus mode override bits [12:10] have been moved to byte register
1581 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1582 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1583 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1584 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1585 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1586 */
27c868c2
MW
1587#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1588#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1589#define HVD 0x1000 /* HVD Device Detect */
1590#define LVD 0x0800 /* LVD Device Detect */
1591#define SE 0x0400 /* SE Device Detect */
1592#define TERM_LVD 0x00C0 /* LVD Termination Bits */
1593#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1594#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1595#define TERM_SE 0x0030 /* SE Termination Bits */
1596#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1597#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1598#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1599#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1600#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1601#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1602#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1603#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
1604
1605#define CABLE_ILLEGAL_A 0x7
1606 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1607
1608#define CABLE_ILLEGAL_B 0xB
1609 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1610
1611/*
1612 * MEM_CFG Register bit definitions
1613 */
27c868c2
MW
1614#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1615#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1616#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1617#define RAM_SZ_2KB 0x00 /* 2 KB */
1618#define RAM_SZ_4KB 0x04 /* 4 KB */
1619#define RAM_SZ_8KB 0x08 /* 8 KB */
1620#define RAM_SZ_16KB 0x0C /* 16 KB */
1621#define RAM_SZ_32KB 0x10 /* 32 KB */
1622#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
1623
1624/*
1625 * DMA_CFG0 Register bit definitions
1626 *
1627 * This register is only accessible to the host.
1628 */
27c868c2
MW
1629#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1630#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1631#define FIFO_THRESH_16B 0x00 /* 16 bytes */
1632#define FIFO_THRESH_32B 0x20 /* 32 bytes */
1633#define FIFO_THRESH_48B 0x30 /* 48 bytes */
1634#define FIFO_THRESH_64B 0x40 /* 64 bytes */
1635#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1636#define FIFO_THRESH_96B 0x60 /* 96 bytes */
1637#define FIFO_THRESH_112B 0x70 /* 112 bytes */
1638#define START_CTL 0x0C /* DMA start conditions */
1639#define START_CTL_TH 0x00 /* Wait threshold level (default) */
1640#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1641#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1642#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1643#define READ_CMD 0x03 /* Memory Read Method */
1644#define READ_CMD_MR 0x00 /* Memory Read */
1645#define READ_CMD_MRL 0x02 /* Memory Read Long */
1646#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
1647
1648/*
1649 * ASC-38C0800 RAM BIST Register bit definitions
1650 */
1651#define RAM_TEST_MODE 0x80
1652#define PRE_TEST_MODE 0x40
1653#define NORMAL_MODE 0x00
1654#define RAM_TEST_DONE 0x10
1655#define RAM_TEST_STATUS 0x0F
1656#define RAM_TEST_HOST_ERROR 0x08
1657#define RAM_TEST_INTRAM_ERROR 0x04
1658#define RAM_TEST_RISC_ERROR 0x02
1659#define RAM_TEST_SCSI_ERROR 0x01
1660#define RAM_TEST_SUCCESS 0x00
1661#define PRE_TEST_VALUE 0x05
1662#define NORMAL_VALUE 0x00
1663
1664/*
1665 * ASC38C1600 Definitions
1666 *
1667 * IOPB_PCI_INT_CFG Bit Field Definitions
1668 */
1669
27c868c2 1670#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
1671
1672/*
1673 * Bit 1 can be set to change the interrupt for the Function to operate in
1674 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1675 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1676 * mode, otherwise the operating mode is undefined.
1677 */
1678#define TOTEMPOLE 0x02
1679
1680/*
1681 * Bit 0 can be used to change the Int Pin for the Function. The value is
1682 * 0 by default for both Functions with Function 0 using INT A and Function
1683 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1684 * INT A is used.
1685 *
1686 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1687 * value specified in the PCI Configuration Space.
1688 */
1689#define INTAB 0x01
1690
1da177e4
LT
1691/*
1692 * Adv Library Status Definitions
1693 */
1694#define ADV_TRUE 1
1695#define ADV_FALSE 0
1da177e4
LT
1696#define ADV_SUCCESS 1
1697#define ADV_BUSY 0
1698#define ADV_ERROR (-1)
1699
1da177e4
LT
1700/*
1701 * ADV_DVC_VAR 'warn_code' values
1702 */
27c868c2
MW
1703#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1704#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1705#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
27c868c2 1706#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 1707
27c868c2
MW
1708#define ADV_MAX_TID 15 /* max. target identifier */
1709#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
1710
1711/*
1712 * Error code values are set in ADV_DVC_VAR 'err_code'.
1713 */
27c868c2
MW
1714#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
1715#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
1716#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
1717#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
1718#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
1719#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
1720#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
1721#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
1722#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
1723#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
1724#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
1725#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
1726#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
1727#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
1728
1729/*
1730 * Fixed locations of microcode operating variables.
1731 */
27c868c2
MW
1732#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1733#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1734#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1735#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1736#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1737#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1738#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1739#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1740#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1741#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1742#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1743#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1744#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
1745#define ASC_MC_CHIP_TYPE 0x009A
1746#define ASC_MC_INTRB_CODE 0x009B
1747#define ASC_MC_WDTR_ABLE 0x009C
1748#define ASC_MC_SDTR_ABLE 0x009E
1749#define ASC_MC_TAGQNG_ABLE 0x00A0
1750#define ASC_MC_DISC_ENABLE 0x00A2
1751#define ASC_MC_IDLE_CMD_STATUS 0x00A4
1752#define ASC_MC_IDLE_CMD 0x00A6
1753#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1754#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1755#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1756#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1757#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1758#define ASC_MC_SDTR_DONE 0x00B6
1759#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1760#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1761#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 1762#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 1763#define ASC_MC_WDTR_DONE 0x0124
27c868c2 1764#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
1765#define ASC_MC_ICQ 0x0160
1766#define ASC_MC_IRQ 0x0164
1767#define ASC_MC_PPR_ABLE 0x017A
1768
1769/*
1770 * BIOS LRAM variable absolute offsets.
1771 */
1772#define BIOS_CODESEG 0x54
1773#define BIOS_CODELEN 0x56
1774#define BIOS_SIGNATURE 0x58
1775#define BIOS_VERSION 0x5A
1776
1777/*
1778 * Microcode Control Flags
1779 *
1780 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1781 * and handled by the microcode.
1782 */
27c868c2
MW
1783#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1784#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
1785
1786/*
1787 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1788 */
1789#define HSHK_CFG_WIDE_XFR 0x8000
1790#define HSHK_CFG_RATE 0x0F00
1791#define HSHK_CFG_OFFSET 0x001F
1792
27c868c2
MW
1793#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1794#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1795#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1796#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1797
1798#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1799#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1800#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1801#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1802#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1803
1804#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1805#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1806#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
1807#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
1808#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
1809/*
1810 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1811 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1812 */
27c868c2
MW
1813#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
1814#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
1815
1816/*
1817 * All fields here are accessed by the board microcode and need to be
1818 * little-endian.
1819 */
27c868c2
MW
1820typedef struct adv_carr_t {
1821 ADV_VADDR carr_va; /* Carrier Virtual Address */
1822 ADV_PADDR carr_pa; /* Carrier Physical Address */
1823 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1824 /*
1825 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
1826 *
1827 * next_vpa [3:1] Reserved Bits
1828 * next_vpa [0] Done Flag set in Response Queue.
1829 */
1830 ADV_VADDR next_vpa;
1da177e4
LT
1831} ADV_CARR_T;
1832
1833/*
1834 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1835 */
1836#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
1837
1838#define ASC_RQ_DONE 0x00000001
1839#define ASC_RQ_GOOD 0x00000002
1840#define ASC_CQ_STOPPER 0x00000000
1841
1842#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1843
1844#define ADV_CARRIER_NUM_PAGE_CROSSING \
1845 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
1846 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1847
1848#define ADV_CARRIER_BUFSIZE \
1849 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1850
1851/*
1852 * ASC_SCSI_REQ_Q 'a_flag' definitions
1853 *
1854 * The Adv Library should limit use to the lower nibble (4 bits) of
1855 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1856 */
27c868c2
MW
1857#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
1858#define ADV_SCSIQ_DONE 0x02 /* request done */
1859#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 1860
27c868c2
MW
1861#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
1862#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
1863#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
1864
1865/*
1866 * Adapter temporary configuration structure
1867 *
1868 * This structure can be discarded after initialization. Don't add
1869 * fields here needed after initialization.
1870 *
1871 * Field naming convention:
1872 *
1873 * *_enable indicates the field enables or disables a feature. The
1874 * value of the field is never reset.
1875 */
1876typedef struct adv_dvc_cfg {
27c868c2
MW
1877 ushort disc_enable; /* enable disconnection */
1878 uchar chip_version; /* chip version */
1879 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1880 ushort lib_version; /* Adv Library version number */
1881 ushort control_flag; /* Microcode Control Flag */
1882 ushort mcode_date; /* Microcode date */
1883 ushort mcode_version; /* Microcode version */
27c868c2
MW
1884 ushort serial1; /* EEPROM serial number word 1 */
1885 ushort serial2; /* EEPROM serial number word 2 */
1886 ushort serial3; /* EEPROM serial number word 3 */
1da177e4
LT
1887} ADV_DVC_CFG;
1888
1889struct adv_dvc_var;
1890struct adv_scsi_req_q;
1891
1da177e4
LT
1892/*
1893 * Adapter operation variable structure.
1894 *
1895 * One structure is required per host adapter.
1896 *
1897 * Field naming convention:
1898 *
1899 * *_able indicates both whether a feature should be enabled or disabled
1900 * and whether a device isi capable of the feature. At initialization
1901 * this field may be set, but later if a device is found to be incapable
1902 * of the feature, the field is cleared.
1903 */
1904typedef struct adv_dvc_var {
27c868c2
MW
1905 AdvPortAddr iop_base; /* I/O port address */
1906 ushort err_code; /* fatal error code */
1907 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
27c868c2
MW
1908 ushort wdtr_able; /* try WDTR for a device */
1909 ushort sdtr_able; /* try SDTR for a device */
1910 ushort ultra_able; /* try SDTR Ultra speed for a device */
1911 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
1912 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
1913 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
1914 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
1915 ushort tagqng_able; /* try tagged queuing with a device */
1916 ushort ppr_able; /* PPR message capable per TID bitmask. */
1917 uchar max_dvc_qng; /* maximum number of tagged commands per device */
1918 ushort start_motor; /* start motor command allowed */
1919 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
1920 uchar chip_no; /* should be assigned by caller */
1921 uchar max_host_qng; /* maximum number of Q'ed command allowed */
1922 uchar irq_no; /* IRQ number */
1923 ushort no_scam; /* scam_tolerant of EEPROM */
1924 struct asc_board *drv_ptr; /* driver pointer to private structure */
1925 uchar chip_scsi_id; /* chip SCSI target ID */
1926 uchar chip_type;
1927 uchar bist_err_code;
1928 ADV_CARR_T *carrier_buf;
1929 ADV_CARR_T *carr_freelist; /* Carrier free list. */
1930 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
1931 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
1932 ushort carr_pending_cnt; /* Count of pending carriers. */
1933 /*
1934 * Note: The following fields will not be used after initialization. The
1935 * driver may discard the buffer after initialization is done.
1936 */
1937 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
1938} ADV_DVC_VAR;
1939
1940#define NO_OF_SG_PER_BLOCK 15
1941
1942typedef struct asc_sg_block {
27c868c2
MW
1943 uchar reserved1;
1944 uchar reserved2;
1945 uchar reserved3;
1946 uchar sg_cnt; /* Valid entries in block. */
1947 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
1948 struct {
1949 ADV_PADDR sg_addr; /* SG element address. */
1950 ADV_DCNT sg_count; /* SG element count. */
1951 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
1952} ADV_SG_BLOCK;
1953
1954/*
1955 * ADV_SCSI_REQ_Q - microcode request structure
1956 *
1957 * All fields in this structure up to byte 60 are used by the microcode.
1958 * The microcode makes assumptions about the size and ordering of fields
1959 * in this structure. Do not change the structure definition here without
1960 * coordinating the change with the microcode.
1961 *
1962 * All fields accessed by microcode must be maintained in little_endian
1963 * order.
1964 */
1965typedef struct adv_scsi_req_q {
27c868c2
MW
1966 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
1967 uchar target_cmd;
1968 uchar target_id; /* Device target identifier. */
1969 uchar target_lun; /* Device target logical unit number. */
1970 ADV_PADDR data_addr; /* Data buffer physical address. */
1971 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
1972 ADV_PADDR sense_addr;
1973 ADV_PADDR carr_pa;
1974 uchar mflag;
1975 uchar sense_len;
1976 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
1977 uchar scsi_cntl;
1978 uchar done_status; /* Completion status. */
1979 uchar scsi_status; /* SCSI status byte. */
1980 uchar host_status; /* Ucode host status. */
1981 uchar sg_working_ix;
1982 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
1983 ADV_PADDR sg_real_addr; /* SG list physical address. */
1984 ADV_PADDR scsiq_rptr;
1985 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
1986 ADV_VADDR scsiq_ptr;
1987 ADV_VADDR carr_va;
1988 /*
1989 * End of microcode structure - 60 bytes. The rest of the structure
1990 * is used by the Adv Library and ignored by the microcode.
1991 */
1992 ADV_VADDR srb_ptr;
1993 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
1994 char *vdata_addr; /* Data buffer virtual address. */
1995 uchar a_flag;
1996 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
1997} ADV_SCSI_REQ_Q;
1998
1999/*
2000 * Microcode idle loop commands
2001 */
2002#define IDLE_CMD_COMPLETED 0
2003#define IDLE_CMD_STOP_CHIP 0x0001
2004#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2005#define IDLE_CMD_SEND_INT 0x0004
2006#define IDLE_CMD_ABORT 0x0008
2007#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
2008#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2009#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
2010#define IDLE_CMD_SCSIREQ 0x0080
2011
2012#define IDLE_CMD_STATUS_SUCCESS 0x0001
2013#define IDLE_CMD_STATUS_FAILURE 0x0002
2014
2015/*
2016 * AdvSendIdleCmd() flag definitions.
2017 */
2018#define ADV_NOWAIT 0x01
2019
2020/*
2021 * Wait loop time out values.
2022 */
27c868c2
MW
2023#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2024#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
27c868c2 2025#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 2026
27c868c2
MW
2027#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2028#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2029#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2030#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 2031
27c868c2 2032#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4 2033
1da177e4
LT
2034/* Read byte from a register. */
2035#define AdvReadByteRegister(iop_base, reg_off) \
2036 (ADV_MEM_READB((iop_base) + (reg_off)))
2037
2038/* Write byte to a register. */
2039#define AdvWriteByteRegister(iop_base, reg_off, byte) \
2040 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2041
2042/* Read word (2 bytes) from a register. */
2043#define AdvReadWordRegister(iop_base, reg_off) \
2044 (ADV_MEM_READW((iop_base) + (reg_off)))
2045
2046/* Write word (2 bytes) to a register. */
2047#define AdvWriteWordRegister(iop_base, reg_off, word) \
2048 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2049
2050/* Write dword (4 bytes) to a register. */
2051#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2052 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2053
2054/* Read byte from LRAM. */
2055#define AdvReadByteLram(iop_base, addr, byte) \
2056do { \
2057 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2058 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2059} while (0)
2060
2061/* Write byte to LRAM. */
2062#define AdvWriteByteLram(iop_base, addr, byte) \
2063 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2064 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2065
2066/* Read word (2 bytes) from LRAM. */
2067#define AdvReadWordLram(iop_base, addr, word) \
2068do { \
2069 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2070 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2071} while (0)
2072
2073/* Write word (2 bytes) to LRAM. */
2074#define AdvWriteWordLram(iop_base, addr, word) \
2075 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2076 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2077
2078/* Write little-endian double word (4 bytes) to LRAM */
2079/* Because of unspecified C language ordering don't use auto-increment. */
2080#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2081 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2082 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2083 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2084 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2085 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2086 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2087
2088/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2089#define AdvReadWordAutoIncLram(iop_base) \
2090 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2091
2092/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2093#define AdvWriteWordAutoIncLram(iop_base, word) \
2094 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2095
1da177e4
LT
2096/*
2097 * Define macro to check for Condor signature.
2098 *
2099 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2100 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2101 */
2102#define AdvFindSignature(iop_base) \
2103 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2104 ADV_CHIP_ID_BYTE) && \
2105 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2106 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2107
2108/*
2109 * Define macro to Return the version number of the chip at 'iop_base'.
2110 *
2111 * The second parameter 'bus_type' is currently unused.
2112 */
2113#define AdvGetChipVersion(iop_base, bus_type) \
2114 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2115
2116/*
2117 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2118 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2119 *
2120 * If the request has not yet been sent to the device it will simply be
2121 * aborted from RISC memory. If the request is disconnected it will be
2122 * aborted on reselection by sending an Abort Message to the target ID.
2123 *
2124 * Return value:
2125 * ADV_TRUE(1) - Queue was successfully aborted.
2126 * ADV_FALSE(0) - Queue was not found on the active queue list.
2127 */
2128#define AdvAbortQueue(asc_dvc, scsiq) \
2129 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2130 (ADV_DCNT) (scsiq))
2131
2132/*
2133 * Send a Bus Device Reset Message to the specified target ID.
2134 *
2135 * All outstanding commands will be purged if sending the
2136 * Bus Device Reset Message is successful.
2137 *
2138 * Return Value:
2139 * ADV_TRUE(1) - All requests on the target are purged.
2140 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2141 * are not purged.
2142 */
2143#define AdvResetDevice(asc_dvc, target_id) \
2144 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2145 (ADV_DCNT) (target_id))
2146
2147/*
2148 * SCSI Wide Type definition.
2149 */
2150#define ADV_SCSI_BIT_ID_TYPE ushort
2151
2152/*
2153 * AdvInitScsiTarget() 'cntl_flag' options.
2154 */
2155#define ADV_SCAN_LUN 0x01
2156#define ADV_CAPINFO_NOLUN 0x02
2157
2158/*
2159 * Convert target id to target id bit mask.
2160 */
2161#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2162
2163/*
2164 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2165 */
2166
27c868c2 2167#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
2168#define QD_NO_ERROR 0x01
2169#define QD_ABORTED_BY_HOST 0x02
2170#define QD_WITH_ERROR 0x04
2171
2172#define QHSTA_NO_ERROR 0x00
2173#define QHSTA_M_SEL_TIMEOUT 0x11
2174#define QHSTA_M_DATA_OVER_RUN 0x12
2175#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2176#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
2177#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2178#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2179#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2180#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2181#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2182#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2183#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 2184/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
2185#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2186#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2187#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2188#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2189#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2190#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2191#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2192#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
2193#define QHSTA_M_WTM_TIMEOUT 0x41
2194#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2195#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2196#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
2197#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2198#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2199#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4 2200
1da177e4
LT
2201/*
2202 * DvcGetPhyAddr() flag arguments
2203 */
27c868c2
MW
2204#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2205#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2206#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2207#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2208#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2209#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
2210
2211/* Return the address that is aligned at the next doubleword >= to 'addr'. */
2212#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2213#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2214#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2215
2216/*
2217 * Total contiguous memory needed for driver SG blocks.
2218 *
2219 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2220 * number of scatter-gather elements the driver supports in a
2221 * single request.
2222 */
2223
2224#define ADV_SG_LIST_MAX_BYTE_SIZE \
2225 (sizeof(ADV_SG_BLOCK) * \
2226 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2227
1da177e4
LT
2228/* Reference Scsi_Host hostdata */
2229#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2230
2231/* asc_board_t flags */
27c868c2 2232#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
2233
2234#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
1da177e4 2235
27c868c2 2236#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 2237
27c868c2 2238#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
2239
2240#ifdef CONFIG_PROC_FS
2241/* /proc/scsi/advansys/[0...] related definitions */
2242#define ASC_PRTBUF_SIZE 2048
2243#define ASC_PRTLINE_SIZE 160
2244
2245#define ASC_PRT_NEXT() \
2246 if (cp) { \
2247 totlen += len; \
2248 leftlen -= len; \
2249 if (leftlen == 0) { \
2250 return totlen; \
2251 } \
2252 cp += len; \
2253 }
2254#endif /* CONFIG_PROC_FS */
2255
2256/* Asc Library return codes */
2257#define ASC_TRUE 1
2258#define ASC_FALSE 0
2259#define ASC_NOERROR 1
2260#define ASC_BUSY 0
2261#define ASC_ERROR (-1)
2262
2263/* struct scsi_cmnd function return codes */
2264#define STATUS_BYTE(byte) (byte)
2265#define MSG_BYTE(byte) ((byte) << 8)
2266#define HOST_BYTE(byte) ((byte) << 16)
2267#define DRIVER_BYTE(byte) ((byte) << 24)
2268
1da177e4 2269#ifndef ADVANSYS_STATS
27c868c2
MW
2270#define ASC_STATS(shost, counter)
2271#define ASC_STATS_ADD(shost, counter, count)
1da177e4 2272#else /* ADVANSYS_STATS */
27c868c2
MW
2273#define ASC_STATS(shost, counter) \
2274 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 2275
27c868c2
MW
2276#define ASC_STATS_ADD(shost, counter, count) \
2277 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
2278#endif /* ADVANSYS_STATS */
2279
2280#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2281
2282/* If the result wraps when calculating tenths, return 0. */
2283#define ASC_TENTHS(num, den) \
2284 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2285 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2286
2287/*
2288 * Display a message to the console.
2289 */
2290#define ASC_PRINT(s) \
2291 { \
2292 printk("advansys: "); \
2293 printk(s); \
2294 }
2295
2296#define ASC_PRINT1(s, a1) \
2297 { \
2298 printk("advansys: "); \
2299 printk((s), (a1)); \
2300 }
2301
2302#define ASC_PRINT2(s, a1, a2) \
2303 { \
2304 printk("advansys: "); \
2305 printk((s), (a1), (a2)); \
2306 }
2307
2308#define ASC_PRINT3(s, a1, a2, a3) \
2309 { \
2310 printk("advansys: "); \
2311 printk((s), (a1), (a2), (a3)); \
2312 }
2313
2314#define ASC_PRINT4(s, a1, a2, a3, a4) \
2315 { \
2316 printk("advansys: "); \
2317 printk((s), (a1), (a2), (a3), (a4)); \
2318 }
2319
1da177e4
LT
2320#ifndef ADVANSYS_DEBUG
2321
2322#define ASC_DBG(lvl, s)
2323#define ASC_DBG1(lvl, s, a1)
2324#define ASC_DBG2(lvl, s, a1, a2)
2325#define ASC_DBG3(lvl, s, a1, a2, a3)
2326#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2327#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2328#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2329#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2330#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2331#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2332#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2333#define ASC_DBG_PRT_HEX(lvl, name, start, length)
2334#define ASC_DBG_PRT_CDB(lvl, cdb, len)
2335#define ASC_DBG_PRT_SENSE(lvl, sense, len)
2336#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2337
2338#else /* ADVANSYS_DEBUG */
2339
2340/*
2341 * Debugging Message Levels:
2342 * 0: Errors Only
2343 * 1: High-Level Tracing
2344 * 2-N: Verbose Tracing
2345 */
2346
2347#define ASC_DBG(lvl, s) \
2348 { \
2349 if (asc_dbglvl >= (lvl)) { \
2350 printk(s); \
2351 } \
2352 }
2353
2354#define ASC_DBG1(lvl, s, a1) \
2355 { \
2356 if (asc_dbglvl >= (lvl)) { \
2357 printk((s), (a1)); \
2358 } \
2359 }
2360
2361#define ASC_DBG2(lvl, s, a1, a2) \
2362 { \
2363 if (asc_dbglvl >= (lvl)) { \
2364 printk((s), (a1), (a2)); \
2365 } \
2366 }
2367
2368#define ASC_DBG3(lvl, s, a1, a2, a3) \
2369 { \
2370 if (asc_dbglvl >= (lvl)) { \
2371 printk((s), (a1), (a2), (a3)); \
2372 } \
2373 }
2374
2375#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2376 { \
2377 if (asc_dbglvl >= (lvl)) { \
2378 printk((s), (a1), (a2), (a3), (a4)); \
2379 } \
2380 }
2381
2382#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2383 { \
2384 if (asc_dbglvl >= (lvl)) { \
2385 asc_prt_scsi_host(s); \
2386 } \
2387 }
2388
2389#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2390 { \
2391 if (asc_dbglvl >= (lvl)) { \
2392 asc_prt_scsi_cmnd(s); \
2393 } \
2394 }
2395
2396#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2397 { \
2398 if (asc_dbglvl >= (lvl)) { \
2399 asc_prt_asc_scsi_q(scsiqp); \
2400 } \
2401 }
2402
2403#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2404 { \
2405 if (asc_dbglvl >= (lvl)) { \
2406 asc_prt_asc_qdone_info(qdone); \
2407 } \
2408 }
2409
2410#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2411 { \
2412 if (asc_dbglvl >= (lvl)) { \
2413 asc_prt_adv_scsi_req_q(scsiqp); \
2414 } \
2415 }
2416
2417#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2418 { \
2419 if (asc_dbglvl >= (lvl)) { \
2420 asc_prt_hex((name), (start), (length)); \
2421 } \
2422 }
2423
2424#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2425 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2426
2427#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2428 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2429
2430#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2431 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2432#endif /* ADVANSYS_DEBUG */
2433
1da177e4
LT
2434#ifdef ADVANSYS_STATS
2435
2436/* Per board statistics structure */
2437struct asc_stats {
27c868c2
MW
2438 /* Driver Entrypoint Statistics */
2439 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2440 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2441 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2442 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2443 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2444 ADV_DCNT done; /* # calls to request's scsi_done function */
2445 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2446 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2447 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2448 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2449 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2450 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2451 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2452 ADV_DCNT exe_unknown; /* # unknown returns. */
2453 /* Data Transfer Statistics */
2454 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2455 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2456 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2457 ADV_DCNT sg_elem; /* # scatter-gather elements */
2458 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
2459};
2460#endif /* ADVANSYS_STATS */
2461
1da177e4
LT
2462/*
2463 * Adv Library Request Structures
2464 *
2465 * The following two structures are used to process Wide Board requests.
2466 *
2467 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2468 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2469 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2470 * Mid-Level SCSI request structure.
2471 *
2472 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2473 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2474 * up to 255 scatter-gather elements may be used per request or
2475 * ADV_SCSI_REQ_Q.
2476 *
2477 * Both structures must be 32 byte aligned.
2478 */
2479typedef struct adv_sgblk {
27c868c2
MW
2480 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2481 uchar align[32]; /* Sgblock structure padding. */
2482 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
2483} adv_sgblk_t;
2484
2485typedef struct adv_req {
27c868c2
MW
2486 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2487 uchar align[32]; /* Request structure padding. */
2488 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2489 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2490 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
2491} adv_req_t;
2492
2493/*
2494 * Structure allocated for each board.
2495 *
8dfb5379 2496 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
2497 * of the 'Scsi_Host' structure starting at the 'hostdata'
2498 * field. It is guaranteed to be allocated from DMA-able memory.
2499 */
2500typedef struct asc_board {
394dbf3f 2501 struct device *dev;
27c868c2
MW
2502 int id; /* Board Id */
2503 uint flags; /* Board flags */
2504 union {
2505 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2506 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2507 } dvc_var;
2508 union {
2509 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2510 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2511 } dvc_cfg;
2512 ushort asc_n_io_port; /* Number I/O ports. */
27c868c2 2513 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
27c868c2
MW
2514 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2515 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2516 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2517 union {
2518 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2519 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2520 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2521 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2522 } eep_config;
2523 ulong last_reset; /* Saved last reset time */
2524 spinlock_t lock; /* Board spinlock */
27c868c2
MW
2525 /* /proc/scsi/advansys/[0...] */
2526 char *prtbuf; /* /proc print buffer */
1da177e4 2527#ifdef ADVANSYS_STATS
27c868c2
MW
2528 struct asc_stats asc_stats; /* Board statistics */
2529#endif /* ADVANSYS_STATS */
2530 /*
2531 * The following fields are used only for Narrow Boards.
2532 */
27c868c2
MW
2533 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2534 /*
2535 * The following fields are used only for Wide Boards.
2536 */
2537 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2538 ushort ioport; /* I/O Port address. */
b2c16f58 2539 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
2540 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2541 adv_req_t *adv_reqp; /* Request structures. */
2542 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2543 ushort bios_signature; /* BIOS Signature. */
2544 ushort bios_version; /* BIOS Version. */
2545 ushort bios_codeseg; /* BIOS Code Segment. */
2546 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
2547} asc_board_t;
2548
13ac2d9c
MW
2549#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2550 dvc_var.adv_dvc_var)
2551#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2552
1da177e4 2553/* Number of boards detected in system. */
78e77d8b
MW
2554static int asc_board_count;
2555
1da177e4 2556/* Overrun buffer used by all narrow boards. */
27c868c2 2557static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4 2558
1da177e4 2559#ifdef ADVANSYS_DEBUG
27c868c2 2560static int asc_dbglvl = 3;
1da177e4 2561
1da177e4 2562/*
51219358 2563 * asc_prt_scsi_host()
1da177e4 2564 */
51219358 2565static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 2566{
27c868c2 2567 asc_board_t *boardp;
1da177e4 2568
51219358 2569 boardp = ASC_BOARDP(s);
1da177e4 2570
51219358
MW
2571 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
2572 printk(" host_busy %u, host_no %d, last_reset %d,\n",
2573 s->host_busy, s->host_no, (unsigned)s->last_reset);
1da177e4 2574
51219358
MW
2575 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
2576 (ulong)s->base, (ulong)s->io_port, s->irq);
1da177e4 2577
51219358
MW
2578 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2579 s->dma_channel, s->this_id, s->can_queue);
27c868c2 2580
51219358
MW
2581 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
2582 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
27c868c2 2583
51219358
MW
2584 if (ASC_NARROW_BOARD(boardp)) {
2585 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
2586 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
2587 } else {
2588 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
2589 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
27c868c2 2590 }
51219358 2591}
27c868c2 2592
51219358
MW
2593/*
2594 * asc_prt_scsi_cmnd()
2595 */
2596static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
2597{
2598 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 2599
51219358
MW
2600 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
2601 (ulong)s->device->host, (ulong)s->device, s->device->id,
2602 s->device->lun, s->device->channel);
27c868c2 2603
51219358 2604 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
27c868c2 2605
51219358
MW
2606 printk("sc_data_direction %u, resid %d\n",
2607 s->sc_data_direction, s->resid);
1da177e4 2608
51219358 2609 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 2610
51219358
MW
2611 printk(" serial_number 0x%x, retries %d, allowed %d\n",
2612 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 2613
51219358 2614 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 2615
51219358
MW
2616 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
2617 s->scsi_done, s->done, s->host_scribble, s->result);
2618
2619 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4 2620}
1da177e4
LT
2621
2622/*
51219358 2623 * asc_prt_asc_dvc_var()
1da177e4 2624 */
51219358 2625static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 2626{
51219358 2627 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
27c868c2 2628
51219358
MW
2629 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2630 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2631
2632 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2633 (unsigned)h->init_sdtr);
2634
2635 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2636 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2637 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2638 (unsigned)h->chip_no);
2639
2640 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2641 "%u,\n", (unsigned)h->queue_full_or_busy,
2642 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2643
2644 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2645 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2646 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2647 (unsigned)h->in_critical_cnt);
2648
2649 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2650 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2651 (unsigned)h->init_state, (unsigned)h->no_scam,
2652 (unsigned)h->pci_fix_asyn_xfer);
2653
2654 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
2655}
2656
51219358
MW
2657/*
2658 * asc_prt_asc_dvc_cfg()
2659 */
2660static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
6ed1ef07 2661{
51219358 2662 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
6ed1ef07 2663
51219358
MW
2664 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2665 h->can_tagged_qng, h->cmd_qng_enabled);
2666 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2667 h->disc_enable, h->sdtr_enable);
6ed1ef07 2668
51219358
MW
2669 printk
2670 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
2671 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
2672 h->chip_version);
6ed1ef07 2673
51219358
MW
2674 printk
2675 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
2676 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
2677 h->mcode_date);
2678
2679 printk(" mcode_version %d, overrun_buf 0x%lx\n",
2680 h->mcode_version, (ulong)h->overrun_buf);
6ed1ef07
MW
2681}
2682
1da177e4 2683/*
51219358 2684 * asc_prt_asc_scsi_q()
1da177e4 2685 */
51219358 2686static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 2687{
51219358
MW
2688 ASC_SG_HEAD *sgp;
2689 int i;
1da177e4 2690
51219358 2691 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
1da177e4 2692
51219358
MW
2693 printk
2694 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
2695 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
2696 q->q2.tag_code);
2697
2698 printk
2699 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2700 (ulong)le32_to_cpu(q->q1.data_addr),
2701 (ulong)le32_to_cpu(q->q1.data_cnt),
2702 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2703
2704 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2705 (ulong)q->cdbptr, q->q2.cdb_len,
2706 (ulong)q->sg_head, q->q1.sg_queue_cnt);
2707
2708 if (q->sg_head) {
2709 sgp = q->sg_head;
2710 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2711 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2712 sgp->queue_cnt);
2713 for (i = 0; i < sgp->entry_cnt; i++) {
2714 printk(" [%u]: addr 0x%lx, bytes %lu\n",
2715 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2716 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2717 }
b2a7a4ba 2718
27c868c2 2719 }
51219358 2720}
1da177e4 2721
51219358
MW
2722/*
2723 * asc_prt_asc_qdone_info()
2724 */
2725static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2726{
2727 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2728 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
2729 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
2730 q->d2.tag_code);
2731 printk
2732 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2733 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
2734}
2735
2736/*
51219358 2737 * asc_prt_adv_dvc_var()
1da177e4 2738 *
51219358 2739 * Display an ADV_DVC_VAR structure.
1da177e4 2740 */
51219358 2741static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 2742{
51219358 2743 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
27c868c2 2744
51219358
MW
2745 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2746 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
1da177e4 2747
51219358
MW
2748 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
2749 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
2750 (unsigned)h->wdtr_able);
1da177e4 2751
51219358
MW
2752 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
2753 (unsigned)h->start_motor,
2754 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
1da177e4 2755
51219358
MW
2756 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2757 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2758 (ulong)h->carr_freelist);
1da177e4 2759
51219358
MW
2760 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
2761 (ulong)h->icq_sp, (ulong)h->irq_sp);
1da177e4 2762
51219358
MW
2763 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
2764 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
1da177e4 2765
51219358
MW
2766 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
2767 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2768}
1da177e4 2769
51219358
MW
2770/*
2771 * asc_prt_adv_dvc_cfg()
2772 *
2773 * Display an ADV_DVC_CFG structure.
2774 */
2775static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2776{
2777 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
27c868c2 2778
51219358
MW
2779 printk(" disc_enable 0x%x, termination 0x%x\n",
2780 h->disc_enable, h->termination);
1da177e4 2781
51219358
MW
2782 printk(" chip_version 0x%x, mcode_date 0x%x\n",
2783 h->chip_version, h->mcode_date);
27c868c2 2784
51219358
MW
2785 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
2786 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 2787
51219358 2788 printk(" control_flag 0x%x\n", h->control_flag);
1da177e4
LT
2789}
2790
2791/*
51219358 2792 * asc_prt_adv_scsi_req_q()
1da177e4 2793 *
51219358 2794 * Display an ADV_SCSI_REQ_Q structure.
1da177e4 2795 */
51219358 2796static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 2797{
51219358
MW
2798 int sg_blk_cnt;
2799 struct asc_sg_block *sg_ptr;
27c868c2 2800
51219358
MW
2801 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2802
2803 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
2804 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
2805
2806 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
2807 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
2808
2809 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2810 (ulong)le32_to_cpu(q->data_cnt),
2811 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2812
2813 printk
2814 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2815 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2816
2817 printk(" sg_working_ix 0x%x, target_cmd %u\n",
2818 q->sg_working_ix, q->target_cmd);
2819
2820 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2821 (ulong)le32_to_cpu(q->scsiq_rptr),
2822 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2823
2824 /* Display the request's ADV_SG_BLOCK structures. */
2825 if (q->sg_list_ptr != NULL) {
2826 sg_blk_cnt = 0;
2827 while (1) {
2828 /*
2829 * 'sg_ptr' is a physical address. Convert it to a virtual
2830 * address by indexing 'sg_blk_cnt' into the virtual address
2831 * array 'sg_list_ptr'.
2832 *
2833 * XXX - Assumes all SG physical blocks are virtually contiguous.
2834 */
2835 sg_ptr =
2836 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
2837 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2838 if (sg_ptr->sg_ptr == 0) {
2839 break;
2840 }
2841 sg_blk_cnt++;
27c868c2
MW
2842 }
2843 }
1da177e4
LT
2844}
2845
1da177e4 2846/*
51219358 2847 * asc_prt_adv_sgblock()
1da177e4 2848 *
51219358 2849 * Display an ADV_SG_BLOCK structure.
1da177e4 2850 */
51219358 2851static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 2852{
51219358 2853 int i;
27c868c2 2854
51219358
MW
2855 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2856 (ulong)b, sgblockno);
2857 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
2858 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
2859 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2860 if (b->sg_ptr != 0)
2861 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2862 for (i = 0; i < b->sg_cnt; i++) {
2863 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
2864 i, (ulong)b->sg_list[i].sg_addr,
2865 (ulong)b->sg_list[i].sg_count);
074c8fe4 2866 }
1da177e4
LT
2867}
2868
51219358
MW
2869/*
2870 * asc_prt_hex()
2871 *
2872 * Print hexadecimal output in 4 byte groupings 32 bytes
2873 * or 8 double-words per line.
2874 */
2875static void asc_prt_hex(char *f, uchar *s, int l)
47d853cc 2876{
51219358
MW
2877 int i;
2878 int j;
2879 int k;
2880 int m;
47d853cc 2881
51219358
MW
2882 printk("%s: (%d bytes)\n", f, l);
2883
2884 for (i = 0; i < l; i += 32) {
2885
2886 /* Display a maximum of 8 double-words per line. */
2887 if ((k = (l - i) / 4) >= 8) {
2888 k = 8;
2889 m = 0;
47d853cc 2890 } else {
51219358 2891 m = (l - i) % 4;
47d853cc
MW
2892 }
2893
51219358
MW
2894 for (j = 0; j < k; j++) {
2895 printk(" %2.2X%2.2X%2.2X%2.2X",
2896 (unsigned)s[i + (j * 4)],
2897 (unsigned)s[i + (j * 4) + 1],
2898 (unsigned)s[i + (j * 4) + 2],
2899 (unsigned)s[i + (j * 4) + 3]);
47d853cc 2900 }
47d853cc 2901
51219358
MW
2902 switch (m) {
2903 case 0:
2904 default:
2905 break;
2906 case 1:
2907 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2908 break;
2909 case 2:
2910 printk(" %2.2X%2.2X",
2911 (unsigned)s[i + (j * 4)],
2912 (unsigned)s[i + (j * 4) + 1]);
2913 break;
2914 case 3:
2915 printk(" %2.2X%2.2X%2.2X",
2916 (unsigned)s[i + (j * 4) + 1],
2917 (unsigned)s[i + (j * 4) + 2],
2918 (unsigned)s[i + (j * 4) + 3]);
2919 break;
2920 }
47d853cc 2921
51219358 2922 printk("\n");
47d853cc
MW
2923 }
2924}
51219358 2925#endif /* ADVANSYS_DEBUG */
47d853cc 2926
1da177e4 2927/*
51219358 2928 * advansys_info()
47d853cc 2929 *
51219358
MW
2930 * Return suitable for printing on the console with the argument
2931 * adapter's configuration information.
2932 *
2933 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2934 * otherwise the static 'info' array will be overrun.
1da177e4 2935 */
51219358 2936static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 2937{
51219358
MW
2938 static char info[ASC_INFO_SIZE];
2939 asc_board_t *boardp;
2940 ASC_DVC_VAR *asc_dvc_varp;
2941 ADV_DVC_VAR *adv_dvc_varp;
2942 char *busname;
2943 char *widename = NULL;
1da177e4 2944
51219358
MW
2945 boardp = ASC_BOARDP(shost);
2946 if (ASC_NARROW_BOARD(boardp)) {
2947 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2948 ASC_DBG(1, "advansys_info: begin\n");
2949 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2950 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2951 ASC_IS_ISAPNP) {
2952 busname = "ISA PnP";
2953 } else {
2954 busname = "ISA";
2955 }
2956 sprintf(info,
2957 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2958 ASC_VERSION, busname,
2959 (ulong)shost->io_port,
2960 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2961 shost->irq, shost->dma_channel);
2962 } else {
2963 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2964 busname = "VL";
2965 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2966 busname = "EISA";
2967 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2968 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2969 == ASC_IS_PCI_ULTRA) {
2970 busname = "PCI Ultra";
2971 } else {
2972 busname = "PCI";
2973 }
2974 } else {
2975 busname = "?";
2976 ASC_PRINT2("advansys_info: board %d: unknown "
2977 "bus type %d\n", boardp->id,
2978 asc_dvc_varp->bus_type);
2979 }
2980 sprintf(info,
2981 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2982 ASC_VERSION, busname, (ulong)shost->io_port,
2983 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2984 shost->irq);
2985 }
2986 } else {
2987 /*
2988 * Wide Adapter Information
2989 *
2990 * Memory-mapped I/O is used instead of I/O space to access
2991 * the adapter, but display the I/O Port range. The Memory
2992 * I/O address is displayed through the driver /proc file.
2993 */
2994 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2995 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2996 widename = "Ultra-Wide";
2997 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2998 widename = "Ultra2-Wide";
2999 } else {
3000 widename = "Ultra3-Wide";
3001 }
3002 sprintf(info,
3003 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3004 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
3005 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
3006 }
3007 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
3008 ASC_DBG(1, "advansys_info: end\n");
3009 return info;
47d853cc
MW
3010}
3011
51219358 3012#ifdef CONFIG_PROC_FS
47d853cc 3013/*
51219358 3014 * asc_prt_line()
47d853cc 3015 *
51219358
MW
3016 * If 'cp' is NULL print to the console, otherwise print to a buffer.
3017 *
3018 * Return 0 if printing to the console, otherwise return the number of
3019 * bytes written to the buffer.
3020 *
3021 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
3022 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
47d853cc 3023 */
51219358 3024static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
47d853cc 3025{
51219358
MW
3026 va_list args;
3027 int ret;
3028 char s[ASC_PRTLINE_SIZE];
47d853cc 3029
51219358
MW
3030 va_start(args, fmt);
3031 ret = vsprintf(s, fmt, args);
3032 BUG_ON(ret >= ASC_PRTLINE_SIZE);
3033 if (buf == NULL) {
3034 (void)printk(s);
3035 ret = 0;
3036 } else {
3037 ret = min(buflen, ret);
3038 memcpy(buf, s, ret);
3039 }
3040 va_end(args);
3041 return ret;
47d853cc
MW
3042}
3043
3044/*
51219358 3045 * asc_prt_board_devices()
47d853cc 3046 *
51219358
MW
3047 * Print driver information for devices attached to the board.
3048 *
3049 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3050 * cf. asc_prt_line().
3051 *
3052 * Return the number of characters copied into 'cp'. No more than
3053 * 'cplen' characters will be copied to 'cp'.
47d853cc 3054 */
51219358 3055static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
47d853cc 3056{
51219358
MW
3057 asc_board_t *boardp;
3058 int leftlen;
3059 int totlen;
3060 int len;
3061 int chip_scsi_id;
3062 int i;
47d853cc 3063
51219358
MW
3064 boardp = ASC_BOARDP(shost);
3065 leftlen = cplen;
3066 totlen = len = 0;
47d853cc 3067
51219358
MW
3068 len = asc_prt_line(cp, leftlen,
3069 "\nDevice Information for AdvanSys SCSI Host %d:\n",
3070 shost->host_no);
3071 ASC_PRT_NEXT();
47d853cc 3072
51219358
MW
3073 if (ASC_NARROW_BOARD(boardp)) {
3074 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3075 } else {
3076 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
47d853cc
MW
3077 }
3078
51219358
MW
3079 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
3080 ASC_PRT_NEXT();
3081 for (i = 0; i <= ADV_MAX_TID; i++) {
3082 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
3083 len = asc_prt_line(cp, leftlen, " %X,", i);
3084 ASC_PRT_NEXT();
3085 }
27c868c2 3086 }
51219358
MW
3087 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
3088 ASC_PRT_NEXT();
3089
3090 return totlen;
47d853cc
MW
3091}
3092
3093/*
51219358 3094 * Display Wide Board BIOS Information.
47d853cc 3095 */
51219358 3096static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
47d853cc 3097{
51219358
MW
3098 asc_board_t *boardp;
3099 int leftlen;
3100 int totlen;
3101 int len;
3102 ushort major, minor, letter;
3103
3104 boardp = ASC_BOARDP(shost);
3105 leftlen = cplen;
3106 totlen = len = 0;
3107
3108 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
3109 ASC_PRT_NEXT();
47d853cc
MW
3110
3111 /*
51219358
MW
3112 * If the BIOS saved a valid signature, then fill in
3113 * the BIOS code segment base address.
47d853cc 3114 */
51219358
MW
3115 if (boardp->bios_signature != 0x55AA) {
3116 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
3117 ASC_PRT_NEXT();
3118 len = asc_prt_line(cp, leftlen,
3119 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
3120 ASC_PRT_NEXT();
3121 len = asc_prt_line(cp, leftlen,
3122 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
3123 ASC_PRT_NEXT();
3124 } else {
3125 major = (boardp->bios_version >> 12) & 0xF;
3126 minor = (boardp->bios_version >> 8) & 0xF;
3127 letter = (boardp->bios_version & 0xFF);
47d853cc 3128
51219358
MW
3129 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
3130 major, minor,
3131 letter >= 26 ? '?' : letter + 'A');
3132 ASC_PRT_NEXT();
47d853cc 3133
51219358
MW
3134 /*
3135 * Current available ROM BIOS release is 3.1I for UW
3136 * and 3.2I for U2W. This code doesn't differentiate
3137 * UW and U2W boards.
3138 */
3139 if (major < 3 || (major <= 3 && minor < 1) ||
3140 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
3141 len = asc_prt_line(cp, leftlen,
3142 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
3143 ASC_PRT_NEXT();
3144 len = asc_prt_line(cp, leftlen,
3145 "ftp://ftp.connectcom.net/pub\n");
3146 ASC_PRT_NEXT();
3147 }
3148 }
3149
3150 return totlen;
1da177e4
LT
3151}
3152
1da177e4 3153/*
51219358
MW
3154 * Add serial number to information bar if signature AAh
3155 * is found in at bit 15-9 (7 bits) of word 1.
1da177e4 3156 *
51219358 3157 * Serial Number consists fo 12 alpha-numeric digits.
1da177e4 3158 *
51219358
MW
3159 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
3160 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
3161 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
3162 * 5 - Product revision (A-J) Word0: " "
1da177e4 3163 *
51219358
MW
3164 * Signature Word1: 15-9 (7 bits)
3165 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
3166 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
1da177e4 3167 *
51219358 3168 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
1da177e4 3169 *
51219358 3170 * Note 1: Only production cards will have a serial number.
1da177e4 3171 *
51219358 3172 * Note 2: Signature is most significant 7 bits (0xFE).
1da177e4 3173 *
51219358 3174 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
1da177e4 3175 */
51219358 3176static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 3177{
51219358 3178 ushort w, num;
27c868c2 3179
51219358
MW
3180 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3181 return ASC_FALSE;
3182 } else {
3183 /*
3184 * First word - 6 digits.
3185 */
3186 w = serialnum[0];
27c868c2 3187
51219358
MW
3188 /* Product type - 1st digit. */
3189 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3190 /* Product type is P=Prototype */
3191 *cp += 0x8;
3192 }
3193 cp++;
3194
3195 /* Manufacturing location - 2nd digit. */
3196 *cp++ = 'A' + ((w & 0x1C00) >> 10);
3197
3198 /* Product ID - 3rd, 4th digits. */
3199 num = w & 0x3FF;
3200 *cp++ = '0' + (num / 100);
3201 num %= 100;
3202 *cp++ = '0' + (num / 10);
3203
3204 /* Product revision - 5th digit. */
3205 *cp++ = 'A' + (num % 10);
27c868c2 3206
27c868c2 3207 /*
51219358 3208 * Second word
27c868c2 3209 */
51219358 3210 w = serialnum[1];
27c868c2
MW
3211
3212 /*
51219358 3213 * Year - 6th digit.
27c868c2 3214 *
51219358
MW
3215 * If bit 15 of third word is set, then the
3216 * last digit of the year is greater than 7.
27c868c2 3217 */
51219358
MW
3218 if (serialnum[2] & 0x8000) {
3219 *cp++ = '8' + ((w & 0x1C0) >> 6);
3220 } else {
3221 *cp++ = '0' + ((w & 0x1C0) >> 6);
27c868c2
MW
3222 }
3223
51219358
MW
3224 /* Week of year - 7th, 8th digits. */
3225 num = w & 0x003F;
3226 *cp++ = '0' + num / 10;
3227 num %= 10;
3228 *cp++ = '0' + num;
27c868c2
MW
3229
3230 /*
51219358 3231 * Third word
27c868c2 3232 */
51219358 3233 w = serialnum[2] & 0x7FFF;
1da177e4 3234
51219358
MW
3235 /* Serial number - 9th digit. */
3236 *cp++ = 'A' + (w / 1000);
27c868c2 3237
51219358
MW
3238 /* 10th, 11th, 12th digits. */
3239 num = w % 1000;
3240 *cp++ = '0' + num / 100;
3241 num %= 100;
3242 *cp++ = '0' + num / 10;
3243 num %= 10;
3244 *cp++ = '0' + num;
3245
3246 *cp = '\0'; /* Null Terminate the string. */
3247 return ASC_TRUE;
3248 }
1da177e4
LT
3249}
3250
3251/*
51219358 3252 * asc_prt_asc_board_eeprom()
1da177e4 3253 *
51219358 3254 * Print board EEPROM configuration.
1da177e4 3255 *
51219358
MW
3256 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3257 * cf. asc_prt_line().
3258 *
3259 * Return the number of characters copied into 'cp'. No more than
3260 * 'cplen' characters will be copied to 'cp'.
1da177e4 3261 */
51219358 3262static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3263{
51219358
MW
3264 asc_board_t *boardp;
3265 ASC_DVC_VAR *asc_dvc_varp;
3266 int leftlen;
3267 int totlen;
3268 int len;
3269 ASCEEP_CONFIG *ep;
3270 int i;
3271#ifdef CONFIG_ISA
3272 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
3273#endif /* CONFIG_ISA */
3274 uchar serialstr[13];
27c868c2 3275
51219358
MW
3276 boardp = ASC_BOARDP(shost);
3277 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3278 ep = &boardp->eep_config.asc_eep;
27c868c2 3279
51219358
MW
3280 leftlen = cplen;
3281 totlen = len = 0;
27c868c2 3282
51219358
MW
3283 len = asc_prt_line(cp, leftlen,
3284 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3285 shost->host_no);
3286 ASC_PRT_NEXT();
1da177e4 3287
51219358
MW
3288 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
3289 == ASC_TRUE) {
3290 len =
3291 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3292 serialstr);
3293 ASC_PRT_NEXT();
27c868c2 3294 } else {
51219358
MW
3295 if (ep->adapter_info[5] == 0xBB) {
3296 len = asc_prt_line(cp, leftlen,
3297 " Default Settings Used for EEPROM-less Adapter.\n");
3298 ASC_PRT_NEXT();
3299 } else {
3300 len = asc_prt_line(cp, leftlen,
3301 " Serial Number Signature Not Present.\n");
3302 ASC_PRT_NEXT();
27c868c2 3303 }
51219358 3304 }
27c868c2 3305
51219358
MW
3306 len = asc_prt_line(cp, leftlen,
3307 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3308 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
3309 ep->max_tag_qng);
3310 ASC_PRT_NEXT();
1da177e4 3311
51219358
MW
3312 len = asc_prt_line(cp, leftlen,
3313 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
3314 ASC_PRT_NEXT();
27c868c2 3315
51219358
MW
3316 len = asc_prt_line(cp, leftlen, " Target ID: ");
3317 ASC_PRT_NEXT();
3318 for (i = 0; i <= ASC_MAX_TID; i++) {
3319 len = asc_prt_line(cp, leftlen, " %d", i);
3320 ASC_PRT_NEXT();
3321 }
3322 len = asc_prt_line(cp, leftlen, "\n");
3323 ASC_PRT_NEXT();
1da177e4 3324
51219358
MW
3325 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3326 ASC_PRT_NEXT();
3327 for (i = 0; i <= ASC_MAX_TID; i++) {
3328 len = asc_prt_line(cp, leftlen, " %c",
3329 (ep->
3330 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3331 'N');
3332 ASC_PRT_NEXT();
27c868c2 3333 }
51219358
MW
3334 len = asc_prt_line(cp, leftlen, "\n");
3335 ASC_PRT_NEXT();
1da177e4 3336
51219358
MW
3337 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3338 ASC_PRT_NEXT();
3339 for (i = 0; i <= ASC_MAX_TID; i++) {
3340 len = asc_prt_line(cp, leftlen, " %c",
3341 (ep->
3342 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3343 'N');
3344 ASC_PRT_NEXT();
3345 }
3346 len = asc_prt_line(cp, leftlen, "\n");
3347 ASC_PRT_NEXT();
1da177e4 3348
51219358
MW
3349 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3350 ASC_PRT_NEXT();
3351 for (i = 0; i <= ASC_MAX_TID; i++) {
3352 len = asc_prt_line(cp, leftlen, " %c",
3353 (ep->
3354 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3355 'N');
3356 ASC_PRT_NEXT();
3357 }
3358 len = asc_prt_line(cp, leftlen, "\n");
3359 ASC_PRT_NEXT();
3360
3361 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3362 ASC_PRT_NEXT();
3363 for (i = 0; i <= ASC_MAX_TID; i++) {
3364 len = asc_prt_line(cp, leftlen, " %c",
3365 (ep->
3366 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3367 'N');
3368 ASC_PRT_NEXT();
3369 }
3370 len = asc_prt_line(cp, leftlen, "\n");
3371 ASC_PRT_NEXT();
3372
3373#ifdef CONFIG_ISA
3374 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3375 len = asc_prt_line(cp, leftlen,
3376 " Host ISA DMA speed: %d MB/S\n",
3377 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
3378 ASC_PRT_NEXT();
3379 }
3380#endif /* CONFIG_ISA */
3381
3382 return totlen;
1da177e4
LT
3383}
3384
3385/*
51219358 3386 * asc_prt_adv_board_eeprom()
1da177e4 3387 *
51219358 3388 * Print board EEPROM configuration.
1da177e4 3389 *
51219358
MW
3390 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3391 * cf. asc_prt_line().
3392 *
3393 * Return the number of characters copied into 'cp'. No more than
3394 * 'cplen' characters will be copied to 'cp'.
1da177e4 3395 */
51219358 3396static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3397{
51219358
MW
3398 asc_board_t *boardp;
3399 ADV_DVC_VAR *adv_dvc_varp;
3400 int leftlen;
3401 int totlen;
3402 int len;
27c868c2 3403 int i;
51219358
MW
3404 char *termstr;
3405 uchar serialstr[13];
3406 ADVEEP_3550_CONFIG *ep_3550 = NULL;
3407 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
3408 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
3409 ushort word;
3410 ushort *wordp;
3411 ushort sdtr_speed = 0;
27c868c2 3412
51219358
MW
3413 boardp = ASC_BOARDP(shost);
3414 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3415 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3416 ep_3550 = &boardp->eep_config.adv_3550_eep;
3417 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3418 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
27c868c2 3419 } else {
51219358 3420 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
27c868c2 3421 }
1da177e4 3422
51219358
MW
3423 leftlen = cplen;
3424 totlen = len = 0;
27c868c2 3425
51219358
MW
3426 len = asc_prt_line(cp, leftlen,
3427 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3428 shost->host_no);
3429 ASC_PRT_NEXT();
27c868c2 3430
51219358
MW
3431 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3432 wordp = &ep_3550->serial_number_word1;
3433 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3434 wordp = &ep_38C0800->serial_number_word1;
3435 } else {
3436 wordp = &ep_38C1600->serial_number_word1;
3437 }
27c868c2 3438
51219358
MW
3439 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
3440 len =
3441 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3442 serialstr);
3443 ASC_PRT_NEXT();
3444 } else {
3445 len = asc_prt_line(cp, leftlen,
3446 " Serial Number Signature Not Present.\n");
3447 ASC_PRT_NEXT();
3448 }
27c868c2 3449
51219358
MW
3450 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3451 len = asc_prt_line(cp, leftlen,
3452 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3453 ep_3550->adapter_scsi_id,
3454 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
3455 ASC_PRT_NEXT();
3456 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3457 len = asc_prt_line(cp, leftlen,
3458 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3459 ep_38C0800->adapter_scsi_id,
3460 ep_38C0800->max_host_qng,
3461 ep_38C0800->max_dvc_qng);
3462 ASC_PRT_NEXT();
3463 } else {
3464 len = asc_prt_line(cp, leftlen,
3465 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3466 ep_38C1600->adapter_scsi_id,
3467 ep_38C1600->max_host_qng,
3468 ep_38C1600->max_dvc_qng);
3469 ASC_PRT_NEXT();
27c868c2 3470 }
51219358
MW
3471 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3472 word = ep_3550->termination;
3473 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3474 word = ep_38C0800->termination_lvd;
3475 } else {
3476 word = ep_38C1600->termination_lvd;
3477 }
3478 switch (word) {
3479 case 1:
3480 termstr = "Low Off/High Off";
3481 break;
3482 case 2:
3483 termstr = "Low Off/High On";
3484 break;
3485 case 3:
3486 termstr = "Low On/High On";
3487 break;
3488 default:
3489 case 0:
3490 termstr = "Automatic";
3491 break;
27c868c2 3492 }
1da177e4 3493
51219358
MW
3494 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3495 len = asc_prt_line(cp, leftlen,
3496 " termination: %u (%s), bios_ctrl: 0x%x\n",
3497 ep_3550->termination, termstr,
3498 ep_3550->bios_ctrl);
3499 ASC_PRT_NEXT();
3500 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3501 len = asc_prt_line(cp, leftlen,
3502 " termination: %u (%s), bios_ctrl: 0x%x\n",
3503 ep_38C0800->termination_lvd, termstr,
3504 ep_38C0800->bios_ctrl);
3505 ASC_PRT_NEXT();
3506 } else {
3507 len = asc_prt_line(cp, leftlen,
3508 " termination: %u (%s), bios_ctrl: 0x%x\n",
3509 ep_38C1600->termination_lvd, termstr,
3510 ep_38C1600->bios_ctrl);
3511 ASC_PRT_NEXT();
3512 }
1da177e4 3513
51219358
MW
3514 len = asc_prt_line(cp, leftlen, " Target ID: ");
3515 ASC_PRT_NEXT();
3516 for (i = 0; i <= ADV_MAX_TID; i++) {
3517 len = asc_prt_line(cp, leftlen, " %X", i);
3518 ASC_PRT_NEXT();
3519 }
3520 len = asc_prt_line(cp, leftlen, "\n");
3521 ASC_PRT_NEXT();
1da177e4 3522
51219358
MW
3523 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3524 word = ep_3550->disc_enable;
3525 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3526 word = ep_38C0800->disc_enable;
3527 } else {
3528 word = ep_38C1600->disc_enable;
3529 }
3530 len = asc_prt_line(cp, leftlen, " Disconnects: ");
3531 ASC_PRT_NEXT();
3532 for (i = 0; i <= ADV_MAX_TID; i++) {
3533 len = asc_prt_line(cp, leftlen, " %c",
3534 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3535 ASC_PRT_NEXT();
3536 }
3537 len = asc_prt_line(cp, leftlen, "\n");
3538 ASC_PRT_NEXT();
1da177e4 3539
51219358
MW
3540 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3541 word = ep_3550->tagqng_able;
3542 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3543 word = ep_38C0800->tagqng_able;
3544 } else {
3545 word = ep_38C1600->tagqng_able;
3546 }
3547 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
3548 ASC_PRT_NEXT();
3549 for (i = 0; i <= ADV_MAX_TID; i++) {
3550 len = asc_prt_line(cp, leftlen, " %c",
3551 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3552 ASC_PRT_NEXT();
3553 }
3554 len = asc_prt_line(cp, leftlen, "\n");
3555 ASC_PRT_NEXT();
1da177e4 3556
51219358
MW
3557 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3558 word = ep_3550->start_motor;
3559 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3560 word = ep_38C0800->start_motor;
27c868c2 3561 } else {
51219358
MW
3562 word = ep_38C1600->start_motor;
3563 }
3564 len = asc_prt_line(cp, leftlen, " Start Motor: ");
3565 ASC_PRT_NEXT();
3566 for (i = 0; i <= ADV_MAX_TID; i++) {
3567 len = asc_prt_line(cp, leftlen, " %c",
3568 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3569 ASC_PRT_NEXT();
3570 }
3571 len = asc_prt_line(cp, leftlen, "\n");
3572 ASC_PRT_NEXT();
27c868c2 3573
51219358
MW
3574 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3575 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3576 ASC_PRT_NEXT();
3577 for (i = 0; i <= ADV_MAX_TID; i++) {
3578 len = asc_prt_line(cp, leftlen, " %c",
3579 (ep_3550->
3580 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3581 'Y' : 'N');
3582 ASC_PRT_NEXT();
27c868c2 3583 }
51219358
MW
3584 len = asc_prt_line(cp, leftlen, "\n");
3585 ASC_PRT_NEXT();
3586 }
27c868c2 3587
51219358
MW
3588 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3589 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
3590 ASC_PRT_NEXT();
3591 for (i = 0; i <= ADV_MAX_TID; i++) {
3592 len = asc_prt_line(cp, leftlen, " %c",
3593 (ep_3550->
3594 ultra_able & ADV_TID_TO_TIDMASK(i))
3595 ? 'Y' : 'N');
3596 ASC_PRT_NEXT();
27c868c2 3597 }
51219358
MW
3598 len = asc_prt_line(cp, leftlen, "\n");
3599 ASC_PRT_NEXT();
3600 }
27c868c2 3601
51219358
MW
3602 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3603 word = ep_3550->wdtr_able;
3604 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3605 word = ep_38C0800->wdtr_able;
3606 } else {
3607 word = ep_38C1600->wdtr_able;
3608 }
3609 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
3610 ASC_PRT_NEXT();
3611 for (i = 0; i <= ADV_MAX_TID; i++) {
3612 len = asc_prt_line(cp, leftlen, " %c",
3613 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3614 ASC_PRT_NEXT();
27c868c2 3615 }
51219358
MW
3616 len = asc_prt_line(cp, leftlen, "\n");
3617 ASC_PRT_NEXT();
1da177e4 3618
51219358
MW
3619 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3620 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3621 len = asc_prt_line(cp, leftlen,
3622 " Synchronous Transfer Speed (Mhz):\n ");
3623 ASC_PRT_NEXT();
3624 for (i = 0; i <= ADV_MAX_TID; i++) {
3625 char *speed_str;
1da177e4 3626
51219358
MW
3627 if (i == 0) {
3628 sdtr_speed = adv_dvc_varp->sdtr_speed1;
3629 } else if (i == 4) {
3630 sdtr_speed = adv_dvc_varp->sdtr_speed2;
3631 } else if (i == 8) {
3632 sdtr_speed = adv_dvc_varp->sdtr_speed3;
3633 } else if (i == 12) {
3634 sdtr_speed = adv_dvc_varp->sdtr_speed4;
3635 }
3636 switch (sdtr_speed & ADV_MAX_TID) {
3637 case 0:
3638 speed_str = "Off";
3639 break;
3640 case 1:
3641 speed_str = " 5";
3642 break;
3643 case 2:
3644 speed_str = " 10";
3645 break;
3646 case 3:
3647 speed_str = " 20";
3648 break;
3649 case 4:
3650 speed_str = " 40";
3651 break;
3652 case 5:
3653 speed_str = " 80";
3654 break;
3655 default:
3656 speed_str = "Unk";
3657 break;
3658 }
3659 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
3660 ASC_PRT_NEXT();
3661 if (i == 7) {
3662 len = asc_prt_line(cp, leftlen, "\n ");
3663 ASC_PRT_NEXT();
3664 }
3665 sdtr_speed >>= 4;
3666 }
3667 len = asc_prt_line(cp, leftlen, "\n");
3668 ASC_PRT_NEXT();
3669 }
1da177e4 3670
51219358 3671 return totlen;
1da177e4
LT
3672}
3673
3674/*
51219358 3675 * asc_prt_driver_conf()
1da177e4 3676 *
51219358
MW
3677 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3678 * cf. asc_prt_line().
1da177e4 3679 *
51219358
MW
3680 * Return the number of characters copied into 'cp'. No more than
3681 * 'cplen' characters will be copied to 'cp'.
1da177e4 3682 */
51219358 3683static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3684{
51219358
MW
3685 asc_board_t *boardp;
3686 int leftlen;
3687 int totlen;
3688 int len;
3689 int chip_scsi_id;
27c868c2 3690
51219358 3691 boardp = ASC_BOARDP(shost);
27c868c2 3692
51219358
MW
3693 leftlen = cplen;
3694 totlen = len = 0;
27c868c2 3695
51219358
MW
3696 len = asc_prt_line(cp, leftlen,
3697 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3698 shost->host_no);
3699 ASC_PRT_NEXT();
95c9f162 3700
51219358
MW
3701 len = asc_prt_line(cp, leftlen,
3702 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
3703 shost->host_busy, shost->last_reset, shost->max_id,
3704 shost->max_lun, shost->max_channel);
3705 ASC_PRT_NEXT();
95c9f162 3706
51219358
MW
3707 len = asc_prt_line(cp, leftlen,
3708 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3709 shost->unique_id, shost->can_queue, shost->this_id,
3710 shost->sg_tablesize, shost->cmd_per_lun);
3711 ASC_PRT_NEXT();
95c9f162 3712
51219358
MW
3713 len = asc_prt_line(cp, leftlen,
3714 " unchecked_isa_dma %d, use_clustering %d\n",
3715 shost->unchecked_isa_dma, shost->use_clustering);
3716 ASC_PRT_NEXT();
27c868c2 3717
51219358
MW
3718 len = asc_prt_line(cp, leftlen,
3719 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
3720 boardp->flags, boardp->last_reset, jiffies,
3721 boardp->asc_n_io_port);
3722 ASC_PRT_NEXT();
27c868c2 3723
51219358
MW
3724 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3725 ASC_PRT_NEXT();
27c868c2 3726
51219358
MW
3727 if (ASC_NARROW_BOARD(boardp)) {
3728 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3729 } else {
3730 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
27c868c2 3731 }
51219358
MW
3732
3733 return totlen;
1da177e4
LT
3734}
3735
3736/*
51219358 3737 * asc_prt_asc_board_info()
1da177e4 3738 *
51219358
MW
3739 * Print dynamic board configuration information.
3740 *
3741 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3742 * cf. asc_prt_line().
3743 *
3744 * Return the number of characters copied into 'cp'. No more than
3745 * 'cplen' characters will be copied to 'cp'.
1da177e4 3746 */
51219358 3747static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3748{
27c868c2 3749 asc_board_t *boardp;
51219358
MW
3750 int chip_scsi_id;
3751 int leftlen;
3752 int totlen;
3753 int len;
3754 ASC_DVC_VAR *v;
3755 ASC_DVC_CFG *c;
3756 int i;
3757 int renegotiate = 0;
27c868c2 3758
51219358
MW
3759 boardp = ASC_BOARDP(shost);
3760 v = &boardp->dvc_var.asc_dvc_var;
3761 c = &boardp->dvc_cfg.asc_dvc_cfg;
3762 chip_scsi_id = c->chip_scsi_id;
27c868c2 3763
51219358
MW
3764 leftlen = cplen;
3765 totlen = len = 0;
27c868c2 3766
51219358
MW
3767 len = asc_prt_line(cp, leftlen,
3768 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3769 shost->host_no);
3770 ASC_PRT_NEXT();
27c868c2 3771
51219358
MW
3772 len = asc_prt_line(cp, leftlen,
3773 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
3774 c->chip_version, c->lib_version, c->lib_serial_no,
3775 c->mcode_date);
3776 ASC_PRT_NEXT();
27c868c2 3777
51219358
MW
3778 len = asc_prt_line(cp, leftlen,
3779 " mcode_version 0x%x, err_code %u\n",
3780 c->mcode_version, v->err_code);
3781 ASC_PRT_NEXT();
1da177e4 3782
51219358
MW
3783 /* Current number of commands waiting for the host. */
3784 len = asc_prt_line(cp, leftlen,
3785 " Total Command Pending: %d\n", v->cur_total_qng);
3786 ASC_PRT_NEXT();
1da177e4 3787
51219358
MW
3788 len = asc_prt_line(cp, leftlen, " Command Queuing:");
3789 ASC_PRT_NEXT();
3790 for (i = 0; i <= ASC_MAX_TID; i++) {
3791 if ((chip_scsi_id == i) ||
3792 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3793 continue;
27c868c2 3794 }
51219358
MW
3795 len = asc_prt_line(cp, leftlen, " %X:%c",
3796 i,
3797 (v->
3798 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3799 'Y' : 'N');
3800 ASC_PRT_NEXT();
3801 }
3802 len = asc_prt_line(cp, leftlen, "\n");
3803 ASC_PRT_NEXT();
27c868c2 3804
51219358
MW
3805 /* Current number of commands waiting for a device. */
3806 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
3807 ASC_PRT_NEXT();
3808 for (i = 0; i <= ASC_MAX_TID; i++) {
3809 if ((chip_scsi_id == i) ||
3810 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3811 continue;
27c868c2 3812 }
51219358
MW
3813 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3814 ASC_PRT_NEXT();
27c868c2 3815 }
51219358
MW
3816 len = asc_prt_line(cp, leftlen, "\n");
3817 ASC_PRT_NEXT();
1da177e4 3818
51219358
MW
3819 /* Current limit on number of commands that can be sent to a device. */
3820 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
3821 ASC_PRT_NEXT();
3822 for (i = 0; i <= ASC_MAX_TID; i++) {
3823 if ((chip_scsi_id == i) ||
3824 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3825 continue;
3826 }
3827 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3828 ASC_PRT_NEXT();
27c868c2 3829 }
51219358
MW
3830 len = asc_prt_line(cp, leftlen, "\n");
3831 ASC_PRT_NEXT();
1da177e4 3832
51219358
MW
3833 /* Indicate whether the device has returned queue full status. */
3834 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
3835 ASC_PRT_NEXT();
3836 for (i = 0; i <= ASC_MAX_TID; i++) {
3837 if ((chip_scsi_id == i) ||
3838 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3839 continue;
3840 }
3841 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
3842 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
3843 i, boardp->queue_full_cnt[i]);
3844 } else {
3845 len = asc_prt_line(cp, leftlen, " %X:N", i);
3846 }
3847 ASC_PRT_NEXT();
3848 }
3849 len = asc_prt_line(cp, leftlen, "\n");
3850 ASC_PRT_NEXT();
1da177e4 3851
51219358
MW
3852 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3853 ASC_PRT_NEXT();
3854 for (i = 0; i <= ASC_MAX_TID; i++) {
3855 if ((chip_scsi_id == i) ||
3856 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3857 continue;
3858 }
3859 len = asc_prt_line(cp, leftlen, " %X:%c",
3860 i,
3861 (v->
3862 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3863 'N');
3864 ASC_PRT_NEXT();
27c868c2 3865 }
51219358
MW
3866 len = asc_prt_line(cp, leftlen, "\n");
3867 ASC_PRT_NEXT();
1da177e4 3868
51219358
MW
3869 for (i = 0; i <= ASC_MAX_TID; i++) {
3870 uchar syn_period_ix;
1da177e4 3871
51219358
MW
3872 if ((chip_scsi_id == i) ||
3873 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3874 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3875 continue;
27c868c2 3876 }
27c868c2 3877
51219358
MW
3878 len = asc_prt_line(cp, leftlen, " %X:", i);
3879 ASC_PRT_NEXT();
27c868c2 3880
51219358
MW
3881 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3882 len = asc_prt_line(cp, leftlen, " Asynchronous");
3883 ASC_PRT_NEXT();
3884 } else {
3885 syn_period_ix =
3886 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3887 1);
27c868c2 3888
51219358
MW
3889 len = asc_prt_line(cp, leftlen,
3890 " Transfer Period Factor: %d (%d.%d Mhz),",
3891 v->sdtr_period_tbl[syn_period_ix],
3892 250 /
3893 v->sdtr_period_tbl[syn_period_ix],
3894 ASC_TENTHS(250,
3895 v->
3896 sdtr_period_tbl
3897 [syn_period_ix]));
3898 ASC_PRT_NEXT();
27c868c2 3899
51219358
MW
3900 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3901 boardp->
3902 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3903 ASC_PRT_NEXT();
3904 }
1da177e4 3905
51219358
MW
3906 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3907 len = asc_prt_line(cp, leftlen, "*\n");
3908 renegotiate = 1;
3909 } else {
3910 len = asc_prt_line(cp, leftlen, "\n");
3911 }
3912 ASC_PRT_NEXT();
27c868c2 3913 }
1da177e4 3914
51219358
MW
3915 if (renegotiate) {
3916 len = asc_prt_line(cp, leftlen,
3917 " * = Re-negotiation pending before next command.\n");
3918 ASC_PRT_NEXT();
27c868c2 3919 }
1da177e4 3920
51219358 3921 return totlen;
1da177e4
LT
3922}
3923
1da177e4 3924/*
51219358 3925 * asc_prt_adv_board_info()
1da177e4 3926 *
51219358 3927 * Print dynamic board configuration information.
1da177e4
LT
3928 *
3929 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3930 * cf. asc_prt_line().
3931 *
3932 * Return the number of characters copied into 'cp'. No more than
3933 * 'cplen' characters will be copied to 'cp'.
3934 */
51219358 3935static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 3936{
27c868c2
MW
3937 asc_board_t *boardp;
3938 int leftlen;
3939 int totlen;
3940 int len;
27c868c2 3941 int i;
51219358
MW
3942 ADV_DVC_VAR *v;
3943 ADV_DVC_CFG *c;
3944 AdvPortAddr iop_base;
3945 ushort chip_scsi_id;
3946 ushort lramword;
3947 uchar lrambyte;
3948 ushort tagqng_able;
3949 ushort sdtr_able, wdtr_able;
3950 ushort wdtr_done, sdtr_done;
3951 ushort period = 0;
3952 int renegotiate = 0;
27c868c2
MW
3953
3954 boardp = ASC_BOARDP(shost);
51219358
MW
3955 v = &boardp->dvc_var.adv_dvc_var;
3956 c = &boardp->dvc_cfg.adv_dvc_cfg;
3957 iop_base = v->iop_base;
3958 chip_scsi_id = v->chip_scsi_id;
3959
27c868c2
MW
3960 leftlen = cplen;
3961 totlen = len = 0;
3962
3963 len = asc_prt_line(cp, leftlen,
51219358 3964 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
27c868c2
MW
3965 shost->host_no);
3966 ASC_PRT_NEXT();
3967
51219358
MW
3968 len = asc_prt_line(cp, leftlen,
3969 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3970 v->iop_base,
3971 AdvReadWordRegister(iop_base,
3972 IOPW_SCSI_CFG1) & CABLE_DETECT,
3973 v->err_code);
3974 ASC_PRT_NEXT();
1da177e4 3975
51219358
MW
3976 len = asc_prt_line(cp, leftlen,
3977 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
3978 c->chip_version, c->lib_version, c->mcode_date,
3979 c->mcode_version);
3980 ASC_PRT_NEXT();
3981
3982 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3983 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
27c868c2
MW
3984 ASC_PRT_NEXT();
3985 for (i = 0; i <= ADV_MAX_TID; i++) {
51219358
MW
3986 if ((chip_scsi_id == i) ||
3987 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3988 continue;
27c868c2 3989 }
51219358
MW
3990
3991 len = asc_prt_line(cp, leftlen, " %X:%c",
3992 i,
3993 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3994 'N');
3995 ASC_PRT_NEXT();
27c868c2 3996 }
51219358 3997 len = asc_prt_line(cp, leftlen, "\n");
27c868c2 3998 ASC_PRT_NEXT();
1da177e4 3999
51219358
MW
4000 len = asc_prt_line(cp, leftlen, " Queue Limit:");
4001 ASC_PRT_NEXT();
4002 for (i = 0; i <= ADV_MAX_TID; i++) {
4003 if ((chip_scsi_id == i) ||
4004 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4005 continue;
4006 }
1da177e4 4007
51219358
MW
4008 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
4009 lrambyte);
27c868c2 4010
51219358
MW
4011 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
4012 ASC_PRT_NEXT();
4013 }
4014 len = asc_prt_line(cp, leftlen, "\n");
4015 ASC_PRT_NEXT();
27c868c2 4016
51219358 4017 len = asc_prt_line(cp, leftlen, " Command Pending:");
27c868c2 4018 ASC_PRT_NEXT();
51219358
MW
4019 for (i = 0; i <= ADV_MAX_TID; i++) {
4020 if ((chip_scsi_id == i) ||
4021 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4022 continue;
4023 }
27c868c2 4024
51219358
MW
4025 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
4026 lrambyte);
1da177e4 4027
51219358 4028 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
27c868c2 4029 ASC_PRT_NEXT();
51219358
MW
4030 }
4031 len = asc_prt_line(cp, leftlen, "\n");
4032 ASC_PRT_NEXT();
1da177e4 4033
51219358
MW
4034 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4035 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
4036 ASC_PRT_NEXT();
4037 for (i = 0; i <= ADV_MAX_TID; i++) {
4038 if ((chip_scsi_id == i) ||
4039 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4040 continue;
27c868c2 4041 }
51219358
MW
4042
4043 len = asc_prt_line(cp, leftlen, " %X:%c",
4044 i,
4045 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4046 'N');
4047 ASC_PRT_NEXT();
27c868c2 4048 }
51219358
MW
4049 len = asc_prt_line(cp, leftlen, "\n");
4050 ASC_PRT_NEXT();
1da177e4 4051
51219358
MW
4052 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
4053 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
4054 ASC_PRT_NEXT();
4055 for (i = 0; i <= ADV_MAX_TID; i++) {
4056 if ((chip_scsi_id == i) ||
4057 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4058 continue;
4059 }
1da177e4 4060
51219358
MW
4061 AdvReadWordLram(iop_base,
4062 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
4063 lramword);
27c868c2 4064
51219358
MW
4065 len = asc_prt_line(cp, leftlen, " %X:%d",
4066 i, (lramword & 0x8000) ? 16 : 8);
4067 ASC_PRT_NEXT();
27c868c2 4068
51219358
MW
4069 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
4070 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4071 len = asc_prt_line(cp, leftlen, "*");
4072 ASC_PRT_NEXT();
4073 renegotiate = 1;
27c868c2 4074 }
51219358
MW
4075 }
4076 len = asc_prt_line(cp, leftlen, "\n");
4077 ASC_PRT_NEXT();
27c868c2 4078
51219358
MW
4079 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4080 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
4081 ASC_PRT_NEXT();
4082 for (i = 0; i <= ADV_MAX_TID; i++) {
4083 if ((chip_scsi_id == i) ||
4084 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4085 continue;
4086 }
27c868c2 4087
51219358
MW
4088 len = asc_prt_line(cp, leftlen, " %X:%c",
4089 i,
4090 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4091 'N');
4092 ASC_PRT_NEXT();
4093 }
4094 len = asc_prt_line(cp, leftlen, "\n");
4095 ASC_PRT_NEXT();
27c868c2 4096
51219358
MW
4097 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
4098 for (i = 0; i <= ADV_MAX_TID; i++) {
27c868c2 4099
51219358
MW
4100 AdvReadWordLram(iop_base,
4101 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
4102 lramword);
4103 lramword &= ~0x8000;
27c868c2 4104
51219358
MW
4105 if ((chip_scsi_id == i) ||
4106 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
4107 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
4108 continue;
27c868c2
MW
4109 }
4110
51219358
MW
4111 len = asc_prt_line(cp, leftlen, " %X:", i);
4112 ASC_PRT_NEXT();
27c868c2 4113
51219358
MW
4114 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
4115 len = asc_prt_line(cp, leftlen, " Asynchronous");
4116 ASC_PRT_NEXT();
4117 } else {
4118 len =
4119 asc_prt_line(cp, leftlen,
4120 " Transfer Period Factor: ");
4121 ASC_PRT_NEXT();
27c868c2 4122
51219358
MW
4123 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
4124 len =
4125 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
4126 ASC_PRT_NEXT();
4127 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
4128 len =
4129 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
4130 ASC_PRT_NEXT();
4131 } else { /* 20 Mhz or below. */
27c868c2 4132
51219358
MW
4133 period = (((lramword >> 8) * 25) + 50) / 4;
4134
4135 if (period == 0) { /* Should never happen. */
4136 len =
4137 asc_prt_line(cp, leftlen,
4138 "%d (? Mhz), ");
4139 ASC_PRT_NEXT();
4140 } else {
4141 len = asc_prt_line(cp, leftlen,
4142 "%d (%d.%d Mhz),",
4143 period, 250 / period,
4144 ASC_TENTHS(250,
4145 period));
4146 ASC_PRT_NEXT();
4147 }
4148 }
4149
4150 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
4151 lramword & 0x1F);
4152 ASC_PRT_NEXT();
4153 }
4154
4155 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4156 len = asc_prt_line(cp, leftlen, "*\n");
4157 renegotiate = 1;
4158 } else {
4159 len = asc_prt_line(cp, leftlen, "\n");
4160 }
4161 ASC_PRT_NEXT();
27c868c2 4162 }
51219358
MW
4163
4164 if (renegotiate) {
4165 len = asc_prt_line(cp, leftlen,
4166 " * = Re-negotiation pending before next command.\n");
4167 ASC_PRT_NEXT();
4168 }
4169
4170 return totlen;
1da177e4
LT
4171}
4172
4173/*
51219358 4174 * asc_proc_copy()
1da177e4 4175 *
51219358
MW
4176 * Copy proc information to a read buffer taking into account the current
4177 * read offset in the file and the remaining space in the read buffer.
4178 */
4179static int
4180asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4181 char *cp, int cplen)
4182{
4183 int cnt = 0;
4184
4185 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
4186 (unsigned)offset, (unsigned)advoffset, cplen);
4187 if (offset <= advoffset) {
4188 /* Read offset below current offset, copy everything. */
4189 cnt = min(cplen, leftlen);
4190 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4191 (ulong)curbuf, (ulong)cp, cnt);
4192 memcpy(curbuf, cp, cnt);
4193 } else if (offset < advoffset + cplen) {
4194 /* Read offset within current range, partial copy. */
4195 cnt = (advoffset + cplen) - offset;
4196 cp = (cp + cplen) - cnt;
4197 cnt = min(cnt, leftlen);
4198 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4199 (ulong)curbuf, (ulong)cp, cnt);
4200 memcpy(curbuf, cp, cnt);
4201 }
4202 return cnt;
4203}
4204
4205#ifdef ADVANSYS_STATS
4206/*
4207 * asc_prt_board_stats()
1da177e4
LT
4208 *
4209 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4210 * cf. asc_prt_line().
4211 *
4212 * Return the number of characters copied into 'cp'. No more than
4213 * 'cplen' characters will be copied to 'cp'.
4214 */
51219358 4215static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4216{
27c868c2
MW
4217 int leftlen;
4218 int totlen;
4219 int len;
51219358
MW
4220 struct asc_stats *s;
4221 asc_board_t *boardp;
27c868c2
MW
4222
4223 leftlen = cplen;
4224 totlen = len = 0;
4225
51219358
MW
4226 boardp = ASC_BOARDP(shost);
4227 s = &boardp->asc_stats;
4228
27c868c2 4229 len = asc_prt_line(cp, leftlen,
51219358 4230 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
27c868c2
MW
4231 shost->host_no);
4232 ASC_PRT_NEXT();
4233
27c868c2 4234 len = asc_prt_line(cp, leftlen,
51219358
MW
4235 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4236 s->queuecommand, s->reset, s->biosparam,
4237 s->interrupt);
27c868c2
MW
4238 ASC_PRT_NEXT();
4239
4240 len = asc_prt_line(cp, leftlen,
51219358
MW
4241 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
4242 s->callback, s->done, s->build_error,
4243 s->adv_build_noreq, s->adv_build_nosg);
27c868c2
MW
4244 ASC_PRT_NEXT();
4245
51219358
MW
4246 len = asc_prt_line(cp, leftlen,
4247 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
4248 s->exe_noerror, s->exe_busy, s->exe_error,
4249 s->exe_unknown);
27c868c2 4250 ASC_PRT_NEXT();
51219358
MW
4251
4252 /*
4253 * Display data transfer statistics.
4254 */
4255 if (s->cont_cnt > 0) {
4256 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
27c868c2 4257 ASC_PRT_NEXT();
27c868c2 4258
51219358
MW
4259 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
4260 s->cont_xfer / 2,
4261 ASC_TENTHS(s->cont_xfer, 2));
27c868c2 4262 ASC_PRT_NEXT();
27c868c2 4263
51219358
MW
4264 /* Contiguous transfer average size */
4265 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
4266 (s->cont_xfer / 2) / s->cont_cnt,
4267 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
27c868c2
MW
4268 ASC_PRT_NEXT();
4269 }
27c868c2 4270
51219358
MW
4271 if (s->sg_cnt > 0) {
4272
4273 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
4274 s->sg_cnt, s->sg_elem);
27c868c2 4275 ASC_PRT_NEXT();
27c868c2 4276
51219358
MW
4277 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
4278 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
27c868c2 4279 ASC_PRT_NEXT();
1da177e4 4280
51219358
MW
4281 /* Scatter gather transfer statistics */
4282 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
4283 s->sg_elem / s->sg_cnt,
4284 ASC_TENTHS(s->sg_elem, s->sg_cnt));
4285 ASC_PRT_NEXT();
4286
4287 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
4288 (s->sg_xfer / 2) / s->sg_elem,
4289 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
4290 ASC_PRT_NEXT();
4291
4292 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
4293 (s->sg_xfer / 2) / s->sg_cnt,
4294 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
27c868c2
MW
4295 ASC_PRT_NEXT();
4296 }
51219358
MW
4297
4298 /*
4299 * Display request queuing statistics.
4300 */
4301 len = asc_prt_line(cp, leftlen,
4302 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
4303 HZ);
4304 ASC_PRT_NEXT();
1da177e4 4305
27c868c2 4306 return totlen;
1da177e4 4307}
51219358 4308#endif /* ADVANSYS_STATS */
1da177e4
LT
4309
4310/*
51219358 4311 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4 4312 *
51219358
MW
4313 * *buffer: I/O buffer
4314 * **start: if inout == FALSE pointer into buffer where user read should start
4315 * offset: current offset into a /proc/scsi/advansys/[0...] file
4316 * length: length of buffer
4317 * hostno: Scsi_Host host_no
4318 * inout: TRUE - user is writing; FALSE - user is reading
1da177e4 4319 *
51219358
MW
4320 * Return the number of bytes read from or written to a
4321 * /proc/scsi/advansys/[0...] file.
1da177e4 4322 *
51219358
MW
4323 * Note: This function uses the per board buffer 'prtbuf' which is
4324 * allocated when the board is initialized in advansys_detect(). The
4325 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4326 * used to write to the buffer. The way asc_proc_copy() is written
4327 * if 'prtbuf' is too small it will not be overwritten. Instead the
4328 * user just won't get all the available statistics.
1da177e4 4329 */
51219358
MW
4330static int
4331advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4332 off_t offset, int length, int inout)
1da177e4 4333{
27c868c2 4334 asc_board_t *boardp;
51219358
MW
4335 char *cp;
4336 int cplen;
4337 int cnt;
4338 int totcnt;
27c868c2 4339 int leftlen;
51219358
MW
4340 char *curbuf;
4341 off_t advoffset;
27c868c2 4342
51219358
MW
4343 ASC_DBG(1, "advansys_proc_info: begin\n");
4344
4345 /*
4346 * User write not supported.
4347 */
4348 if (inout == TRUE) {
4349 return (-ENOSYS);
27c868c2 4350 }
1da177e4 4351
51219358
MW
4352 /*
4353 * User read of /proc/scsi/advansys/[0...] file.
4354 */
1da177e4 4355
51219358 4356 boardp = ASC_BOARDP(shost);
1da177e4 4357
51219358
MW
4358 /* Copy read data starting at the beginning of the buffer. */
4359 *start = buffer;
4360 curbuf = buffer;
4361 advoffset = 0;
4362 totcnt = 0;
4363 leftlen = length;
4364
4365 /*
4366 * Get board configuration information.
4367 *
4368 * advansys_info() returns the board string from its own static buffer.
4369 */
4370 cp = (char *)advansys_info(shost);
4371 strcat(cp, "\n");
4372 cplen = strlen(cp);
4373 /* Copy board information. */
4374 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4375 totcnt += cnt;
4376 leftlen -= cnt;
4377 if (leftlen == 0) {
4378 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4379 return totcnt;
27c868c2 4380 }
51219358
MW
4381 advoffset += cplen;
4382 curbuf += cnt;
1da177e4 4383
51219358
MW
4384 /*
4385 * Display Wide Board BIOS Information.
4386 */
9a256fa5 4387 if (!ASC_NARROW_BOARD(boardp)) {
51219358
MW
4388 cp = boardp->prtbuf;
4389 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4390 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4391 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4392 cplen);
4393 totcnt += cnt;
4394 leftlen -= cnt;
4395 if (leftlen == 0) {
4396 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4397 return totcnt;
4398 }
4399 advoffset += cplen;
4400 curbuf += cnt;
27c868c2 4401 }
1da177e4 4402
51219358
MW
4403 /*
4404 * Display driver information for each device attached to the board.
4405 */
4406 cp = boardp->prtbuf;
4407 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4408 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4409 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4410 totcnt += cnt;
4411 leftlen -= cnt;
4412 if (leftlen == 0) {
4413 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4414 return totcnt;
27c868c2 4415 }
51219358
MW
4416 advoffset += cplen;
4417 curbuf += cnt;
4418
4419 /*
4420 * Display EEPROM configuration for the board.
4421 */
4422 cp = boardp->prtbuf;
4423 if (ASC_NARROW_BOARD(boardp)) {
4424 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4425 } else {
51219358 4426 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4427 }
51219358
MW
4428 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4429 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4430 totcnt += cnt;
4431 leftlen -= cnt;
4432 if (leftlen == 0) {
4433 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4434 return totcnt;
27c868c2 4435 }
51219358
MW
4436 advoffset += cplen;
4437 curbuf += cnt;
1da177e4 4438
51219358
MW
4439 /*
4440 * Display driver configuration and information for the board.
4441 */
4442 cp = boardp->prtbuf;
4443 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4444 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4445 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4446 totcnt += cnt;
4447 leftlen -= cnt;
4448 if (leftlen == 0) {
4449 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4450 return totcnt;
27c868c2 4451 }
51219358
MW
4452 advoffset += cplen;
4453 curbuf += cnt;
1da177e4 4454
51219358
MW
4455#ifdef ADVANSYS_STATS
4456 /*
4457 * Display driver statistics for the board.
4458 */
4459 cp = boardp->prtbuf;
4460 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4461 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4462 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4463 totcnt += cnt;
4464 leftlen -= cnt;
4465 if (leftlen == 0) {
4466 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4467 return totcnt;
27c868c2 4468 }
51219358
MW
4469 advoffset += cplen;
4470 curbuf += cnt;
4471#endif /* ADVANSYS_STATS */
1da177e4 4472
51219358
MW
4473 /*
4474 * Display Asc Library dynamic configuration information
4475 * for the board.
4476 */
4477 cp = boardp->prtbuf;
4478 if (ASC_NARROW_BOARD(boardp)) {
4479 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4480 } else {
51219358 4481 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 4482 }
51219358
MW
4483 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4484 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4485 totcnt += cnt;
4486 leftlen -= cnt;
4487 if (leftlen == 0) {
4488 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4489 return totcnt;
27c868c2 4490 }
51219358
MW
4491 advoffset += cplen;
4492 curbuf += cnt;
1da177e4 4493
51219358 4494 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
27c868c2 4495
51219358
MW
4496 return totcnt;
4497}
4498#endif /* CONFIG_PROC_FS */
4499
4500static void asc_scsi_done(struct scsi_cmnd *scp)
4501{
4502 struct asc_board *boardp = ASC_BOARDP(scp->device->host);
4503
4504 if (scp->use_sg)
4505 dma_unmap_sg(boardp->dev,
4506 (struct scatterlist *)scp->request_buffer,
4507 scp->use_sg, scp->sc_data_direction);
4508 else if (scp->request_bufflen)
4509 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
4510 scp->request_bufflen, scp->sc_data_direction);
4511
4512 ASC_STATS(scp->device->host, done);
4513
4514 scp->scsi_done(scp);
4515}
4516
4517static void AscSetBank(PortAddr iop_base, uchar bank)
4518{
4519 uchar val;
4520
4521 val = AscGetChipControl(iop_base) &
4522 (~
4523 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
4524 CC_CHIP_RESET));
4525 if (bank == 1) {
4526 val |= CC_BANK_ONE;
4527 } else if (bank == 2) {
4528 val |= CC_DIAG | CC_BANK_ONE;
27c868c2 4529 } else {
51219358 4530 val &= ~CC_BANK_ONE;
27c868c2 4531 }
51219358
MW
4532 AscSetChipControl(iop_base, val);
4533 return;
4534}
4535
4536static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4537{
4538 AscSetBank(iop_base, 1);
4539 AscWriteChipIH(iop_base, ins_code);
4540 AscSetBank(iop_base, 0);
4541 return;
4542}
4543
4544static int AscStartChip(PortAddr iop_base)
4545{
4546 AscSetChipControl(iop_base, 0);
4547 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4548 return (0);
27c868c2 4549 }
51219358
MW
4550 return (1);
4551}
27c868c2 4552
51219358
MW
4553static int AscStopChip(PortAddr iop_base)
4554{
4555 uchar cc_val;
4556
4557 cc_val =
4558 AscGetChipControl(iop_base) &
4559 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
4560 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
4561 AscSetChipIH(iop_base, INS_HALT);
4562 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4563 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
4564 return (0);
27c868c2 4565 }
51219358
MW
4566 return (1);
4567}
27c868c2 4568
51219358
MW
4569static int AscIsChipHalted(PortAddr iop_base)
4570{
4571 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4572 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4573 return (1);
27c868c2 4574 }
27c868c2 4575 }
51219358
MW
4576 return (0);
4577}
27c868c2 4578
51219358
MW
4579static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4580{
4581 PortAddr iop_base;
4582 int i = 10;
4583
4584 iop_base = asc_dvc->iop_base;
4585 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4586 && (i-- > 0)) {
4587 mdelay(100);
27c868c2 4588 }
51219358
MW
4589 AscStopChip(iop_base);
4590 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
4591 udelay(60);
4592 AscSetChipIH(iop_base, INS_RFLAG_WTM);
4593 AscSetChipIH(iop_base, INS_HALT);
4594 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
4595 AscSetChipControl(iop_base, CC_HALT);
4596 mdelay(200);
4597 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
4598 AscSetChipStatus(iop_base, 0);
4599 return (AscIsChipHalted(iop_base));
4600}
27c868c2 4601
51219358
MW
4602static int AscFindSignature(PortAddr iop_base)
4603{
4604 ushort sig_word;
27c868c2 4605
51219358
MW
4606 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
4607 iop_base, AscGetChipSignatureByte(iop_base));
4608 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
4609 ASC_DBG2(1,
4610 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
4611 iop_base, AscGetChipSignatureWord(iop_base));
4612 sig_word = AscGetChipSignatureWord(iop_base);
4613 if ((sig_word == (ushort)ASC_1000_ID0W) ||
4614 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
4615 return (1);
27c868c2 4616 }
27c868c2 4617 }
51219358 4618 return (0);
27c868c2
MW
4619}
4620
51219358 4621static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 4622{
51219358 4623 ushort cfg;
27c868c2 4624
51219358
MW
4625 cfg = AscGetChipCfgLsw(iop_base);
4626 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
4627 return;
4628}
27c868c2 4629
51219358
MW
4630static void AscDisableInterrupt(PortAddr iop_base)
4631{
4632 ushort cfg;
27c868c2 4633
51219358
MW
4634 cfg = AscGetChipCfgLsw(iop_base);
4635 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
4636 return;
4637}
27c868c2 4638
51219358
MW
4639static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4640{
4641 unsigned char byte_data;
4642 unsigned short word_data;
27c868c2 4643
51219358
MW
4644 if (isodd_word(addr)) {
4645 AscSetChipLramAddr(iop_base, addr - 1);
4646 word_data = AscGetChipLramData(iop_base);
4647 byte_data = (word_data >> 8) & 0xFF;
4648 } else {
4649 AscSetChipLramAddr(iop_base, addr);
4650 word_data = AscGetChipLramData(iop_base);
4651 byte_data = word_data & 0xFF;
4652 }
4653 return byte_data;
4654}
27c868c2 4655
51219358
MW
4656static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4657{
4658 ushort word_data;
27c868c2 4659
51219358
MW
4660 AscSetChipLramAddr(iop_base, addr);
4661 word_data = AscGetChipLramData(iop_base);
4662 return (word_data);
4663}
27c868c2 4664
51219358
MW
4665#if CC_VERY_LONG_SG_LIST
4666static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4667{
4668 ushort val_low, val_high;
4669 ASC_DCNT dword_data;
27c868c2 4670
51219358
MW
4671 AscSetChipLramAddr(iop_base, addr);
4672 val_low = AscGetChipLramData(iop_base);
4673 val_high = AscGetChipLramData(iop_base);
4674 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
4675 return (dword_data);
4676}
4677#endif /* CC_VERY_LONG_SG_LIST */
4678
4679static void
4680AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4681{
4682 int i;
4683
4684 AscSetChipLramAddr(iop_base, s_addr);
4685 for (i = 0; i < words; i++) {
4686 AscSetChipLramData(iop_base, set_wval);
27c868c2 4687 }
51219358 4688}
1da177e4 4689
51219358
MW
4690static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4691{
4692 AscSetChipLramAddr(iop_base, addr);
4693 AscSetChipLramData(iop_base, word_val);
4694 return;
4695}
4696
4697static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4698{
4699 ushort word_data;
4700
4701 if (isodd_word(addr)) {
4702 addr--;
4703 word_data = AscReadLramWord(iop_base, addr);
4704 word_data &= 0x00FF;
4705 word_data |= (((ushort)byte_val << 8) & 0xFF00);
4706 } else {
4707 word_data = AscReadLramWord(iop_base, addr);
4708 word_data &= 0xFF00;
4709 word_data |= ((ushort)byte_val & 0x00FF);
4710 }
4711 AscWriteLramWord(iop_base, addr, word_data);
4712 return;
1da177e4
LT
4713}
4714
4715/*
51219358 4716 * Copy 2 bytes to LRAM.
1da177e4 4717 *
51219358
MW
4718 * The source data is assumed to be in little-endian order in memory
4719 * and is maintained in little-endian order when written to LRAM.
1da177e4 4720 */
51219358
MW
4721static void
4722AscMemWordCopyPtrToLram(PortAddr iop_base,
4723 ushort s_addr, uchar *s_buffer, int words)
1da177e4 4724{
27c868c2 4725 int i;
27c868c2 4726
51219358
MW
4727 AscSetChipLramAddr(iop_base, s_addr);
4728 for (i = 0; i < 2 * words; i += 2) {
4729 /*
4730 * On a little-endian system the second argument below
4731 * produces a little-endian ushort which is written to
4732 * LRAM in little-endian order. On a big-endian system
4733 * the second argument produces a big-endian ushort which
4734 * is "transparently" byte-swapped by outpw() and written
4735 * in little-endian order to LRAM.
4736 */
4737 outpw(iop_base + IOP_RAM_DATA,
4738 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4739 }
4740 return;
4741}
27c868c2 4742
51219358
MW
4743/*
4744 * Copy 4 bytes to LRAM.
4745 *
4746 * The source data is assumed to be in little-endian order in memory
4747 * and is maintained in little-endian order when writen to LRAM.
4748 */
4749static void
4750AscMemDWordCopyPtrToLram(PortAddr iop_base,
4751 ushort s_addr, uchar *s_buffer, int dwords)
4752{
4753 int i;
27c868c2 4754
51219358
MW
4755 AscSetChipLramAddr(iop_base, s_addr);
4756 for (i = 0; i < 4 * dwords; i += 4) {
4757 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
4758 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
4759 }
4760 return;
4761}
27c868c2 4762
51219358
MW
4763/*
4764 * Copy 2 bytes from LRAM.
4765 *
4766 * The source data is assumed to be in little-endian order in LRAM
4767 * and is maintained in little-endian order when written to memory.
4768 */
4769static void
4770AscMemWordCopyPtrFromLram(PortAddr iop_base,
4771 ushort s_addr, uchar *d_buffer, int words)
4772{
4773 int i;
4774 ushort word;
27c868c2 4775
51219358
MW
4776 AscSetChipLramAddr(iop_base, s_addr);
4777 for (i = 0; i < 2 * words; i += 2) {
4778 word = inpw(iop_base + IOP_RAM_DATA);
4779 d_buffer[i] = word & 0xff;
4780 d_buffer[i + 1] = (word >> 8) & 0xff;
27c868c2 4781 }
51219358
MW
4782 return;
4783}
27c868c2 4784
51219358
MW
4785static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4786{
4787 ASC_DCNT sum;
4788 int i;
27c868c2 4789
51219358
MW
4790 sum = 0L;
4791 for (i = 0; i < words; i++, s_addr += 2) {
4792 sum += AscReadLramWord(iop_base, s_addr);
27c868c2 4793 }
51219358
MW
4794 return (sum);
4795}
27c868c2 4796
51219358
MW
4797static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4798{
4799 uchar i;
4800 ushort s_addr;
4801 PortAddr iop_base;
4802 ushort warn_code;
27c868c2 4803
51219358
MW
4804 iop_base = asc_dvc->iop_base;
4805 warn_code = 0;
4806 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
4807 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
4808 64) >> 1));
4809 i = ASC_MIN_ACTIVE_QNO;
4810 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
4811 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4812 (uchar)(i + 1));
4813 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4814 (uchar)(asc_dvc->max_total_qng));
4815 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4816 (uchar)i);
4817 i++;
4818 s_addr += ASC_QBLK_SIZE;
4819 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
4820 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4821 (uchar)(i + 1));
4822 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4823 (uchar)(i - 1));
4824 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4825 (uchar)i);
27c868c2 4826 }
51219358
MW
4827 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4828 (uchar)ASC_QLINK_END);
4829 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4830 (uchar)(asc_dvc->max_total_qng - 1));
4831 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4832 (uchar)asc_dvc->max_total_qng);
4833 i++;
4834 s_addr += ASC_QBLK_SIZE;
4835 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
4836 i++, s_addr += ASC_QBLK_SIZE) {
4837 AscWriteLramByte(iop_base,
4838 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
4839 AscWriteLramByte(iop_base,
4840 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
4841 AscWriteLramByte(iop_base,
4842 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
27c868c2 4843 }
51219358 4844 return warn_code;
1da177e4
LT
4845}
4846
51219358
MW
4847static ASC_DCNT
4848AscLoadMicroCode(PortAddr iop_base,
4849 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 4850{
51219358
MW
4851 ASC_DCNT chksum;
4852 ushort mcode_word_size;
4853 ushort mcode_chksum;
27c868c2 4854
51219358
MW
4855 /* Write the microcode buffer starting at LRAM address 0. */
4856 mcode_word_size = (ushort)(mcode_size >> 1);
4857 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
4858 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
27c868c2 4859
51219358
MW
4860 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
4861 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
4862 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
4863 (ushort)ASC_CODE_SEC_BEG,
4864 (ushort)((mcode_size -
4865 s_addr - (ushort)
4866 ASC_CODE_SEC_BEG) /
4867 2));
4868 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
4869 (ulong)mcode_chksum);
4870 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4871 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
4872 return (chksum);
4873}
27c868c2 4874
51219358
MW
4875/* Microcode buffer is kept after initialization for error recovery. */
4876static uchar _asc_mcode_buf[] = {
4877 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4878 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
4879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4881 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
4883 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4884 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4885 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
4886 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
4887 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
4888 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
4889 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
4890 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
4891 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
4892 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
4893 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
4894 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
4895 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
4896 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
4897 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
4898 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
4899 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
4900 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
4901 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
4902 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
4903 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
4904 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
4905 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
4906 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
4907 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
4908 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
4909 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
4910 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
4911 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
4912 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
4913 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
4914 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
4915 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
4916 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
4917 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
4918 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
4919 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
4920 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
4921 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
4922 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
4923 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
4924 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
4925 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
4926 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
4927 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
4928 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
4929 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
4930 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
4931 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
4932 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
4933 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
4934 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
4935 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
4936 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
4937 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
4938 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
4939 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
4940 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
4941 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
4942 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
4943 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
4944 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
4945 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
4946 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
4947 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
4948 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
4949 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
4950 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
4951 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
4952 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
4953 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
4954 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
4955 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4956 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
4957 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4958 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
4959 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
4960 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
4961 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
4962 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
4963 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
4964 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
4965 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
4966 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
4967 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
4968 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
4969 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
4970 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
4971 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
4972 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
4973 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
4974 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
4975 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
4976 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
4977 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
4978 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
4979 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
4980 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
4981 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
4982 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
4983 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
4984 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
4985 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
4986 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
4987 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
4988 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
4989 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
4990 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
4991 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
4992 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
4993 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
4994 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
4995 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
4996 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
4997 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
4998 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
4999 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
5000 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
5001 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
5002 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
5003 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
5004 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
5005 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
5006 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
5007 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
5008 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
5009 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
5010 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
5011 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
5012 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
5013 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
5014 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
5015 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
5016 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
5017 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
5018 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
5019 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
5020 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
5021 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
5022 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
5023 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
5024 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
5025 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
5026 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
5027 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
5028 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
5029 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
5030 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
5031 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
5032 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
5033 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
5034 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
5035 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
5036 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
5037 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
5038 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
5039 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
5040 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
5041 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
5042 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
5043 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
5044 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
5045 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
5046 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
5047 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
5048 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
5049 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
5050 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
5051 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
5052 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
5053 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
5054 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
5055 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
5056 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
5057 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
5058 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
5059 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
5060 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
5061 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
5062 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
5063 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
5064 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
5065 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
5066 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
5067 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
5068 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
5069};
27c868c2 5070
51219358
MW
5071static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
5072static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4 5073
1da177e4 5074/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
5075static unsigned char _adv_asc3550_buf[] = {
5076 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
629d688d
MW
5077 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
5078 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
5079 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
27c868c2 5080 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
629d688d
MW
5081 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
5082 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
5083 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
27c868c2 5084 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
629d688d
MW
5085 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5086 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5087 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
27c868c2 5088 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
629d688d
MW
5089 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5090 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
5091 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
27c868c2 5092 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
629d688d
MW
5093 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
5094 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
5095 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
27c868c2 5096 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
629d688d
MW
5097 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
5098 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
5099 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
27c868c2 5100 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
629d688d
MW
5101 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
5102 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
5103 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
27c868c2 5104 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
629d688d
MW
5105 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
5106 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
5107 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
27c868c2 5108 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
629d688d
MW
5109 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
5110 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
5111 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
27c868c2 5112 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
629d688d
MW
5113 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
5114 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
5115 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
27c868c2 5116 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
629d688d
MW
5117 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
5118 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
5119 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
27c868c2 5120 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
5121 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
5122 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5123 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
27c868c2 5124 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
5125 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
5126 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
5127 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
27c868c2 5128 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
629d688d
MW
5129 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
5130 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5131 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
27c868c2 5132 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
629d688d
MW
5133 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
5134 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
5135 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
27c868c2 5136 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
629d688d
MW
5137 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
5138 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
5139 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
27c868c2 5140 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
5141 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
5142 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
5143 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
27c868c2 5144 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
629d688d
MW
5145 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
5146 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
5147 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
27c868c2 5148 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
629d688d
MW
5149 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
5150 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
5151 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
27c868c2 5152 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
629d688d
MW
5153 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
5154 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
5155 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
27c868c2 5156 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
629d688d
MW
5157 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
5158 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
5159 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
27c868c2 5160 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
629d688d
MW
5161 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
5162 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
5163 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
27c868c2 5164 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
629d688d
MW
5165 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
5166 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
5167 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
27c868c2 5168 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
629d688d
MW
5169 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
5170 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
5171 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
27c868c2 5172 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
629d688d
MW
5173 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
5174 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
5175 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
27c868c2 5176 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
629d688d
MW
5177 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
5178 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
5179 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
27c868c2 5180 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
629d688d
MW
5181 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
5182 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
5183 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
27c868c2 5184 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
629d688d
MW
5185 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
5186 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
5187 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
27c868c2 5188 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
629d688d
MW
5189 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
5190 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
5191 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
27c868c2 5192 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
629d688d
MW
5193 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
5194 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
5195 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
27c868c2 5196 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
629d688d
MW
5197 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
5198 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
5199 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
27c868c2 5200 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
629d688d
MW
5201 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
5202 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
5203 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
27c868c2 5204 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
629d688d
MW
5205 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
5206 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
5207 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
27c868c2 5208 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
629d688d
MW
5209 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
5210 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
5211 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
27c868c2 5212 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
629d688d
MW
5213 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
5214 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
5215 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
27c868c2 5216 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
629d688d
MW
5217 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
5218 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
5219 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
27c868c2 5220 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
629d688d
MW
5221 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5222 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
5223 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
27c868c2 5224 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
629d688d
MW
5225 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
5226 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
5227 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
27c868c2 5228 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
629d688d
MW
5229 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
5230 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
5231 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
27c868c2 5232 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
629d688d
MW
5233 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
5234 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
5235 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
27c868c2 5236 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
629d688d
MW
5237 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
5238 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
5239 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
27c868c2 5240 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
629d688d
MW
5241 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5242 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
5243 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
27c868c2 5244 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
629d688d
MW
5245 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
5246 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
5247 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
27c868c2 5248 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
629d688d
MW
5249 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
5250 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
5251 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
27c868c2 5252 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
629d688d
MW
5253 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
5254 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
5255 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
27c868c2 5256 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
629d688d
MW
5257 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
5258 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
5259 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
27c868c2 5260 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
629d688d
MW
5261 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
5262 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
5263 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
27c868c2 5264 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
629d688d
MW
5265 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
5266 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
5267 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
27c868c2 5268 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
629d688d
MW
5269 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
5270 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
5271 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
27c868c2 5272 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
629d688d
MW
5273 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
5274 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
5275 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
27c868c2 5276 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
629d688d
MW
5277 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
5278 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
5279 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
27c868c2 5280 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
629d688d
MW
5281 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
5282 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
5283 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
27c868c2 5284 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
629d688d
MW
5285 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
5286 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
5287 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
27c868c2 5288 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
629d688d
MW
5289 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
5290 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
5291 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
27c868c2 5292 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
629d688d
MW
5293 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
5294 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
5295 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
27c868c2 5296 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
629d688d
MW
5297 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
5298 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
5299 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
27c868c2 5300 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
629d688d
MW
5301 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
5302 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
5303 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
27c868c2 5304 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
629d688d
MW
5305 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
5306 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
5307 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
27c868c2 5308 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
629d688d
MW
5309 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
5310 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
5311 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
27c868c2 5312 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
629d688d
MW
5313 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
5314 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
5315 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
27c868c2 5316 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
629d688d
MW
5317 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
5318 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
5319 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
27c868c2 5320 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
629d688d
MW
5321 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
5322 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
5323 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
27c868c2 5324 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
629d688d
MW
5325 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
5326 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
5327 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
27c868c2 5328 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
629d688d
MW
5329 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
5330 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5331 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
27c868c2 5332 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
629d688d
MW
5333 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
5334 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5335 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
27c868c2 5336 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
629d688d
MW
5337 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
5338 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5339 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
27c868c2 5340 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
629d688d
MW
5341 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
5342 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
5343 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
27c868c2 5344 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
629d688d
MW
5345 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
5346 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5347 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
27c868c2 5348 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
629d688d
MW
5349 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
5350 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
5351 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
27c868c2 5352 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
629d688d
MW
5353 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
5354 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
5355 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
27c868c2 5356 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
629d688d
MW
5357 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
5358 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
5359 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
27c868c2 5360 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
629d688d
MW
5361 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
5362 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
5363 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
27c868c2 5364 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
629d688d
MW
5365 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
5366 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
5367 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
27c868c2 5368 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
629d688d
MW
5369 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
5370 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
5371 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
27c868c2 5372 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
629d688d
MW
5373 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
5374 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
5375 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
27c868c2 5376 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
629d688d
MW
5377 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
5378 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
5379 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
27c868c2 5380 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
629d688d
MW
5381 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
5382 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
5383 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
27c868c2 5384 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
629d688d
MW
5385 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
5386 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
5387 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
27c868c2 5388 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
629d688d
MW
5389 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
5390 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
5391 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
27c868c2 5392 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
629d688d
MW
5393 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
5394 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
5395 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
27c868c2 5396 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
629d688d
MW
5397 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
5398 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
5399 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
27c868c2 5400 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
629d688d
MW
5401 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
5402 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
5403 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
27c868c2 5404 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
629d688d
MW
5405 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
5406 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
5407 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
27c868c2 5408 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
629d688d
MW
5409 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
5410 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
5411 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
27c868c2 5412 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
629d688d
MW
5413 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
5414 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
5415 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
27c868c2 5416 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
629d688d
MW
5417 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
5418 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
5419 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
27c868c2 5420 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
629d688d
MW
5421 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
5422 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
5423 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
27c868c2 5424 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
629d688d
MW
5425 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
5426 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
5427 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
27c868c2 5428 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
629d688d
MW
5429 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
5430 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
5431 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
27c868c2 5432 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
629d688d
MW
5433 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
5434 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
5435 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
27c868c2 5436 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
629d688d
MW
5437 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
5438 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
5439 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
27c868c2 5440 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
629d688d
MW
5441 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
5442 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
5443 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
27c868c2 5444 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
629d688d
MW
5445 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
5446 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
5447 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
27c868c2 5448 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
629d688d
MW
5449 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
5450 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
5451 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
27c868c2 5452 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
629d688d
MW
5453 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
5454 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
5455 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
27c868c2 5456 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
629d688d
MW
5457 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
5458 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
5459 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
27c868c2 5460 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
629d688d
MW
5461 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
5462 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
5463 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
27c868c2 5464 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
629d688d
MW
5465 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
5466 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
5467 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
27c868c2 5468 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
629d688d
MW
5469 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
5470 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
5471 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
27c868c2 5472 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
629d688d
MW
5473 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
5474 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
5475 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
27c868c2 5476 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
629d688d
MW
5477 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
5478 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
5479 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
27c868c2 5480 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
629d688d
MW
5481 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
5482 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
5483 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
27c868c2 5484 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
629d688d
MW
5485 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
5486 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
5487 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
27c868c2 5488 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
629d688d
MW
5489 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
5490 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
5491 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
27c868c2 5492 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
629d688d
MW
5493 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5494 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
1da177e4
LT
5495};
5496
27c868c2
MW
5497static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
5498static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
5499
5500/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
5501static unsigned char _adv_asc38C0800_buf[] = {
5502 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
629d688d
MW
5503 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
5504 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
5505 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
27c868c2 5506 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
629d688d
MW
5507 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
5508 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
5509 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
27c868c2 5510 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
629d688d
MW
5511 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
5512 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
5513 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
27c868c2 5514 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
629d688d
MW
5515 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
5516 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
5517 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
27c868c2 5518 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
629d688d
MW
5519 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
5520 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
5521 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
27c868c2 5522 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
629d688d
MW
5523 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
5524 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
5525 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
27c868c2 5526 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
629d688d
MW
5527 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
5528 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
5529 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
27c868c2 5530 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
629d688d
MW
5531 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
5532 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
5533 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
27c868c2 5534 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
629d688d
MW
5535 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
5536 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
5537 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
27c868c2 5538 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
629d688d
MW
5539 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
5540 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
5541 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
27c868c2 5542 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
629d688d
MW
5543 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
5544 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
5545 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
27c868c2 5546 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
5547 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
5548 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5549 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
27c868c2 5550 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
5551 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
5552 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
5553 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
27c868c2 5554 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
629d688d
MW
5555 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
5556 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5557 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
27c868c2 5558 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
629d688d
MW
5559 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
5560 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
5561 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
27c868c2 5562 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
629d688d
MW
5563 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
5564 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
5565 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
27c868c2 5566 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
5567 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
5568 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
5569 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
27c868c2 5570 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
629d688d
MW
5571 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
5572 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
5573 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
27c868c2 5574 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
629d688d
MW
5575 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
5576 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
5577 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
27c868c2 5578 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
629d688d
MW
5579 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
5580 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
5581 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
27c868c2 5582 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
629d688d
MW
5583 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
5584 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
5585 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
27c868c2 5586 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
629d688d
MW
5587 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
5588 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
5589 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
27c868c2 5590 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
629d688d
MW
5591 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
5592 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
5593 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
27c868c2 5594 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
629d688d
MW
5595 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5596 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
5597 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
27c868c2 5598 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
629d688d
MW
5599 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
5600 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
5601 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
27c868c2 5602 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
629d688d
MW
5603 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5604 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
5605 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
27c868c2 5606 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
629d688d
MW
5607 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
5608 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
5609 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
27c868c2 5610 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
629d688d
MW
5611 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
5612 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
5613 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
27c868c2 5614 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
629d688d
MW
5615 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
5616 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
5617 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
27c868c2 5618 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
629d688d
MW
5619 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
5620 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
5621 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
27c868c2 5622 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
629d688d
MW
5623 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
5624 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
5625 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
27c868c2 5626 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
629d688d
MW
5627 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
5628 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
5629 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
27c868c2 5630 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
629d688d
MW
5631 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
5632 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
5633 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
27c868c2 5634 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
629d688d
MW
5635 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
5636 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
5637 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
27c868c2 5638 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
629d688d
MW
5639 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
5640 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
5641 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
27c868c2 5642 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
629d688d
MW
5643 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
5644 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
5645 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
27c868c2 5646 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
629d688d
MW
5647 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
5648 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
5649 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
27c868c2 5650 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
629d688d
MW
5651 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
5652 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
5653 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
27c868c2 5654 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
629d688d
MW
5655 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
5656 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
5657 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
27c868c2 5658 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
629d688d
MW
5659 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
5660 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
5661 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
27c868c2 5662 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
629d688d
MW
5663 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
5664 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
5665 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
27c868c2 5666 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
629d688d
MW
5667 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
5668 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
5669 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
27c868c2 5670 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
629d688d
MW
5671 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
5672 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
5673 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
27c868c2 5674 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
629d688d
MW
5675 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
5676 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
5677 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
27c868c2 5678 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
629d688d
MW
5679 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
5680 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
5681 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
27c868c2 5682 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
629d688d
MW
5683 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
5684 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
5685 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
27c868c2 5686 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
629d688d
MW
5687 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
5688 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
5689 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
27c868c2 5690 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
629d688d
MW
5691 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
5692 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
5693 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
27c868c2 5694 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
629d688d
MW
5695 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
5696 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
5697 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
27c868c2 5698 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
629d688d
MW
5699 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
5700 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
5701 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
27c868c2 5702 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
629d688d
MW
5703 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
5704 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
5705 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
27c868c2 5706 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
629d688d
MW
5707 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
5708 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
5709 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
27c868c2 5710 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
629d688d
MW
5711 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
5712 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
5713 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
27c868c2 5714 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
629d688d
MW
5715 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
5716 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
5717 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
27c868c2 5718 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
629d688d
MW
5719 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
5720 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
5721 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
27c868c2 5722 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
629d688d
MW
5723 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
5724 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
5725 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
27c868c2 5726 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
629d688d
MW
5727 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
5728 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
5729 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
27c868c2 5730 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
629d688d
MW
5731 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
5732 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
5733 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
27c868c2 5734 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
629d688d
MW
5735 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
5736 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
5737 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
27c868c2 5738 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
629d688d
MW
5739 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
5740 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
5741 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
27c868c2 5742 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
629d688d
MW
5743 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
5744 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
5745 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
27c868c2 5746 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
629d688d
MW
5747 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
5748 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
5749 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
27c868c2 5750 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
629d688d
MW
5751 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
5752 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
5753 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
27c868c2 5754 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
629d688d
MW
5755 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
5756 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
5757 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
27c868c2 5758 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
629d688d
MW
5759 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
5760 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
5761 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
27c868c2 5762 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
629d688d
MW
5763 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
5764 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
5765 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
27c868c2 5766 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
629d688d
MW
5767 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
5768 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
5769 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
27c868c2 5770 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
629d688d
MW
5771 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5772 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
5773 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
27c868c2 5774 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
629d688d
MW
5775 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
5776 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5777 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
27c868c2 5778 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
629d688d
MW
5779 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
5780 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
5781 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
27c868c2 5782 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
629d688d
MW
5783 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
5784 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5785 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
27c868c2 5786 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
629d688d
MW
5787 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
5788 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5789 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
27c868c2 5790 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
629d688d
MW
5791 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
5792 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
5793 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
27c868c2 5794 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
629d688d
MW
5795 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
5796 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
5797 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
27c868c2 5798 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
629d688d
MW
5799 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
5800 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
5801 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
27c868c2 5802 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
629d688d
MW
5803 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
5804 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
5805 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
27c868c2 5806 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
629d688d
MW
5807 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
5808 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
5809 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
27c868c2 5810 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
629d688d
MW
5811 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
5812 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
5813 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
27c868c2 5814 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
629d688d
MW
5815 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
5816 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
5817 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
27c868c2 5818 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
629d688d
MW
5819 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
5820 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
5821 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
27c868c2 5822 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
629d688d
MW
5823 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
5824 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
5825 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
27c868c2 5826 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
629d688d
MW
5827 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
5828 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
5829 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
27c868c2 5830 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
629d688d
MW
5831 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
5832 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
5833 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
27c868c2 5834 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
629d688d
MW
5835 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
5836 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
5837 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
27c868c2 5838 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
629d688d
MW
5839 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
5840 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
5841 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
27c868c2 5842 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
629d688d
MW
5843 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
5844 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
5845 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
27c868c2 5846 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
629d688d
MW
5847 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
5848 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5849 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
27c868c2 5850 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
629d688d
MW
5851 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5852 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
5853 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
27c868c2 5854 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
629d688d
MW
5855 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
5856 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
5857 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
27c868c2 5858 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
629d688d
MW
5859 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
5860 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
5861 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
27c868c2 5862 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
629d688d
MW
5863 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
5864 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
5865 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
27c868c2 5866 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
629d688d
MW
5867 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
5868 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
5869 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
27c868c2 5870 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
629d688d
MW
5871 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
5872 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
5873 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
27c868c2 5874 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
629d688d
MW
5875 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
5876 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
5877 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
27c868c2 5878 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
629d688d
MW
5879 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5880 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
5881 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
27c868c2 5882 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
629d688d
MW
5883 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
5884 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
5885 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
27c868c2 5886 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
629d688d
MW
5887 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
5888 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
5889 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
27c868c2 5890 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
629d688d
MW
5891 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
5892 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
5893 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
27c868c2 5894 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
629d688d
MW
5895 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
5896 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
5897 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
27c868c2 5898 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
629d688d
MW
5899 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
5900 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
5901 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
27c868c2 5902 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
629d688d
MW
5903 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
5904 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
5905 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
27c868c2 5906 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
629d688d
MW
5907 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
5908 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
5909 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
27c868c2 5910 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
629d688d
MW
5911 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
5912 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
5913 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
27c868c2 5914 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
629d688d
MW
5915 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
5916 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
5917 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
27c868c2 5918 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
629d688d
MW
5919 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
5920 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
5921 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
27c868c2 5922 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
629d688d
MW
5923 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
5924 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
5925 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
27c868c2 5926 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
629d688d
MW
5927 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
5928 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
5929 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
27c868c2 5930 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
629d688d
MW
5931 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
5932 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
5933 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
27c868c2 5934 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
629d688d
MW
5935 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
5936 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
5937 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
27c868c2 5938 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
629d688d
MW
5939 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
5940 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
5941 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
27c868c2 5942 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
629d688d
MW
5943 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
5944 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
5945 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
27c868c2 5946 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
5947};
5948
27c868c2
MW
5949static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
5950static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
5951
5952/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
5953static unsigned char _adv_asc38C1600_buf[] = {
5954 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
629d688d
MW
5955 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
5956 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
5957 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
27c868c2 5958 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
629d688d
MW
5959 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
5960 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
5961 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
27c868c2 5962 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
629d688d
MW
5963 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
5964 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
5965 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
27c868c2 5966 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
629d688d
MW
5967 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
5968 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
5969 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
27c868c2 5970 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
629d688d
MW
5971 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
5972 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
5973 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
27c868c2 5974 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
629d688d
MW
5975 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
5976 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
5977 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
27c868c2 5978 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
629d688d
MW
5979 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
5980 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
5981 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
27c868c2 5982 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
629d688d
MW
5983 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
5984 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
5985 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
27c868c2 5986 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
629d688d
MW
5987 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
5988 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
5989 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
27c868c2 5990 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
629d688d
MW
5991 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
5992 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
5993 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
27c868c2 5994 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
629d688d
MW
5995 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
5996 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
5997 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
27c868c2 5998 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
5999 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
6000 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
6001 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
27c868c2 6002 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
6003 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
6004 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
6005 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
27c868c2 6006 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
629d688d
MW
6007 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
6008 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
6009 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
27c868c2 6010 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
629d688d
MW
6011 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
6012 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
6013 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
27c868c2 6014 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
629d688d
MW
6015 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
6016 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
6017 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
27c868c2 6018 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
629d688d
MW
6019 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
6020 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
6021 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
27c868c2 6022 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
629d688d
MW
6023 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
6024 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
6025 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
27c868c2 6026 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
629d688d
MW
6027 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
6028 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
6029 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
27c868c2 6030 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
629d688d
MW
6031 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
6032 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
6033 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
27c868c2 6034 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
629d688d
MW
6035 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
6036 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
6037 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
27c868c2 6038 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
629d688d
MW
6039 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
6040 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
6041 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
27c868c2 6042 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
629d688d
MW
6043 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
6044 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
6045 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
27c868c2 6046 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
629d688d
MW
6047 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
6048 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
6049 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
27c868c2 6050 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
629d688d
MW
6051 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
6052 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
6053 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
27c868c2 6054 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
629d688d
MW
6055 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
6056 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
6057 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
27c868c2 6058 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
629d688d
MW
6059 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
6060 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
6061 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
27c868c2 6062 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
629d688d
MW
6063 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
6064 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
6065 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
27c868c2 6066 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
629d688d
MW
6067 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
6068 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
6069 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
27c868c2 6070 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
629d688d
MW
6071 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
6072 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
6073 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
27c868c2 6074 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
629d688d
MW
6075 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
6076 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
6077 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
27c868c2 6078 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
629d688d
MW
6079 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
6080 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
6081 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
27c868c2 6082 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
629d688d
MW
6083 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
6084 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
6085 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
27c868c2 6086 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
629d688d
MW
6087 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
6088 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
6089 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
27c868c2 6090 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
629d688d
MW
6091 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
6092 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
6093 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
27c868c2 6094 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
629d688d
MW
6095 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
6096 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
6097 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
27c868c2 6098 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
629d688d
MW
6099 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
6100 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
6101 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
27c868c2 6102 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
629d688d
MW
6103 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
6104 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
6105 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
27c868c2 6106 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
629d688d
MW
6107 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
6108 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
6109 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
27c868c2 6110 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
629d688d
MW
6111 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
6112 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
6113 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
27c868c2 6114 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
629d688d
MW
6115 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
6116 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
6117 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
27c868c2 6118 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
629d688d
MW
6119 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
6120 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
6121 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 6122 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
629d688d
MW
6123 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
6124 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
6125 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
27c868c2 6126 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
629d688d
MW
6127 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
6128 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
6129 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 6130 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
629d688d
MW
6131 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
6132 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
6133 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
27c868c2 6134 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
629d688d
MW
6135 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
6136 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
6137 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
27c868c2 6138 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
629d688d
MW
6139 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
6140 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
6141 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
27c868c2 6142 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
629d688d
MW
6143 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
6144 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
6145 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
27c868c2 6146 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
629d688d
MW
6147 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
6148 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
6149 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
27c868c2 6150 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
629d688d
MW
6151 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
6152 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
6153 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
27c868c2 6154 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
629d688d
MW
6155 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
6156 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
6157 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
27c868c2 6158 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
629d688d
MW
6159 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
6160 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
6161 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
27c868c2 6162 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
629d688d
MW
6163 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
6164 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
6165 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
27c868c2 6166 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
629d688d
MW
6167 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
6168 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
6169 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
27c868c2 6170 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
629d688d
MW
6171 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
6172 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
6173 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
27c868c2 6174 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
629d688d
MW
6175 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
6176 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
6177 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
27c868c2 6178 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
629d688d
MW
6179 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
6180 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
6181 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
27c868c2 6182 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
629d688d
MW
6183 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
6184 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
6185 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
27c868c2 6186 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
629d688d
MW
6187 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
6188 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
6189 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
27c868c2 6190 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
629d688d
MW
6191 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
6192 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
6193 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
27c868c2 6194 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
629d688d
MW
6195 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
6196 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
6197 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
27c868c2 6198 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
629d688d
MW
6199 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
6200 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
6201 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
27c868c2 6202 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
629d688d
MW
6203 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
6204 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
6205 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
27c868c2 6206 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
629d688d
MW
6207 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
6208 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
6209 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
27c868c2 6210 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
629d688d
MW
6211 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
6212 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
6213 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
27c868c2 6214 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
629d688d
MW
6215 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
6216 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
6217 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
27c868c2 6218 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
629d688d
MW
6219 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
6220 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
6221 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
27c868c2 6222 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
629d688d
MW
6223 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
6224 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
6225 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
27c868c2 6226 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
629d688d
MW
6227 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
6228 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
6229 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
27c868c2 6230 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
629d688d
MW
6231 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
6232 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
6233 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
27c868c2 6234 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
629d688d
MW
6235 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
6236 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
6237 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
27c868c2 6238 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
629d688d
MW
6239 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
6240 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
6241 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
27c868c2 6242 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
629d688d
MW
6243 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
6244 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
6245 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
27c868c2 6246 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
629d688d
MW
6247 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
6248 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
6249 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
27c868c2 6250 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
629d688d
MW
6251 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
6252 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
6253 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
27c868c2 6254 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
629d688d
MW
6255 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
6256 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
6257 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
27c868c2 6258 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
629d688d
MW
6259 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
6260 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
6261 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
27c868c2 6262 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
629d688d
MW
6263 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
6264 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
6265 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
27c868c2 6266 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
629d688d
MW
6267 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
6268 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
6269 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
27c868c2 6270 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
629d688d
MW
6271 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
6272 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
6273 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
27c868c2 6274 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
629d688d
MW
6275 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
6276 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
6277 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
27c868c2 6278 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
629d688d
MW
6279 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
6280 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
6281 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
27c868c2 6282 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
629d688d
MW
6283 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
6284 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
6285 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
27c868c2 6286 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
629d688d
MW
6287 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
6288 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
6289 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
27c868c2 6290 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
629d688d
MW
6291 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6292 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
6293 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
27c868c2 6294 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
629d688d
MW
6295 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
6296 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
6297 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
27c868c2 6298 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
629d688d
MW
6299 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
6300 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
6301 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
27c868c2 6302 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
629d688d
MW
6303 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
6304 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
6305 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
27c868c2 6306 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
629d688d
MW
6307 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
6308 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
6309 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
27c868c2 6310 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
629d688d
MW
6311 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
6312 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
6313 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
27c868c2 6314 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
629d688d
MW
6315 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
6316 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
6317 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
27c868c2 6318 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
629d688d
MW
6319 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
6320 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
6321 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
27c868c2 6322 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
629d688d
MW
6323 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
6324 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
6325 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
27c868c2 6326 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
629d688d
MW
6327 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
6328 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
6329 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
27c868c2 6330 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
629d688d
MW
6331 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
6332 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
6333 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
27c868c2 6334 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
629d688d
MW
6335 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
6336 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
6337 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
27c868c2 6338 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
629d688d
MW
6339 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
6340 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
6341 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
27c868c2 6342 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
629d688d
MW
6343 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
6344 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
6345 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
27c868c2 6346 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
629d688d
MW
6347 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
6348 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
6349 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
27c868c2 6350 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
629d688d
MW
6351 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
6352 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
6353 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
27c868c2 6354 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
629d688d
MW
6355 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
6356 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
6357 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
27c868c2 6358 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
629d688d
MW
6359 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
6360 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
6361 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
27c868c2 6362 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
629d688d
MW
6363 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
6364 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
6365 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
27c868c2 6366 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
629d688d
MW
6367 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
6368 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
6369 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
27c868c2 6370 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
629d688d
MW
6371 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
6372 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
6373 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
27c868c2 6374 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
629d688d
MW
6375 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
6376 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
6377 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
27c868c2 6378 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
629d688d
MW
6379 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
6380 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
6381 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
27c868c2 6382 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
629d688d
MW
6383 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
6384 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
6385 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
27c868c2 6386 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
629d688d
MW
6387 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
6388 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6389 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
27c868c2 6390 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
629d688d
MW
6391 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
6392 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
6393 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
27c868c2 6394 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
629d688d
MW
6395 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
6396 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
6397 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
27c868c2 6398 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
629d688d
MW
6399 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
6400 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
6401 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
27c868c2 6402 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
629d688d
MW
6403 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
6404 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
6405 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
27c868c2 6406 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
629d688d
MW
6407 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
6408 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
6409 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
27c868c2 6410 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
629d688d
MW
6411 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
6412 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
6413 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
27c868c2 6414 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
629d688d
MW
6415 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
6416 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
6417 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
27c868c2 6418 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
629d688d
MW
6419 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
6420 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
6421 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
27c868c2 6422 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
629d688d
MW
6423 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
6424 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
6425 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
27c868c2 6426 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
629d688d
MW
6427 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
6428 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
6429 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
27c868c2 6430 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
629d688d
MW
6431 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
6432 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
6433 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
27c868c2 6434 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
629d688d
MW
6435 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
6436 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
6437 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
27c868c2 6438 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
629d688d
MW
6439 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
6440 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
6441 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
27c868c2 6442 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
629d688d
MW
6443 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
6444 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
6445 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
27c868c2 6446 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
629d688d
MW
6447 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
6448 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
6449 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
27c868c2 6450 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
629d688d
MW
6451 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
6452 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
6453 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
27c868c2 6454 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
629d688d
MW
6455 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
6456 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
6457 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
27c868c2 6458 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
629d688d
MW
6459 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
6460 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
6461 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
27c868c2 6462 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
629d688d
MW
6463 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
6464 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
6465 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
27c868c2 6466 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
629d688d
MW
6467 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
6468 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
6469 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
27c868c2 6470 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
629d688d
MW
6471 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
6472 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
6473 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 6474 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
6475 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6476 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6477 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 6478 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
6479 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
6480 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
6481 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
6482};
6483
51219358
MW
6484static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
6485static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
6486
6487static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6488{
6489 PortAddr iop_base;
6490 int i;
6491 ushort lram_addr;
6492
6493 iop_base = asc_dvc->iop_base;
6494 AscPutRiscVarFreeQHead(iop_base, 1);
6495 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6496 AscPutVarFreeQHead(iop_base, 1);
6497 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6498 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6499 (uchar)((int)asc_dvc->max_total_qng + 1));
6500 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6501 (uchar)((int)asc_dvc->max_total_qng + 2));
6502 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
6503 asc_dvc->max_total_qng);
6504 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6505 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6506 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6507 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6508 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6509 AscPutQDoneInProgress(iop_base, 0);
6510 lram_addr = ASC_QADR_BEG;
6511 for (i = 0; i < 32; i++, lram_addr += 2) {
6512 AscWriteLramWord(iop_base, lram_addr, 0);
6513 }
6514}
6515
6516static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6517{
6518 int i;
6519 ushort warn_code;
6520 PortAddr iop_base;
6521 ASC_PADDR phy_addr;
6522 ASC_DCNT phy_size;
6523
6524 iop_base = asc_dvc->iop_base;
6525 warn_code = 0;
6526 for (i = 0; i <= ASC_MAX_TID; i++) {
6527 AscPutMCodeInitSDTRAtID(iop_base, i,
6528 asc_dvc->cfg->sdtr_period_offset[i]);
6529 }
6530
6531 AscInitQLinkVar(asc_dvc);
6532 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
6533 asc_dvc->cfg->disc_enable);
6534 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
6535 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
6536
6537 /* Align overrun buffer on an 8 byte boundary. */
6538 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
6539 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
6540 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
6541 (uchar *)&phy_addr, 1);
6542 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
6543 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
6544 (uchar *)&phy_size, 1);
6545
6546 asc_dvc->cfg->mcode_date =
6547 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
6548 asc_dvc->cfg->mcode_version =
6549 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
6550
6551 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6552 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6553 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
6554 return warn_code;
6555 }
6556 if (AscStartChip(iop_base) != 1) {
6557 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6558 return warn_code;
6559 }
6560
6561 return warn_code;
6562}
6563
6564static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6565{
6566 ushort warn_code;
6567 PortAddr iop_base;
6568
6569 iop_base = asc_dvc->iop_base;
6570 warn_code = 0;
6571 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
6572 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
6573 AscResetChipAndScsiBus(asc_dvc);
6574 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6575 }
6576 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
6577 if (asc_dvc->err_code != 0)
6578 return UW_ERR;
6579 if (!AscFindSignature(asc_dvc->iop_base)) {
6580 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
6581 return warn_code;
6582 }
6583 AscDisableInterrupt(iop_base);
6584 warn_code |= AscInitLram(asc_dvc);
6585 if (asc_dvc->err_code != 0)
6586 return UW_ERR;
6587 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
6588 (ulong)_asc_mcode_chksum);
6589 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
6590 _asc_mcode_size) != _asc_mcode_chksum) {
6591 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
6592 return warn_code;
6593 }
6594 warn_code |= AscInitMicroCodeVar(asc_dvc);
6595 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
6596 AscEnableInterrupt(iop_base);
6597 return warn_code;
6598}
6599
6600/*
6601 * Load the Microcode
6602 *
6603 * Write the microcode image to RISC memory starting at address 0.
6604 *
6605 * The microcode is stored compressed in the following format:
6606 *
6607 * 254 word (508 byte) table indexed by byte code followed
6608 * by the following byte codes:
6609 *
6610 * 1-Byte Code:
6611 * 00: Emit word 0 in table.
6612 * 01: Emit word 1 in table.
6613 * .
6614 * FD: Emit word 253 in table.
6615 *
6616 * Multi-Byte Code:
6617 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
6618 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
6619 *
6620 * Returns 0 or an error if the checksum doesn't match
6621 */
6622static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6623 int memsize, int chksum)
6624{
6625 int i, j, end, len = 0;
6626 ADV_DCNT sum;
6627
6628 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6629
6630 for (i = 253 * 2; i < size; i++) {
6631 if (buf[i] == 0xff) {
6632 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
6633 for (j = 0; j < buf[i + 1]; j++) {
6634 AdvWriteWordAutoIncLram(iop_base, word);
6635 len += 2;
6636 }
6637 i += 3;
6638 } else if (buf[i] == 0xfe) {
6639 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
6640 AdvWriteWordAutoIncLram(iop_base, word);
6641 i += 2;
6642 len += 2;
6643 } else {
6644 unsigned char off = buf[i] * 2;
6645 unsigned short word = (buf[off + 1] << 8) | buf[off];
6646 AdvWriteWordAutoIncLram(iop_base, word);
6647 len += 2;
6648 }
6649 }
6650
6651 end = len;
6652
6653 while (len < memsize) {
6654 AdvWriteWordAutoIncLram(iop_base, 0);
6655 len += 2;
6656 }
6657
6658 /* Verify the microcode checksum. */
6659 sum = 0;
6660 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6661
6662 for (len = 0; len < end; len += 2) {
6663 sum += AdvReadWordAutoIncLram(iop_base);
6664 }
6665
6666 if (sum != chksum)
6667 return ASC_IERR_MCODE_CHKSUM;
6668
6669 return 0;
6670}
6671
6672/*
6673 * DvcGetPhyAddr()
6674 *
6675 * Return the physical address of 'vaddr' and set '*lenp' to the
6676 * number of physically contiguous bytes that follow 'vaddr'.
6677 * 'flag' indicates the type of structure whose physical address
6678 * is being translated.
6679 *
6680 * Note: Because Linux currently doesn't page the kernel and all
6681 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6682 */
6683ADV_PADDR
6684DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
6685 uchar *vaddr, ADV_SDCNT *lenp, int flag)
6686{
6687 ADV_PADDR paddr = virt_to_bus(vaddr);
6688
6689 ASC_DBG4(4, "DvcGetPhyAddr: vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n",
6690 vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr);
6691
6692 return paddr;
6693}
6694
6695static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6696{
6697 ADV_CARR_T *carrp;
6698 ADV_SDCNT buf_size;
6699 ADV_PADDR carr_paddr;
6700
6701 BUG_ON(!asc_dvc->carrier_buf);
6702
6703 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
6704 asc_dvc->carr_freelist = NULL;
6705 if (carrp == asc_dvc->carrier_buf) {
6706 buf_size = ADV_CARRIER_BUFSIZE;
6707 } else {
6708 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
6709 }
6710
6711 do {
6712 /* Get physical address of the carrier 'carrp'. */
6713 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
6714 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
6715 (uchar *)carrp,
6716 (ADV_SDCNT *)&contig_len,
6717 ADV_IS_CARRIER_FLAG));
6718
6719 buf_size -= sizeof(ADV_CARR_T);
6720
6721 /*
6722 * If the current carrier is not physically contiguous, then
6723 * maybe there was a page crossing. Try the next carrier
6724 * aligned start address.
6725 */
6726 if (contig_len < sizeof(ADV_CARR_T)) {
6727 carrp++;
6728 continue;
6729 }
6730
6731 carrp->carr_pa = carr_paddr;
6732 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6733
6734 /*
6735 * Insert the carrier at the beginning of the freelist.
6736 */
6737 carrp->next_vpa =
6738 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6739 asc_dvc->carr_freelist = carrp;
6740
6741 carrp++;
6742 } while (buf_size > 0);
6743}
6744
6745/*
6746 * Send an idle command to the chip and wait for completion.
6747 *
6748 * Command completion is polled for once per microsecond.
6749 *
6750 * The function can be called from anywhere including an interrupt handler.
6751 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
6752 * functions to prevent reentrancy.
6753 *
6754 * Return Values:
6755 * ADV_TRUE - command completed successfully
6756 * ADV_FALSE - command failed
6757 * ADV_ERROR - command timed out
6758 */
6759static int
6760AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6761 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6762{
6763 int result;
6764 ADV_DCNT i, j;
6765 AdvPortAddr iop_base;
6766
6767 iop_base = asc_dvc->iop_base;
6768
6769 /*
6770 * Clear the idle command status which is set by the microcode
6771 * to a non-zero value to indicate when the command is completed.
6772 * The non-zero result is one of the IDLE_CMD_STATUS_* values
6773 */
6774 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6775
6776 /*
6777 * Write the idle command value after the idle command parameter
6778 * has been written to avoid a race condition. If the order is not
6779 * followed, the microcode may process the idle command before the
6780 * parameters have been written to LRAM.
6781 */
6782 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
6783 cpu_to_le32(idle_cmd_parameter));
6784 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
6785
6786 /*
6787 * Tickle the RISC to tell it to process the idle command.
6788 */
6789 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6790 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6791 /*
6792 * Clear the tickle value. In the ASC-3550 the RISC flag
6793 * command 'clr_tickle_b' does not work unless the host
6794 * value is cleared.
6795 */
6796 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6797 }
6798
6799 /* Wait for up to 100 millisecond for the idle command to timeout. */
6800 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
6801 /* Poll once each microsecond for command completion. */
6802 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
6803 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
6804 result);
6805 if (result != 0)
6806 return result;
6807 udelay(1);
6808 }
6809 }
6810
6811 BUG(); /* The idle command should never timeout. */
6812 return ADV_ERROR;
6813}
6814
6815/*
6816 * Reset SCSI Bus and purge all outstanding requests.
6817 *
6818 * Return Value:
6819 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
6820 * ADV_FALSE(0) - Microcode command failed.
6821 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
6822 * may be hung which requires driver recovery.
6823 */
6824static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6825{
6826 int status;
6827
6828 /*
6829 * Send the SCSI Bus Reset idle start idle command which asserts
6830 * the SCSI Bus Reset signal.
6831 */
6832 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6833 if (status != ADV_TRUE) {
6834 return status;
6835 }
6836
6837 /*
6838 * Delay for the specified SCSI Bus Reset hold time.
6839 *
6840 * The hold time delay is done on the host because the RISC has no
6841 * microsecond accurate timer.
6842 */
6843 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6844
6845 /*
6846 * Send the SCSI Bus Reset end idle command which de-asserts
6847 * the SCSI Bus Reset signal and purges any pending requests.
6848 */
6849 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6850 if (status != ADV_TRUE) {
6851 return status;
6852 }
6853
6854 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6855
6856 return status;
6857}
6858
6859/*
6860 * Initialize the ASC-3550.
6861 *
6862 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6863 *
6864 * For a non-fatal error return a warning code. If there are no warnings
6865 * then 0 is returned.
6866 *
6867 * Needed after initialization for error recovery.
6868 */
6869static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6870{
6871 AdvPortAddr iop_base;
6872 ushort warn_code;
6873 int begin_addr;
6874 int end_addr;
6875 ushort code_sum;
6876 int word;
6877 int i;
6878 ushort scsi_cfg1;
6879 uchar tid;
6880 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
6881 ushort wdtr_able = 0, sdtr_able, tagqng_able;
6882 uchar max_cmd[ADV_MAX_TID + 1];
6883
6884 /* If there is already an error, don't continue. */
6885 if (asc_dvc->err_code != 0)
6886 return ADV_ERROR;
6887
6888 /*
6889 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6890 */
6891 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6892 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6893 return ADV_ERROR;
6894 }
6895
6896 warn_code = 0;
6897 iop_base = asc_dvc->iop_base;
6898
6899 /*
6900 * Save the RISC memory BIOS region before writing the microcode.
6901 * The BIOS may already be loaded and using its RISC LRAM region
6902 * so its region must be saved and restored.
6903 *
6904 * Note: This code makes the assumption, which is currently true,
6905 * that a chip reset does not clear RISC LRAM.
6906 */
6907 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6908 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6909 bios_mem[i]);
6910 }
6911
6912 /*
6913 * Save current per TID negotiated values.
6914 */
6915 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6916 ushort bios_version, major, minor;
6917
6918 bios_version =
6919 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
6920 major = (bios_version >> 12) & 0xF;
6921 minor = (bios_version >> 8) & 0xF;
6922 if (major < 3 || (major == 3 && minor == 1)) {
6923 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
6924 AdvReadWordLram(iop_base, 0x120, wdtr_able);
6925 } else {
6926 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6927 }
6928 }
6929 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6930 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6931 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6932 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
6933 max_cmd[tid]);
6934 }
6935
6936 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
6937 _adv_asc3550_size, ADV_3550_MEMSIZE,
6938 _adv_asc3550_chksum);
6939 if (asc_dvc->err_code)
6940 return ADV_ERROR;
6941
6942 /*
6943 * Restore the RISC memory BIOS region.
6944 */
6945 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6946 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6947 bios_mem[i]);
6948 }
6949
6950 /*
6951 * Calculate and write the microcode code checksum to the microcode
6952 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6953 */
6954 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
6955 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
6956 code_sum = 0;
6957 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
6958 for (word = begin_addr; word < end_addr; word += 2) {
6959 code_sum += AdvReadWordAutoIncLram(iop_base);
6960 }
6961 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6962
6963 /*
6964 * Read and save microcode version and date.
6965 */
6966 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
6967 asc_dvc->cfg->mcode_date);
6968 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
6969 asc_dvc->cfg->mcode_version);
6970
6971 /*
6972 * Set the chip type to indicate the ASC3550.
6973 */
6974 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6975
6976 /*
6977 * If the PCI Configuration Command Register "Parity Error Response
6978 * Control" Bit was clear (0), then set the microcode variable
6979 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
6980 * to ignore DMA parity errors.
6981 */
6982 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
6983 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6984 word |= CONTROL_FLAG_IGNORE_PERR;
6985 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6986 }
6987
6988 /*
6989 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
6990 * threshold of 128 bytes. This register is only accessible to the host.
6991 */
6992 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6993 START_CTL_EMFU | READ_CMD_MRM);
6994
6995 /*
6996 * Microcode operating variables for WDTR, SDTR, and command tag
6997 * queuing will be set in slave_configure() based on what a
6998 * device reports it is capable of in Inquiry byte 7.
6999 *
7000 * If SCSI Bus Resets have been disabled, then directly set
7001 * SDTR and WDTR from the EEPROM configuration. This will allow
7002 * the BIOS and warm boot to work without a SCSI bus hang on
7003 * the Inquiry caused by host and target mismatched DTR values.
7004 * Without the SCSI Bus Reset, before an Inquiry a device can't
7005 * be assumed to be in Asynchronous, Narrow mode.
7006 */
7007 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7008 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7009 asc_dvc->wdtr_able);
7010 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7011 asc_dvc->sdtr_able);
7012 }
7013
7014 /*
7015 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
7016 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
7017 * bitmask. These values determine the maximum SDTR speed negotiated
7018 * with a device.
7019 *
7020 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7021 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7022 * without determining here whether the device supports SDTR.
7023 *
7024 * 4-bit speed SDTR speed name
7025 * =========== ===============
7026 * 0000b (0x0) SDTR disabled
7027 * 0001b (0x1) 5 Mhz
7028 * 0010b (0x2) 10 Mhz
7029 * 0011b (0x3) 20 Mhz (Ultra)
7030 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
7031 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
7032 * 0110b (0x6) Undefined
7033 * .
7034 * 1111b (0xF) Undefined
7035 */
7036 word = 0;
7037 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7038 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
7039 /* Set Ultra speed for TID 'tid'. */
7040 word |= (0x3 << (4 * (tid % 4)));
7041 } else {
7042 /* Set Fast speed for TID 'tid'. */
7043 word |= (0x2 << (4 * (tid % 4)));
7044 }
7045 if (tid == 3) { /* Check if done with sdtr_speed1. */
7046 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
7047 word = 0;
7048 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
7049 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
7050 word = 0;
7051 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
7052 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
7053 word = 0;
7054 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
7055 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
7056 /* End of loop. */
7057 }
7058 }
7059
7060 /*
7061 * Set microcode operating variable for the disconnect per TID bitmask.
7062 */
7063 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7064 asc_dvc->cfg->disc_enable);
7065
7066 /*
7067 * Set SCSI_CFG0 Microcode Default Value.
7068 *
7069 * The microcode will set the SCSI_CFG0 register using this value
7070 * after it is started below.
7071 */
7072 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7073 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7074 asc_dvc->chip_scsi_id);
7075
7076 /*
7077 * Determine SCSI_CFG1 Microcode Default Value.
7078 *
7079 * The microcode will set the SCSI_CFG1 register using this value
7080 * after it is started below.
7081 */
7082
7083 /* Read current SCSI_CFG1 Register value. */
7084 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7085
7086 /*
7087 * If all three connectors are in use, return an error.
7088 */
7089 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
7090 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
7091 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
7092 return ADV_ERROR;
7093 }
7094
7095 /*
7096 * If the internal narrow cable is reversed all of the SCSI_CTRL
7097 * register signals will be set. Check for and return an error if
7098 * this condition is found.
7099 */
7100 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7101 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7102 return ADV_ERROR;
7103 }
7104
7105 /*
7106 * If this is a differential board and a single-ended device
7107 * is attached to one of the connectors, return an error.
7108 */
7109 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
7110 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
7111 return ADV_ERROR;
7112 }
7113
7114 /*
7115 * If automatic termination control is enabled, then set the
7116 * termination value based on a table listed in a_condor.h.
7117 *
7118 * If manual termination was specified with an EEPROM setting
7119 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
7120 * is ready to be 'ored' into SCSI_CFG1.
7121 */
7122 if (asc_dvc->cfg->termination == 0) {
7123 /*
7124 * The software always controls termination by setting TERM_CTL_SEL.
7125 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
7126 */
7127 asc_dvc->cfg->termination |= TERM_CTL_SEL;
7128
7129 switch (scsi_cfg1 & CABLE_DETECT) {
7130 /* TERM_CTL_H: on, TERM_CTL_L: on */
7131 case 0x3:
7132 case 0x7:
7133 case 0xB:
7134 case 0xD:
7135 case 0xE:
7136 case 0xF:
7137 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
7138 break;
7139
7140 /* TERM_CTL_H: on, TERM_CTL_L: off */
7141 case 0x1:
7142 case 0x5:
7143 case 0x9:
7144 case 0xA:
7145 case 0xC:
7146 asc_dvc->cfg->termination |= TERM_CTL_H;
7147 break;
7148
7149 /* TERM_CTL_H: off, TERM_CTL_L: off */
7150 case 0x2:
7151 case 0x6:
7152 break;
7153 }
7154 }
7155
7156 /*
7157 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
7158 */
7159 scsi_cfg1 &= ~TERM_CTL;
7160
7161 /*
7162 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
7163 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
7164 * referenced, because the hardware internally inverts
7165 * the Termination High and Low bits if TERM_POL is set.
7166 */
7167 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
7168
7169 /*
7170 * Set SCSI_CFG1 Microcode Default Value
7171 *
7172 * Set filter value and possibly modified termination control
7173 * bits in the Microcode SCSI_CFG1 Register Value.
7174 *
7175 * The microcode will set the SCSI_CFG1 register using this value
7176 * after it is started below.
7177 */
7178 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
7179 FLTR_DISABLE | scsi_cfg1);
7180
7181 /*
7182 * Set MEM_CFG Microcode Default Value
7183 *
7184 * The microcode will set the MEM_CFG register using this value
7185 * after it is started below.
7186 *
7187 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7188 * are defined.
7189 *
7190 * ASC-3550 has 8KB internal memory.
7191 */
7192 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7193 BIOS_EN | RAM_SZ_8KB);
7194
7195 /*
7196 * Set SEL_MASK Microcode Default Value
7197 *
7198 * The microcode will set the SEL_MASK register using this value
7199 * after it is started below.
7200 */
7201 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7202 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7203
7204 AdvBuildCarrierFreelist(asc_dvc);
7205
7206 /*
7207 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7208 */
7209
7210 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7211 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7212 return ADV_ERROR;
7213 }
7214 asc_dvc->carr_freelist = (ADV_CARR_T *)
7215 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7216
7217 /*
7218 * The first command issued will be placed in the stopper carrier.
7219 */
7220 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7221
7222 /*
7223 * Set RISC ICQ physical address start value.
7224 */
7225 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7226
7227 /*
7228 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7229 */
7230 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7231 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7232 return ADV_ERROR;
7233 }
7234 asc_dvc->carr_freelist = (ADV_CARR_T *)
7235 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7236
7237 /*
7238 * The first command completed by the RISC will be placed in
7239 * the stopper.
7240 *
7241 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7242 * completed the RISC will set the ASC_RQ_STOPPER bit.
7243 */
7244 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7245
7246 /*
7247 * Set RISC IRQ physical address start value.
7248 */
7249 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7250 asc_dvc->carr_pending_cnt = 0;
7251
7252 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7253 (ADV_INTR_ENABLE_HOST_INTR |
7254 ADV_INTR_ENABLE_GLOBAL_INTR));
7255
7256 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7257 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7258
7259 /* finally, finally, gentlemen, start your engine */
7260 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7261
7262 /*
7263 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7264 * Resets should be performed. The RISC has to be running
7265 * to issue a SCSI Bus Reset.
7266 */
7267 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7268 /*
7269 * If the BIOS Signature is present in memory, restore the
7270 * BIOS Handshake Configuration Table and do not perform
7271 * a SCSI Bus Reset.
7272 */
7273 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7274 0x55AA) {
7275 /*
7276 * Restore per TID negotiated values.
7277 */
7278 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7279 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7280 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7281 tagqng_able);
7282 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7283 AdvWriteByteLram(iop_base,
7284 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7285 max_cmd[tid]);
7286 }
7287 } else {
7288 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7289 warn_code = ASC_WARN_BUSRESET_ERROR;
7290 }
7291 }
7292 }
7293
7294 return warn_code;
7295}
7296
7297/*
7298 * Initialize the ASC-38C0800.
7299 *
7300 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7301 *
7302 * For a non-fatal error return a warning code. If there are no warnings
7303 * then 0 is returned.
7304 *
7305 * Needed after initialization for error recovery.
7306 */
7307static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7308{
7309 AdvPortAddr iop_base;
7310 ushort warn_code;
7311 int begin_addr;
7312 int end_addr;
7313 ushort code_sum;
7314 int word;
7315 int i;
7316 ushort scsi_cfg1;
7317 uchar byte;
7318 uchar tid;
7319 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7320 ushort wdtr_able, sdtr_able, tagqng_able;
7321 uchar max_cmd[ADV_MAX_TID + 1];
7322
7323 /* If there is already an error, don't continue. */
7324 if (asc_dvc->err_code != 0)
7325 return ADV_ERROR;
7326
7327 /*
7328 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7329 */
7330 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7331 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7332 return ADV_ERROR;
7333 }
7334
7335 warn_code = 0;
7336 iop_base = asc_dvc->iop_base;
7337
7338 /*
7339 * Save the RISC memory BIOS region before writing the microcode.
7340 * The BIOS may already be loaded and using its RISC LRAM region
7341 * so its region must be saved and restored.
7342 *
7343 * Note: This code makes the assumption, which is currently true,
7344 * that a chip reset does not clear RISC LRAM.
7345 */
7346 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7347 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7348 bios_mem[i]);
7349 }
7350
7351 /*
7352 * Save current per TID negotiated values.
7353 */
7354 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7355 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7356 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7357 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7358 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7359 max_cmd[tid]);
7360 }
7361
7362 /*
7363 * RAM BIST (RAM Built-In Self Test)
7364 *
7365 * Address : I/O base + offset 0x38h register (byte).
7366 * Function: Bit 7-6(RW) : RAM mode
7367 * Normal Mode : 0x00
7368 * Pre-test Mode : 0x40
7369 * RAM Test Mode : 0x80
7370 * Bit 5 : unused
7371 * Bit 4(RO) : Done bit
7372 * Bit 3-0(RO) : Status
7373 * Host Error : 0x08
7374 * Int_RAM Error : 0x04
7375 * RISC Error : 0x02
7376 * SCSI Error : 0x01
7377 * No Error : 0x00
7378 *
7379 * Note: RAM BIST code should be put right here, before loading the
7380 * microcode and after saving the RISC memory BIOS region.
7381 */
7382
7383 /*
7384 * LRAM Pre-test
7385 *
7386 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7387 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7388 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7389 * to NORMAL_MODE, return an error too.
7390 */
7391 for (i = 0; i < 2; i++) {
7392 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7393 mdelay(10); /* Wait for 10ms before reading back. */
7394 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7395 if ((byte & RAM_TEST_DONE) == 0
7396 || (byte & 0x0F) != PRE_TEST_VALUE) {
7397 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7398 return ADV_ERROR;
7399 }
7400
7401 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7402 mdelay(10); /* Wait for 10ms before reading back. */
7403 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7404 != NORMAL_VALUE) {
7405 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7406 return ADV_ERROR;
7407 }
7408 }
7409
7410 /*
7411 * LRAM Test - It takes about 1.5 ms to run through the test.
7412 *
7413 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7414 * If Done bit not set or Status not 0, save register byte, set the
7415 * err_code, and return an error.
7416 */
7417 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7418 mdelay(10); /* Wait for 10ms before checking status. */
7419
7420 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7421 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7422 /* Get here if Done bit not set or Status not 0. */
7423 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7424 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7425 return ADV_ERROR;
7426 }
7427
7428 /* We need to reset back to normal mode after LRAM test passes. */
7429 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7430
7431 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
7432 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
7433 _adv_asc38C0800_chksum);
7434 if (asc_dvc->err_code)
7435 return ADV_ERROR;
7436
7437 /*
7438 * Restore the RISC memory BIOS region.
7439 */
7440 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7441 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7442 bios_mem[i]);
7443 }
7444
7445 /*
7446 * Calculate and write the microcode code checksum to the microcode
7447 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7448 */
7449 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7450 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7451 code_sum = 0;
7452 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7453 for (word = begin_addr; word < end_addr; word += 2) {
7454 code_sum += AdvReadWordAutoIncLram(iop_base);
7455 }
7456 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7457
7458 /*
7459 * Read microcode version and date.
7460 */
7461 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7462 asc_dvc->cfg->mcode_date);
7463 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7464 asc_dvc->cfg->mcode_version);
7465
7466 /*
7467 * Set the chip type to indicate the ASC38C0800.
7468 */
7469 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7470
7471 /*
7472 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7473 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7474 * cable detection and then we are able to read C_DET[3:0].
7475 *
7476 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7477 * Microcode Default Value' section below.
7478 */
7479 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7480 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7481 scsi_cfg1 | DIS_TERM_DRV);
7482
7483 /*
7484 * If the PCI Configuration Command Register "Parity Error Response
7485 * Control" Bit was clear (0), then set the microcode variable
7486 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7487 * to ignore DMA parity errors.
7488 */
7489 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7490 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7491 word |= CONTROL_FLAG_IGNORE_PERR;
7492 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7493 }
7494
7495 /*
7496 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7497 * bits for the default FIFO threshold.
7498 *
7499 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7500 *
7501 * For DMA Errata #4 set the BC_THRESH_ENB bit.
7502 */
7503 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7504 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7505 READ_CMD_MRM);
7506
7507 /*
7508 * Microcode operating variables for WDTR, SDTR, and command tag
7509 * queuing will be set in slave_configure() based on what a
7510 * device reports it is capable of in Inquiry byte 7.
7511 *
7512 * If SCSI Bus Resets have been disabled, then directly set
7513 * SDTR and WDTR from the EEPROM configuration. This will allow
7514 * the BIOS and warm boot to work without a SCSI bus hang on
7515 * the Inquiry caused by host and target mismatched DTR values.
7516 * Without the SCSI Bus Reset, before an Inquiry a device can't
7517 * be assumed to be in Asynchronous, Narrow mode.
7518 */
7519 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7520 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7521 asc_dvc->wdtr_able);
7522 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7523 asc_dvc->sdtr_able);
7524 }
7525
7526 /*
7527 * Set microcode operating variables for DISC and SDTR_SPEED1,
7528 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7529 * configuration values.
7530 *
7531 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7532 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7533 * without determining here whether the device supports SDTR.
7534 */
7535 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7536 asc_dvc->cfg->disc_enable);
7537 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7538 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7539 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7540 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7541
7542 /*
7543 * Set SCSI_CFG0 Microcode Default Value.
7544 *
7545 * The microcode will set the SCSI_CFG0 register using this value
7546 * after it is started below.
7547 */
7548 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7549 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7550 asc_dvc->chip_scsi_id);
7551
7552 /*
7553 * Determine SCSI_CFG1 Microcode Default Value.
7554 *
7555 * The microcode will set the SCSI_CFG1 register using this value
7556 * after it is started below.
7557 */
7558
7559 /* Read current SCSI_CFG1 Register value. */
7560 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7561
7562 /*
7563 * If the internal narrow cable is reversed all of the SCSI_CTRL
7564 * register signals will be set. Check for and return an error if
7565 * this condition is found.
7566 */
7567 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7568 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7569 return ADV_ERROR;
7570 }
7571
7572 /*
7573 * All kind of combinations of devices attached to one of four
7574 * connectors are acceptable except HVD device attached. For example,
7575 * LVD device can be attached to SE connector while SE device attached
7576 * to LVD connector. If LVD device attached to SE connector, it only
7577 * runs up to Ultra speed.
7578 *
7579 * If an HVD device is attached to one of LVD connectors, return an
7580 * error. However, there is no way to detect HVD device attached to
7581 * SE connectors.
7582 */
7583 if (scsi_cfg1 & HVD) {
7584 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7585 return ADV_ERROR;
7586 }
7587
7588 /*
7589 * If either SE or LVD automatic termination control is enabled, then
7590 * set the termination value based on a table listed in a_condor.h.
7591 *
7592 * If manual termination was specified with an EEPROM setting then
7593 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
7594 * to be 'ored' into SCSI_CFG1.
7595 */
7596 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7597 /* SE automatic termination control is enabled. */
7598 switch (scsi_cfg1 & C_DET_SE) {
7599 /* TERM_SE_HI: on, TERM_SE_LO: on */
7600 case 0x1:
7601 case 0x2:
7602 case 0x3:
7603 asc_dvc->cfg->termination |= TERM_SE;
7604 break;
7605
7606 /* TERM_SE_HI: on, TERM_SE_LO: off */
7607 case 0x0:
7608 asc_dvc->cfg->termination |= TERM_SE_HI;
7609 break;
7610 }
7611 }
7612
7613 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
7614 /* LVD automatic termination control is enabled. */
7615 switch (scsi_cfg1 & C_DET_LVD) {
7616 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
7617 case 0x4:
7618 case 0x8:
7619 case 0xC:
7620 asc_dvc->cfg->termination |= TERM_LVD;
7621 break;
7622
7623 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7624 case 0x0:
7625 break;
7626 }
7627 }
7628
7629 /*
7630 * Clear any set TERM_SE and TERM_LVD bits.
7631 */
7632 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7633
7634 /*
7635 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7636 */
7637 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7638
7639 /*
7640 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
7641 * bits and set possibly modified termination control bits in the
7642 * Microcode SCSI_CFG1 Register Value.
7643 */
7644 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7645
7646 /*
7647 * Set SCSI_CFG1 Microcode Default Value
7648 *
7649 * Set possibly modified termination control and reset DIS_TERM_DRV
7650 * bits in the Microcode SCSI_CFG1 Register Value.
7651 *
7652 * The microcode will set the SCSI_CFG1 register using this value
7653 * after it is started below.
7654 */
7655 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7656
7657 /*
7658 * Set MEM_CFG Microcode Default Value
7659 *
7660 * The microcode will set the MEM_CFG register using this value
7661 * after it is started below.
7662 *
7663 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7664 * are defined.
7665 *
7666 * ASC-38C0800 has 16KB internal memory.
7667 */
7668 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7669 BIOS_EN | RAM_SZ_16KB);
7670
7671 /*
7672 * Set SEL_MASK Microcode Default Value
7673 *
7674 * The microcode will set the SEL_MASK register using this value
7675 * after it is started below.
7676 */
7677 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7678 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7679
7680 AdvBuildCarrierFreelist(asc_dvc);
7681
7682 /*
7683 * Set-up the Host->RISC Initiator Command Queue (ICQ).
7684 */
7685
7686 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7687 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7688 return ADV_ERROR;
7689 }
7690 asc_dvc->carr_freelist = (ADV_CARR_T *)
7691 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7692
7693 /*
7694 * The first command issued will be placed in the stopper carrier.
7695 */
7696 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7697
7698 /*
7699 * Set RISC ICQ physical address start value.
7700 * carr_pa is LE, must be native before write
7701 */
7702 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7703
7704 /*
7705 * Set-up the RISC->Host Initiator Response Queue (IRQ).
7706 */
7707 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7708 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7709 return ADV_ERROR;
7710 }
7711 asc_dvc->carr_freelist = (ADV_CARR_T *)
7712 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7713
7714 /*
7715 * The first command completed by the RISC will be placed in
7716 * the stopper.
7717 *
7718 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7719 * completed the RISC will set the ASC_RQ_STOPPER bit.
7720 */
7721 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7722
7723 /*
7724 * Set RISC IRQ physical address start value.
7725 *
7726 * carr_pa is LE, must be native before write *
7727 */
7728 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7729 asc_dvc->carr_pending_cnt = 0;
7730
7731 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7732 (ADV_INTR_ENABLE_HOST_INTR |
7733 ADV_INTR_ENABLE_GLOBAL_INTR));
7734
7735 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7736 AdvWriteWordRegister(iop_base, IOPW_PC, word);
7737
7738 /* finally, finally, gentlemen, start your engine */
7739 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7740
7741 /*
7742 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7743 * Resets should be performed. The RISC has to be running
7744 * to issue a SCSI Bus Reset.
7745 */
7746 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7747 /*
7748 * If the BIOS Signature is present in memory, restore the
7749 * BIOS Handshake Configuration Table and do not perform
7750 * a SCSI Bus Reset.
7751 */
7752 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7753 0x55AA) {
7754 /*
7755 * Restore per TID negotiated values.
7756 */
7757 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7758 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7759 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7760 tagqng_able);
7761 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7762 AdvWriteByteLram(iop_base,
7763 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7764 max_cmd[tid]);
7765 }
7766 } else {
7767 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7768 warn_code = ASC_WARN_BUSRESET_ERROR;
7769 }
7770 }
7771 }
7772
7773 return warn_code;
7774}
7775
7776/*
7777 * Initialize the ASC-38C1600.
7778 *
7779 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7780 *
7781 * For a non-fatal error return a warning code. If there are no warnings
7782 * then 0 is returned.
7783 *
7784 * Needed after initialization for error recovery.
7785 */
7786static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7787{
7788 AdvPortAddr iop_base;
7789 ushort warn_code;
7790 int begin_addr;
7791 int end_addr;
7792 ushort code_sum;
7793 long word;
7794 int i;
7795 ushort scsi_cfg1;
7796 uchar byte;
7797 uchar tid;
7798 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
7799 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
7800 uchar max_cmd[ASC_MAX_TID + 1];
7801
7802 /* If there is already an error, don't continue. */
7803 if (asc_dvc->err_code != 0) {
7804 return ADV_ERROR;
7805 }
7806
7807 /*
7808 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7809 */
7810 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7811 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7812 return ADV_ERROR;
7813 }
7814
7815 warn_code = 0;
7816 iop_base = asc_dvc->iop_base;
7817
7818 /*
7819 * Save the RISC memory BIOS region before writing the microcode.
7820 * The BIOS may already be loaded and using its RISC LRAM region
7821 * so its region must be saved and restored.
7822 *
7823 * Note: This code makes the assumption, which is currently true,
7824 * that a chip reset does not clear RISC LRAM.
7825 */
7826 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7827 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7828 bios_mem[i]);
7829 }
7830
7831 /*
7832 * Save current per TID negotiated values.
7833 */
7834 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7835 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7836 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
7837 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7838 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7839 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7840 max_cmd[tid]);
7841 }
7842
7843 /*
7844 * RAM BIST (Built-In Self Test)
7845 *
7846 * Address : I/O base + offset 0x38h register (byte).
7847 * Function: Bit 7-6(RW) : RAM mode
7848 * Normal Mode : 0x00
7849 * Pre-test Mode : 0x40
7850 * RAM Test Mode : 0x80
7851 * Bit 5 : unused
7852 * Bit 4(RO) : Done bit
7853 * Bit 3-0(RO) : Status
7854 * Host Error : 0x08
7855 * Int_RAM Error : 0x04
7856 * RISC Error : 0x02
7857 * SCSI Error : 0x01
7858 * No Error : 0x00
7859 *
7860 * Note: RAM BIST code should be put right here, before loading the
7861 * microcode and after saving the RISC memory BIOS region.
7862 */
7863
7864 /*
7865 * LRAM Pre-test
7866 *
7867 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7868 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7869 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7870 * to NORMAL_MODE, return an error too.
7871 */
7872 for (i = 0; i < 2; i++) {
7873 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7874 mdelay(10); /* Wait for 10ms before reading back. */
7875 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7876 if ((byte & RAM_TEST_DONE) == 0
7877 || (byte & 0x0F) != PRE_TEST_VALUE) {
7878 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7879 return ADV_ERROR;
7880 }
7881
7882 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7883 mdelay(10); /* Wait for 10ms before reading back. */
7884 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7885 != NORMAL_VALUE) {
7886 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7887 return ADV_ERROR;
7888 }
7889 }
7890
7891 /*
7892 * LRAM Test - It takes about 1.5 ms to run through the test.
7893 *
7894 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7895 * If Done bit not set or Status not 0, save register byte, set the
7896 * err_code, and return an error.
7897 */
7898 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7899 mdelay(10); /* Wait for 10ms before checking status. */
7900
7901 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7902 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7903 /* Get here if Done bit not set or Status not 0. */
7904 asc_dvc->bist_err_code = byte; /* for BIOS display message */
7905 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7906 return ADV_ERROR;
7907 }
7908
7909 /* We need to reset back to normal mode after LRAM test passes. */
7910 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7911
7912 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
7913 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
7914 _adv_asc38C1600_chksum);
7915 if (asc_dvc->err_code)
7916 return ADV_ERROR;
7917
7918 /*
7919 * Restore the RISC memory BIOS region.
7920 */
7921 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7922 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7923 bios_mem[i]);
7924 }
7925
7926 /*
7927 * Calculate and write the microcode code checksum to the microcode
7928 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7929 */
7930 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7931 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7932 code_sum = 0;
7933 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7934 for (word = begin_addr; word < end_addr; word += 2) {
7935 code_sum += AdvReadWordAutoIncLram(iop_base);
7936 }
7937 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7938
7939 /*
7940 * Read microcode version and date.
7941 */
7942 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7943 asc_dvc->cfg->mcode_date);
7944 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7945 asc_dvc->cfg->mcode_version);
7946
7947 /*
7948 * Set the chip type to indicate the ASC38C1600.
7949 */
7950 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7951
7952 /*
7953 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7954 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7955 * cable detection and then we are able to read C_DET[3:0].
7956 *
7957 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7958 * Microcode Default Value' section below.
7959 */
7960 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7961 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7962 scsi_cfg1 | DIS_TERM_DRV);
7963
7964 /*
7965 * If the PCI Configuration Command Register "Parity Error Response
7966 * Control" Bit was clear (0), then set the microcode variable
7967 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7968 * to ignore DMA parity errors.
7969 */
7970 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7971 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7972 word |= CONTROL_FLAG_IGNORE_PERR;
7973 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7974 }
7975
7976 /*
7977 * If the BIOS control flag AIPP (Asynchronous Information
7978 * Phase Protection) disable bit is not set, then set the firmware
7979 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
7980 * AIPP checking and encoding.
7981 */
7982 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
7983 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7984 word |= CONTROL_FLAG_ENABLE_AIPP;
7985 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7986 }
7987
7988 /*
7989 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7990 * and START_CTL_TH [3:2].
7991 */
7992 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7993 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7994
7995 /*
7996 * Microcode operating variables for WDTR, SDTR, and command tag
7997 * queuing will be set in slave_configure() based on what a
7998 * device reports it is capable of in Inquiry byte 7.
7999 *
8000 * If SCSI Bus Resets have been disabled, then directly set
8001 * SDTR and WDTR from the EEPROM configuration. This will allow
8002 * the BIOS and warm boot to work without a SCSI bus hang on
8003 * the Inquiry caused by host and target mismatched DTR values.
8004 * Without the SCSI Bus Reset, before an Inquiry a device can't
8005 * be assumed to be in Asynchronous, Narrow mode.
8006 */
8007 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
8008 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
8009 asc_dvc->wdtr_able);
8010 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
8011 asc_dvc->sdtr_able);
8012 }
8013
8014 /*
8015 * Set microcode operating variables for DISC and SDTR_SPEED1,
8016 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
8017 * configuration values.
8018 *
8019 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
8020 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
8021 * without determining here whether the device supports SDTR.
8022 */
8023 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
8024 asc_dvc->cfg->disc_enable);
8025 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
8026 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
8027 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
8028 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
8029
8030 /*
8031 * Set SCSI_CFG0 Microcode Default Value.
8032 *
8033 * The microcode will set the SCSI_CFG0 register using this value
8034 * after it is started below.
8035 */
8036 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
8037 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
8038 asc_dvc->chip_scsi_id);
8039
8040 /*
8041 * Calculate SCSI_CFG1 Microcode Default Value.
8042 *
8043 * The microcode will set the SCSI_CFG1 register using this value
8044 * after it is started below.
8045 *
8046 * Each ASC-38C1600 function has only two cable detect bits.
8047 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
8048 */
8049 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
8050
8051 /*
8052 * If the cable is reversed all of the SCSI_CTRL register signals
8053 * will be set. Check for and return an error if this condition is
8054 * found.
8055 */
8056 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
8057 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
8058 return ADV_ERROR;
8059 }
8060
8061 /*
8062 * Each ASC-38C1600 function has two connectors. Only an HVD device
8063 * can not be connected to either connector. An LVD device or SE device
8064 * may be connected to either connecor. If an SE device is connected,
8065 * then at most Ultra speed (20 Mhz) can be used on both connectors.
8066 *
8067 * If an HVD device is attached, return an error.
8068 */
8069 if (scsi_cfg1 & HVD) {
8070 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
8071 return ADV_ERROR;
8072 }
8073
8074 /*
8075 * Each function in the ASC-38C1600 uses only the SE cable detect and
8076 * termination because there are two connectors for each function. Each
8077 * function may use either LVD or SE mode. Corresponding the SE automatic
8078 * termination control EEPROM bits are used for each function. Each
8079 * function has its own EEPROM. If SE automatic control is enabled for
8080 * the function, then set the termination value based on a table listed
8081 * in a_condor.h.
8082 *
8083 * If manual termination is specified in the EEPROM for the function,
8084 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
8085 * ready to be 'ored' into SCSI_CFG1.
8086 */
8087 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
8088 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
8089 /* SE automatic termination control is enabled. */
8090 switch (scsi_cfg1 & C_DET_SE) {
8091 /* TERM_SE_HI: on, TERM_SE_LO: on */
8092 case 0x1:
8093 case 0x2:
8094 case 0x3:
8095 asc_dvc->cfg->termination |= TERM_SE;
8096 break;
8097
8098 case 0x0:
8099 if (PCI_FUNC(pdev->devfn) == 0) {
8100 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
8101 } else {
8102 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
8103 asc_dvc->cfg->termination |= TERM_SE_HI;
8104 }
8105 break;
8106 }
8107 }
8108
8109 /*
8110 * Clear any set TERM_SE bits.
8111 */
8112 scsi_cfg1 &= ~TERM_SE;
8113
8114 /*
8115 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
8116 */
8117 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
8118
8119 /*
8120 * Clear Big Endian and Terminator Polarity bits and set possibly
8121 * modified termination control bits in the Microcode SCSI_CFG1
8122 * Register Value.
8123 *
8124 * Big Endian bit is not used even on big endian machines.
8125 */
8126 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
8127
8128 /*
8129 * Set SCSI_CFG1 Microcode Default Value
8130 *
8131 * Set possibly modified termination control bits in the Microcode
8132 * SCSI_CFG1 Register Value.
8133 *
8134 * The microcode will set the SCSI_CFG1 register using this value
8135 * after it is started below.
8136 */
8137 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
8138
8139 /*
8140 * Set MEM_CFG Microcode Default Value
8141 *
8142 * The microcode will set the MEM_CFG register using this value
8143 * after it is started below.
8144 *
8145 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
8146 * are defined.
8147 *
8148 * ASC-38C1600 has 32KB internal memory.
8149 *
8150 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
8151 * out a special 16K Adv Library and Microcode version. After the issue
8152 * resolved, we should turn back to the 32K support. Both a_condor.h and
8153 * mcode.sas files also need to be updated.
8154 *
8155 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8156 * BIOS_EN | RAM_SZ_32KB);
8157 */
8158 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8159 BIOS_EN | RAM_SZ_16KB);
8160
8161 /*
8162 * Set SEL_MASK Microcode Default Value
8163 *
8164 * The microcode will set the SEL_MASK register using this value
8165 * after it is started below.
8166 */
8167 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
8168 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
8169
8170 AdvBuildCarrierFreelist(asc_dvc);
8171
8172 /*
8173 * Set-up the Host->RISC Initiator Command Queue (ICQ).
8174 */
8175 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
8176 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8177 return ADV_ERROR;
8178 }
8179 asc_dvc->carr_freelist = (ADV_CARR_T *)
8180 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
8181
8182 /*
8183 * The first command issued will be placed in the stopper carrier.
8184 */
8185 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8186
8187 /*
8188 * Set RISC ICQ physical address start value. Initialize the
8189 * COMMA register to the same value otherwise the RISC will
8190 * prematurely detect a command is available.
8191 */
8192 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
8193 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8194 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
8195
8196 /*
8197 * Set-up the RISC->Host Initiator Response Queue (IRQ).
8198 */
8199 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
8200 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8201 return ADV_ERROR;
8202 }
8203 asc_dvc->carr_freelist = (ADV_CARR_T *)
8204 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
8205
8206 /*
8207 * The first command completed by the RISC will be placed in
8208 * the stopper.
8209 *
8210 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
8211 * completed the RISC will set the ASC_RQ_STOPPER bit.
8212 */
8213 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8214
8215 /*
8216 * Set RISC IRQ physical address start value.
8217 */
8218 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
8219 asc_dvc->carr_pending_cnt = 0;
8220
8221 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
8222 (ADV_INTR_ENABLE_HOST_INTR |
8223 ADV_INTR_ENABLE_GLOBAL_INTR));
8224 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
8225 AdvWriteWordRegister(iop_base, IOPW_PC, word);
8226
8227 /* finally, finally, gentlemen, start your engine */
8228 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
8229
8230 /*
8231 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
8232 * Resets should be performed. The RISC has to be running
8233 * to issue a SCSI Bus Reset.
8234 */
8235 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
8236 /*
8237 * If the BIOS Signature is present in memory, restore the
8238 * per TID microcode operating variables.
8239 */
8240 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8241 0x55AA) {
8242 /*
8243 * Restore per TID negotiated values.
8244 */
8245 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8246 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8247 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8248 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
8249 tagqng_able);
8250 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
8251 AdvWriteByteLram(iop_base,
8252 ASC_MC_NUMBER_OF_MAX_CMD + tid,
8253 max_cmd[tid]);
8254 }
8255 } else {
8256 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8257 warn_code = ASC_WARN_BUSRESET_ERROR;
8258 }
8259 }
8260 }
8261
8262 return warn_code;
8263}
8264
8265/*
8266 * Reset chip and SCSI Bus.
8267 *
8268 * Return Value:
8269 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
8270 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
8271 */
8272static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8273{
8274 int status;
8275 ushort wdtr_able, sdtr_able, tagqng_able;
8276 ushort ppr_able = 0;
8277 uchar tid, max_cmd[ADV_MAX_TID + 1];
8278 AdvPortAddr iop_base;
8279 ushort bios_sig;
8280
8281 iop_base = asc_dvc->iop_base;
8282
8283 /*
8284 * Save current per TID negotiated values.
8285 */
8286 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8287 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8288 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8289 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8290 }
8291 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8292 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8293 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8294 max_cmd[tid]);
8295 }
8296
8297 /*
8298 * Force the AdvInitAsc3550/38C0800Driver() function to
8299 * perform a SCSI Bus Reset by clearing the BIOS signature word.
8300 * The initialization functions assumes a SCSI Bus Reset is not
8301 * needed if the BIOS signature word is present.
8302 */
8303 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8304 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8305
8306 /*
8307 * Stop chip and reset it.
8308 */
8309 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
8310 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
8311 mdelay(100);
8312 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
8313 ADV_CTRL_REG_CMD_WR_IO_REG);
8314
8315 /*
8316 * Reset Adv Library error code, if any, and try
8317 * re-initializing the chip.
8318 */
8319 asc_dvc->err_code = 0;
8320 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8321 status = AdvInitAsc38C1600Driver(asc_dvc);
8322 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8323 status = AdvInitAsc38C0800Driver(asc_dvc);
8324 } else {
8325 status = AdvInitAsc3550Driver(asc_dvc);
8326 }
8327
8328 /* Translate initialization return value to status value. */
8329 if (status == 0) {
8330 status = ADV_TRUE;
8331 } else {
8332 status = ADV_FALSE;
8333 }
8334
8335 /*
8336 * Restore the BIOS signature word.
8337 */
8338 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8339
8340 /*
8341 * Restore per TID negotiated values.
8342 */
8343 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8344 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8345 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8346 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8347 }
8348 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8349 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8350 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8351 max_cmd[tid]);
8352 }
8353
8354 return status;
8355}
8356
8357/*
8358 * adv_async_callback() - Adv Library asynchronous event callback function.
8359 */
8360static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8361{
8362 switch (code) {
8363 case ADV_ASYNC_SCSI_BUS_RESET_DET:
8364 /*
8365 * The firmware detected a SCSI Bus reset.
8366 */
8367 ASC_DBG(0,
8368 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
8369 break;
8370
8371 case ADV_ASYNC_RDMA_FAILURE:
8372 /*
8373 * Handle RDMA failure by resetting the SCSI Bus and
8374 * possibly the chip if it is unresponsive. Log the error
8375 * with a unique code.
8376 */
8377 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
8378 AdvResetChipAndSB(adv_dvc_varp);
8379 break;
8380
8381 case ADV_HOST_SCSI_BUS_RESET:
8382 /*
8383 * Host generated SCSI bus reset occurred.
8384 */
8385 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
8386 break;
8387
8388 default:
8389 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
8390 break;
8391 }
8392}
8393
8394/*
8395 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8396 *
8397 * Callback function for the Wide SCSI Adv Library.
8398 */
8399static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8400{
8401 asc_board_t *boardp;
8402 adv_req_t *reqp;
8403 adv_sgblk_t *sgblkp;
8404 struct scsi_cmnd *scp;
8405 struct Scsi_Host *shost;
8406 ADV_DCNT resid_cnt;
8407
8408 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
8409 (ulong)adv_dvc_varp, (ulong)scsiqp);
8410 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8411
8412 /*
8413 * Get the adv_req_t structure for the command that has been
8414 * completed. The adv_req_t structure actually contains the
8415 * completed ADV_SCSI_REQ_Q structure.
8416 */
8417 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
8418 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
8419 if (reqp == NULL) {
8420 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8421 return;
8422 }
8423
8424 /*
8425 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8426 * command that has been completed.
8427 *
8428 * Note: The adv_req_t request structure and adv_sgblk_t structure,
8429 * if any, are dropped, because a board structure pointer can not be
8430 * determined.
8431 */
8432 scp = reqp->cmndp;
8433 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
8434 if (scp == NULL) {
8435 ASC_PRINT
8436 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8437 return;
8438 }
8439 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8440
8441 shost = scp->device->host;
8442 ASC_STATS(shost, callback);
8443 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
8444
8445 boardp = ASC_BOARDP(shost);
8446 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8447
8448 /*
8449 * 'done_status' contains the command's ending status.
8450 */
8451 switch (scsiqp->done_status) {
8452 case QD_NO_ERROR:
8453 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
8454 scp->result = 0;
8455
8456 /*
8457 * Check for an underrun condition.
8458 *
8459 * If there was no error and an underrun condition, then
8460 * then return the number of underrun bytes.
8461 */
8462 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8463 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
8464 resid_cnt <= scp->request_bufflen) {
8465 ASC_DBG1(1,
8466 "adv_isr_callback: underrun condition %lu bytes\n",
8467 (ulong)resid_cnt);
8468 scp->resid = resid_cnt;
8469 }
8470 break;
8471
8472 case QD_WITH_ERROR:
8473 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
8474 switch (scsiqp->host_status) {
8475 case QHSTA_NO_ERROR:
8476 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
8477 ASC_DBG(2,
8478 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
8479 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8480 sizeof(scp->sense_buffer));
8481 /*
8482 * Note: The 'status_byte()' macro used by
8483 * target drivers defined in scsi.h shifts the
8484 * status byte returned by host drivers right
8485 * by 1 bit. This is why target drivers also
8486 * use right shifted status byte definitions.
8487 * For instance target drivers use
8488 * CHECK_CONDITION, defined to 0x1, instead of
8489 * the SCSI defined check condition value of
8490 * 0x2. Host drivers are supposed to return
8491 * the status byte as it is defined by SCSI.
8492 */
8493 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8494 STATUS_BYTE(scsiqp->scsi_status);
8495 } else {
8496 scp->result = STATUS_BYTE(scsiqp->scsi_status);
8497 }
8498 break;
8499
8500 default:
8501 /* Some other QHSTA error occurred. */
8502 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
8503 scsiqp->host_status);
8504 scp->result = HOST_BYTE(DID_BAD_TARGET);
8505 break;
8506 }
8507 break;
8508
8509 case QD_ABORTED_BY_HOST:
8510 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
8511 scp->result =
8512 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8513 break;
8514
8515 default:
8516 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
8517 scsiqp->done_status);
8518 scp->result =
8519 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8520 break;
8521 }
8522
8523 /*
8524 * If the 'init_tidmask' bit isn't already set for the target and the
8525 * current request finished normally, then set the bit for the target
8526 * to indicate that a device is present.
8527 */
8528 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
8529 scsiqp->done_status == QD_NO_ERROR &&
8530 scsiqp->host_status == QHSTA_NO_ERROR) {
8531 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
8532 }
8533
8534 asc_scsi_done(scp);
8535
8536 /*
8537 * Free all 'adv_sgblk_t' structures allocated for the request.
8538 */
8539 while ((sgblkp = reqp->sgblkp) != NULL) {
8540 /* Remove 'sgblkp' from the request list. */
8541 reqp->sgblkp = sgblkp->next_sgblkp;
8542
8543 /* Add 'sgblkp' to the board free list. */
8544 sgblkp->next_sgblkp = boardp->adv_sgblkp;
8545 boardp->adv_sgblkp = sgblkp;
8546 }
8547
8548 /*
8549 * Free the adv_req_t structure used with the command by adding
8550 * it back to the board free list.
8551 */
8552 reqp->next_reqp = boardp->adv_reqp;
8553 boardp->adv_reqp = reqp;
8554
8555 ASC_DBG(1, "adv_isr_callback: done\n");
8556
8557 return;
8558}
8559
8560/*
8561 * Adv Library Interrupt Service Routine
8562 *
8563 * This function is called by a driver's interrupt service routine.
8564 * The function disables and re-enables interrupts.
8565 *
8566 * When a microcode idle command is completed, the ADV_DVC_VAR
8567 * 'idle_cmd_done' field is set to ADV_TRUE.
8568 *
8569 * Note: AdvISR() can be called when interrupts are disabled or even
8570 * when there is no hardware interrupt condition present. It will
8571 * always check for completed idle commands and microcode requests.
8572 * This is an important feature that shouldn't be changed because it
8573 * allows commands to be completed from polling mode loops.
8574 *
8575 * Return:
8576 * ADV_TRUE(1) - interrupt was pending
8577 * ADV_FALSE(0) - no interrupt was pending
8578 */
8579static int AdvISR(ADV_DVC_VAR *asc_dvc)
8580{
8581 AdvPortAddr iop_base;
8582 uchar int_stat;
8583 ushort target_bit;
8584 ADV_CARR_T *free_carrp;
8585 ADV_VADDR irq_next_vpa;
8586 ADV_SCSI_REQ_Q *scsiq;
8587
8588 iop_base = asc_dvc->iop_base;
8589
8590 /* Reading the register clears the interrupt. */
8591 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8592
8593 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8594 ADV_INTR_STATUS_INTRC)) == 0) {
8595 return ADV_FALSE;
8596 }
8597
8598 /*
8599 * Notify the driver of an asynchronous microcode condition by
8600 * calling the adv_async_callback function. The function
8601 * is passed the microcode ASC_MC_INTRB_CODE byte value.
8602 */
8603 if (int_stat & ADV_INTR_STATUS_INTRB) {
8604 uchar intrb_code;
8605
8606 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8607
8608 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8609 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8610 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
8611 asc_dvc->carr_pending_cnt != 0) {
8612 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8613 ADV_TICKLE_A);
8614 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8615 AdvWriteByteRegister(iop_base,
8616 IOPB_TICKLE,
8617 ADV_TICKLE_NOP);
8618 }
8619 }
8620 }
8621
8622 adv_async_callback(asc_dvc, intrb_code);
8623 }
8624
8625 /*
8626 * Check if the IRQ stopper carrier contains a completed request.
8627 */
8628 while (((irq_next_vpa =
8629 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8630 /*
8631 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
8632 * The RISC will have set 'areq_vpa' to a virtual address.
8633 *
8634 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
8635 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
8636 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
8637 * in AdvExeScsiQueue().
8638 */
8639 scsiq = (ADV_SCSI_REQ_Q *)
8640 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8641
8642 /*
8643 * Request finished with good status and the queue was not
8644 * DMAed to host memory by the firmware. Set all status fields
8645 * to indicate good status.
8646 */
8647 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
8648 scsiq->done_status = QD_NO_ERROR;
8649 scsiq->host_status = scsiq->scsi_status = 0;
8650 scsiq->data_cnt = 0L;
8651 }
8652
8653 /*
8654 * Advance the stopper pointer to the next carrier
8655 * ignoring the lower four bits. Free the previous
8656 * stopper carrier.
8657 */
8658 free_carrp = asc_dvc->irq_sp;
8659 asc_dvc->irq_sp = (ADV_CARR_T *)
8660 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
8661
8662 free_carrp->next_vpa =
8663 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
8664 asc_dvc->carr_freelist = free_carrp;
8665 asc_dvc->carr_pending_cnt--;
8666
8667 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8668
8669 /*
8670 * Clear request microcode control flag.
8671 */
8672 scsiq->cntl = 0;
8673
8674 /*
8675 * Notify the driver of the completed request by passing
8676 * the ADV_SCSI_REQ_Q pointer to its callback function.
8677 */
8678 scsiq->a_flag |= ADV_SCSIQ_DONE;
8679 adv_isr_callback(asc_dvc, scsiq);
8680 /*
8681 * Note: After the driver callback function is called, 'scsiq'
8682 * can no longer be referenced.
8683 *
8684 * Fall through and continue processing other completed
8685 * requests...
8686 */
8687 }
8688 return ADV_TRUE;
8689}
8690
8691static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8692{
8693 if (asc_dvc->err_code == 0) {
8694 asc_dvc->err_code = err_code;
8695 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8696 err_code);
8697 }
8698 return err_code;
8699}
8700
8701static void AscAckInterrupt(PortAddr iop_base)
8702{
8703 uchar host_flag;
8704 uchar risc_flag;
8705 ushort loop;
8706
8707 loop = 0;
8708 do {
8709 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8710 if (loop++ > 0x7FFF) {
8711 break;
8712 }
8713 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8714 host_flag =
8715 AscReadLramByte(iop_base,
8716 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8717 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8718 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8719 AscSetChipStatus(iop_base, CIW_INT_ACK);
8720 loop = 0;
8721 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8722 AscSetChipStatus(iop_base, CIW_INT_ACK);
8723 if (loop++ > 3) {
8724 break;
8725 }
8726 }
8727 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8728 return;
8729}
8730
8731static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8732{
8733 uchar *period_table;
8734 int max_index;
8735 int min_index;
8736 int i;
8737
8738 period_table = asc_dvc->sdtr_period_tbl;
8739 max_index = (int)asc_dvc->max_sdtr_index;
8740 min_index = (int)asc_dvc->host_init_sdtr_index;
8741 if ((syn_time <= period_table[max_index])) {
8742 for (i = min_index; i < (max_index - 1); i++) {
8743 if (syn_time <= period_table[i]) {
8744 return (uchar)i;
8745 }
8746 }
8747 return (uchar)max_index;
8748 } else {
8749 return (uchar)(max_index + 1);
8750 }
8751}
8752
8753static uchar
8754AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8755{
8756 EXT_MSG sdtr_buf;
8757 uchar sdtr_period_index;
8758 PortAddr iop_base;
8759
8760 iop_base = asc_dvc->iop_base;
8761 sdtr_buf.msg_type = EXTENDED_MESSAGE;
8762 sdtr_buf.msg_len = MS_SDTR_LEN;
8763 sdtr_buf.msg_req = EXTENDED_SDTR;
8764 sdtr_buf.xfer_period = sdtr_period;
8765 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8766 sdtr_buf.req_ack_offset = sdtr_offset;
8767 sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8768 if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
8769 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8770 (uchar *)&sdtr_buf,
8771 sizeof(EXT_MSG) >> 1);
8772 return ((sdtr_period_index << 4) | sdtr_offset);
8773 } else {
8774 sdtr_buf.req_ack_offset = 0;
8775 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8776 (uchar *)&sdtr_buf,
8777 sizeof(EXT_MSG) >> 1);
8778 return 0;
8779 }
8780}
8781
8782static uchar
8783AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8784{
8785 uchar byte;
8786 uchar sdtr_period_ix;
8787
8788 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8789 if (sdtr_period_ix > asc_dvc->max_sdtr_index) {
8790 return 0xFF;
8791 }
8792 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8793 return byte;
8794}
8795
8796static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8797{
8798 ASC_SCSI_BIT_ID_TYPE org_id;
8799 int i;
8800 int sta = TRUE;
8801
8802 AscSetBank(iop_base, 1);
8803 org_id = AscReadChipDvcID(iop_base);
8804 for (i = 0; i <= ASC_MAX_TID; i++) {
8805 if (org_id == (0x01 << i))
8806 break;
8807 }
8808 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8809 AscWriteChipDvcID(iop_base, id);
8810 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8811 AscSetBank(iop_base, 0);
8812 AscSetChipSyn(iop_base, sdtr_data);
8813 if (AscGetChipSyn(iop_base) != sdtr_data) {
8814 sta = FALSE;
8815 }
8816 } else {
8817 sta = FALSE;
8818 }
8819 AscSetBank(iop_base, 1);
8820 AscWriteChipDvcID(iop_base, org_id);
8821 AscSetBank(iop_base, 0);
8822 return (sta);
8823}
8824
8825static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8826{
8827 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8828 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8829}
8830
8831static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8832{
8833 EXT_MSG ext_msg;
8834 EXT_MSG out_msg;
8835 ushort halt_q_addr;
8836 int sdtr_accept;
8837 ushort int_halt_code;
8838 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8839 ASC_SCSI_BIT_ID_TYPE target_id;
8840 PortAddr iop_base;
8841 uchar tag_code;
8842 uchar q_status;
8843 uchar halt_qp;
8844 uchar sdtr_data;
8845 uchar target_ix;
8846 uchar q_cntl, tid_no;
8847 uchar cur_dvc_qng;
8848 uchar asyn_sdtr;
8849 uchar scsi_status;
8850 asc_board_t *boardp;
8851
8852 BUG_ON(!asc_dvc->drv_ptr);
8853 boardp = asc_dvc->drv_ptr;
8854
8855 iop_base = asc_dvc->iop_base;
8856 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8857
8858 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8859 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8860 target_ix = AscReadLramByte(iop_base,
8861 (ushort)(halt_q_addr +
8862 (ushort)ASC_SCSIQ_B_TARGET_IX));
8863 q_cntl = AscReadLramByte(iop_base,
8864 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8865 tid_no = ASC_TIX_TO_TID(target_ix);
8866 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8867 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8868 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8869 } else {
8870 asyn_sdtr = 0;
8871 }
8872 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8873 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8874 AscSetChipSDTR(iop_base, 0, tid_no);
8875 boardp->sdtr_data[tid_no] = 0;
8876 }
8877 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8878 return (0);
8879 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8880 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8881 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8882 boardp->sdtr_data[tid_no] = asyn_sdtr;
8883 }
8884 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8885 return (0);
8886 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8887 AscMemWordCopyPtrFromLram(iop_base,
8888 ASCV_MSGIN_BEG,
8889 (uchar *)&ext_msg,
8890 sizeof(EXT_MSG) >> 1);
8891
8892 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8893 ext_msg.msg_req == EXTENDED_SDTR &&
8894 ext_msg.msg_len == MS_SDTR_LEN) {
8895 sdtr_accept = TRUE;
8896 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8897
8898 sdtr_accept = FALSE;
8899 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8900 }
8901 if ((ext_msg.xfer_period <
8902 asc_dvc->sdtr_period_tbl[asc_dvc->
8903 host_init_sdtr_index])
8904 || (ext_msg.xfer_period >
8905 asc_dvc->sdtr_period_tbl[asc_dvc->
8906 max_sdtr_index])) {
8907 sdtr_accept = FALSE;
8908 ext_msg.xfer_period =
8909 asc_dvc->sdtr_period_tbl[asc_dvc->
8910 host_init_sdtr_index];
8911 }
8912 if (sdtr_accept) {
8913 sdtr_data =
8914 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8915 ext_msg.req_ack_offset);
8916 if ((sdtr_data == 0xFF)) {
8917
8918 q_cntl |= QC_MSG_OUT;
8919 asc_dvc->init_sdtr &= ~target_id;
8920 asc_dvc->sdtr_done &= ~target_id;
8921 AscSetChipSDTR(iop_base, asyn_sdtr,
8922 tid_no);
8923 boardp->sdtr_data[tid_no] = asyn_sdtr;
8924 }
8925 }
8926 if (ext_msg.req_ack_offset == 0) {
8927
8928 q_cntl &= ~QC_MSG_OUT;
8929 asc_dvc->init_sdtr &= ~target_id;
8930 asc_dvc->sdtr_done &= ~target_id;
8931 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8932 } else {
8933 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8934
8935 q_cntl &= ~QC_MSG_OUT;
8936 asc_dvc->sdtr_done |= target_id;
8937 asc_dvc->init_sdtr |= target_id;
8938 asc_dvc->pci_fix_asyn_xfer &=
8939 ~target_id;
8940 sdtr_data =
8941 AscCalSDTRData(asc_dvc,
8942 ext_msg.xfer_period,
8943 ext_msg.
8944 req_ack_offset);
8945 AscSetChipSDTR(iop_base, sdtr_data,
8946 tid_no);
8947 boardp->sdtr_data[tid_no] = sdtr_data;
8948 } else {
8949
8950 q_cntl |= QC_MSG_OUT;
8951 AscMsgOutSDTR(asc_dvc,
8952 ext_msg.xfer_period,
8953 ext_msg.req_ack_offset);
8954 asc_dvc->pci_fix_asyn_xfer &=
8955 ~target_id;
8956 sdtr_data =
8957 AscCalSDTRData(asc_dvc,
8958 ext_msg.xfer_period,
8959 ext_msg.
8960 req_ack_offset);
8961 AscSetChipSDTR(iop_base, sdtr_data,
8962 tid_no);
8963 boardp->sdtr_data[tid_no] = sdtr_data;
8964 asc_dvc->sdtr_done |= target_id;
8965 asc_dvc->init_sdtr |= target_id;
8966 }
8967 }
8968
8969 AscWriteLramByte(iop_base,
8970 (ushort)(halt_q_addr +
8971 (ushort)ASC_SCSIQ_B_CNTL),
8972 q_cntl);
8973 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8974 return (0);
8975 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8976 ext_msg.msg_req == EXTENDED_WDTR &&
8977 ext_msg.msg_len == MS_WDTR_LEN) {
8978
8979 ext_msg.wdtr_width = 0;
8980 AscMemWordCopyPtrToLram(iop_base,
8981 ASCV_MSGOUT_BEG,
8982 (uchar *)&ext_msg,
8983 sizeof(EXT_MSG) >> 1);
8984 q_cntl |= QC_MSG_OUT;
8985 AscWriteLramByte(iop_base,
8986 (ushort)(halt_q_addr +
8987 (ushort)ASC_SCSIQ_B_CNTL),
8988 q_cntl);
8989 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8990 return (0);
8991 } else {
8992
8993 ext_msg.msg_type = MESSAGE_REJECT;
8994 AscMemWordCopyPtrToLram(iop_base,
8995 ASCV_MSGOUT_BEG,
8996 (uchar *)&ext_msg,
8997 sizeof(EXT_MSG) >> 1);
8998 q_cntl |= QC_MSG_OUT;
8999 AscWriteLramByte(iop_base,
9000 (ushort)(halt_q_addr +
9001 (ushort)ASC_SCSIQ_B_CNTL),
9002 q_cntl);
9003 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9004 return (0);
9005 }
9006 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
9007
9008 q_cntl |= QC_REQ_SENSE;
9009
9010 if ((asc_dvc->init_sdtr & target_id) != 0) {
9011
9012 asc_dvc->sdtr_done &= ~target_id;
9013
9014 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9015 q_cntl |= QC_MSG_OUT;
9016 AscMsgOutSDTR(asc_dvc,
9017 asc_dvc->
9018 sdtr_period_tbl[(sdtr_data >> 4) &
9019 (uchar)(asc_dvc->
9020 max_sdtr_index -
9021 1)],
9022 (uchar)(sdtr_data & (uchar)
9023 ASC_SYN_MAX_OFFSET));
9024 }
9025
9026 AscWriteLramByte(iop_base,
9027 (ushort)(halt_q_addr +
9028 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
9029
9030 tag_code = AscReadLramByte(iop_base,
9031 (ushort)(halt_q_addr + (ushort)
9032 ASC_SCSIQ_B_TAG_CODE));
9033 tag_code &= 0xDC;
9034 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
9035 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
9036 ) {
9037
9038 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
9039 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
9040
9041 }
9042 AscWriteLramByte(iop_base,
9043 (ushort)(halt_q_addr +
9044 (ushort)ASC_SCSIQ_B_TAG_CODE),
9045 tag_code);
9046
9047 q_status = AscReadLramByte(iop_base,
9048 (ushort)(halt_q_addr + (ushort)
9049 ASC_SCSIQ_B_STATUS));
9050 q_status |= (QS_READY | QS_BUSY);
9051 AscWriteLramByte(iop_base,
9052 (ushort)(halt_q_addr +
9053 (ushort)ASC_SCSIQ_B_STATUS),
9054 q_status);
9055
9056 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
9057 scsi_busy &= ~target_id;
9058 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
9059
9060 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9061 return (0);
9062 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
9063
9064 AscMemWordCopyPtrFromLram(iop_base,
9065 ASCV_MSGOUT_BEG,
9066 (uchar *)&out_msg,
9067 sizeof(EXT_MSG) >> 1);
9068
9069 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
9070 (out_msg.msg_len == MS_SDTR_LEN) &&
9071 (out_msg.msg_req == EXTENDED_SDTR)) {
9072
9073 asc_dvc->init_sdtr &= ~target_id;
9074 asc_dvc->sdtr_done &= ~target_id;
9075 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9076 boardp->sdtr_data[tid_no] = asyn_sdtr;
9077 }
9078 q_cntl &= ~QC_MSG_OUT;
9079 AscWriteLramByte(iop_base,
9080 (ushort)(halt_q_addr +
9081 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
9082 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9083 return (0);
9084 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
9085
9086 scsi_status = AscReadLramByte(iop_base,
9087 (ushort)((ushort)halt_q_addr +
9088 (ushort)
9089 ASC_SCSIQ_SCSI_STATUS));
9090 cur_dvc_qng =
9091 AscReadLramByte(iop_base,
9092 (ushort)((ushort)ASC_QADR_BEG +
9093 (ushort)target_ix));
9094 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
9095
9096 scsi_busy = AscReadLramByte(iop_base,
9097 (ushort)ASCV_SCSIBUSY_B);
9098 scsi_busy |= target_id;
9099 AscWriteLramByte(iop_base,
9100 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
9101 asc_dvc->queue_full_or_busy |= target_id;
9102
9103 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
9104 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
9105 cur_dvc_qng -= 1;
9106 asc_dvc->max_dvc_qng[tid_no] =
9107 cur_dvc_qng;
9108
9109 AscWriteLramByte(iop_base,
9110 (ushort)((ushort)
9111 ASCV_MAX_DVC_QNG_BEG
9112 + (ushort)
9113 tid_no),
9114 cur_dvc_qng);
9115
9116 /*
9117 * Set the device queue depth to the
9118 * number of active requests when the
9119 * QUEUE FULL condition was encountered.
9120 */
9121 boardp->queue_full |= target_id;
9122 boardp->queue_full_cnt[tid_no] =
9123 cur_dvc_qng;
9124 }
9125 }
9126 }
9127 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9128 return (0);
9129 }
9130#if CC_VERY_LONG_SG_LIST
9131 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
9132 uchar q_no;
9133 ushort q_addr;
9134 uchar sg_wk_q_no;
9135 uchar first_sg_wk_q_no;
9136 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
9137 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
9138 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
9139 ushort sg_list_dwords;
9140 ushort sg_entry_cnt;
9141 uchar next_qp;
9142 int i;
9143
9144 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
9145 if (q_no == ASC_QLINK_END)
9146 return 0;
9147
9148 q_addr = ASC_QNO_TO_QADDR(q_no);
9149
9150 /*
9151 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
9152 * structure pointer using a macro provided by the driver.
9153 * The ASC_SCSI_REQ pointer provides a pointer to the
9154 * host ASC_SG_HEAD structure.
9155 */
9156 /* Read request's SRB pointer. */
9157 scsiq = (ASC_SCSI_Q *)
9158 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
9159 (ushort)
9160 (q_addr +
9161 ASC_SCSIQ_D_SRBPTR))));
9162
9163 /*
9164 * Get request's first and working SG queue.
9165 */
9166 sg_wk_q_no = AscReadLramByte(iop_base,
9167 (ushort)(q_addr +
9168 ASC_SCSIQ_B_SG_WK_QP));
9169
9170 first_sg_wk_q_no = AscReadLramByte(iop_base,
9171 (ushort)(q_addr +
9172 ASC_SCSIQ_B_FIRST_SG_WK_QP));
9173
9174 /*
9175 * Reset request's working SG queue back to the
9176 * first SG queue.
9177 */
9178 AscWriteLramByte(iop_base,
9179 (ushort)(q_addr +
9180 (ushort)ASC_SCSIQ_B_SG_WK_QP),
9181 first_sg_wk_q_no);
9182
9183 sg_head = scsiq->sg_head;
9184
9185 /*
9186 * Set sg_entry_cnt to the number of SG elements
9187 * that will be completed on this interrupt.
9188 *
9189 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
9190 * SG elements. The data_cnt and data_addr fields which
9191 * add 1 to the SG element capacity are not used when
9192 * restarting SG handling after a halt.
9193 */
9194 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
9195 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9196
9197 /*
9198 * Keep track of remaining number of SG elements that
9199 * will need to be handled on the next interrupt.
9200 */
9201 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
9202 } else {
9203 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
9204 scsiq->remain_sg_entry_cnt = 0;
9205 }
9206
9207 /*
9208 * Copy SG elements into the list of allocated SG queues.
9209 *
9210 * Last index completed is saved in scsiq->next_sg_index.
9211 */
9212 next_qp = first_sg_wk_q_no;
9213 q_addr = ASC_QNO_TO_QADDR(next_qp);
9214 scsi_sg_q.sg_head_qp = q_no;
9215 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9216 for (i = 0; i < sg_head->queue_cnt; i++) {
9217 scsi_sg_q.seq_no = i + 1;
9218 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9219 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9220 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9221 /*
9222 * After very first SG queue RISC FW uses next
9223 * SG queue first element then checks sg_list_cnt
9224 * against zero and then decrements, so set
9225 * sg_list_cnt 1 less than number of SG elements
9226 * in each SG queue.
9227 */
9228 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
9229 scsi_sg_q.sg_cur_list_cnt =
9230 ASC_SG_LIST_PER_Q - 1;
9231 } else {
9232 /*
9233 * This is the last SG queue in the list of
9234 * allocated SG queues. If there are more
9235 * SG elements than will fit in the allocated
9236 * queues, then set the QCSG_SG_XFER_MORE flag.
9237 */
9238 if (scsiq->remain_sg_entry_cnt != 0) {
9239 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9240 } else {
9241 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9242 }
9243 /* equals sg_entry_cnt * 2 */
9244 sg_list_dwords = sg_entry_cnt << 1;
9245 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
9246 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
9247 sg_entry_cnt = 0;
9248 }
9249
9250 scsi_sg_q.q_no = next_qp;
9251 AscMemWordCopyPtrToLram(iop_base,
9252 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9253 (uchar *)&scsi_sg_q,
9254 sizeof(ASC_SG_LIST_Q) >> 1);
9255
9256 AscMemDWordCopyPtrToLram(iop_base,
9257 q_addr + ASC_SGQ_LIST_BEG,
9258 (uchar *)&sg_head->
9259 sg_list[scsiq->next_sg_index],
9260 sg_list_dwords);
9261
9262 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9263
9264 /*
9265 * If the just completed SG queue contained the
9266 * last SG element, then no more SG queues need
9267 * to be written.
9268 */
9269 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9270 break;
9271 }
9272
9273 next_qp = AscReadLramByte(iop_base,
9274 (ushort)(q_addr +
9275 ASC_SCSIQ_B_FWD));
9276 q_addr = ASC_QNO_TO_QADDR(next_qp);
9277 }
9278
9279 /*
9280 * Clear the halt condition so the RISC will be restarted
9281 * after the return.
9282 */
9283 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9284 return (0);
9285 }
9286#endif /* CC_VERY_LONG_SG_LIST */
9287 return (0);
9288}
1da177e4 9289
1da177e4 9290/*
51219358
MW
9291 * void
9292 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
1da177e4 9293 *
51219358
MW
9294 * Calling/Exit State:
9295 * none
1da177e4 9296 *
51219358
MW
9297 * Description:
9298 * Input an ASC_QDONE_INFO structure from the chip
1da177e4 9299 */
51219358
MW
9300static void
9301DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9302{
9303 int i;
9304 ushort word;
9305
9306 AscSetChipLramAddr(iop_base, s_addr);
9307 for (i = 0; i < 2 * words; i += 2) {
9308 if (i == 10) {
9309 continue;
9310 }
9311 word = inpw(iop_base + IOP_RAM_DATA);
9312 inbuf[i] = word & 0xff;
9313 inbuf[i + 1] = (word >> 8) & 0xff;
9314 }
9315 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9316}
9317
9318static uchar
9319_AscCopyLramScsiDoneQ(PortAddr iop_base,
9320 ushort q_addr,
9321 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9322{
9323 ushort _val;
9324 uchar sg_queue_cnt;
9325
9326 DvcGetQinfo(iop_base,
9327 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
9328 (uchar *)scsiq,
9329 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
9330
9331 _val = AscReadLramWord(iop_base,
9332 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
9333 scsiq->q_status = (uchar)_val;
9334 scsiq->q_no = (uchar)(_val >> 8);
9335 _val = AscReadLramWord(iop_base,
9336 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
9337 scsiq->cntl = (uchar)_val;
9338 sg_queue_cnt = (uchar)(_val >> 8);
9339 _val = AscReadLramWord(iop_base,
9340 (ushort)(q_addr +
9341 (ushort)ASC_SCSIQ_B_SENSE_LEN));
9342 scsiq->sense_len = (uchar)_val;
9343 scsiq->extra_bytes = (uchar)(_val >> 8);
9344
9345 /*
9346 * Read high word of remain bytes from alternate location.
9347 */
9348 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9349 (ushort)(q_addr +
9350 (ushort)
9351 ASC_SCSIQ_W_ALT_DC1)))
9352 << 16);
9353 /*
9354 * Read low word of remain bytes from original location.
9355 */
9356 scsiq->remain_bytes += AscReadLramWord(iop_base,
9357 (ushort)(q_addr + (ushort)
9358 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9359
9360 scsiq->remain_bytes &= max_dma_count;
9361 return sg_queue_cnt;
9362}
9363
9364/*
9365 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9366 *
9367 * Interrupt callback function for the Narrow SCSI Asc Library.
9368 */
9369static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9370{
9371 asc_board_t *boardp;
9372 struct scsi_cmnd *scp;
9373 struct Scsi_Host *shost;
9374
9375 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
9376 (ulong)asc_dvc_varp, (ulong)qdonep);
9377 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9378
9379 /*
9380 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
9381 * command that has been completed.
9382 */
9383 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
9384 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
9385
9386 if (scp == NULL) {
9387 ASC_PRINT("asc_isr_callback: scp is NULL\n");
9388 return;
9389 }
9390 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9391
9392 shost = scp->device->host;
9393 ASC_STATS(shost, callback);
9394 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
9395
9396 boardp = ASC_BOARDP(shost);
9397 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9398
9399 /*
9400 * 'qdonep' contains the command's ending status.
9401 */
9402 switch (qdonep->d3.done_stat) {
9403 case QD_NO_ERROR:
9404 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
9405 scp->result = 0;
9406
9407 /*
9408 * Check for an underrun condition.
9409 *
9410 * If there was no error and an underrun condition, then
9411 * return the number of underrun bytes.
9412 */
9413 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
9414 qdonep->remain_bytes <= scp->request_bufflen) {
9415 ASC_DBG1(1,
9416 "asc_isr_callback: underrun condition %u bytes\n",
9417 (unsigned)qdonep->remain_bytes);
9418 scp->resid = qdonep->remain_bytes;
9419 }
9420 break;
9421
9422 case QD_WITH_ERROR:
9423 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
9424 switch (qdonep->d3.host_stat) {
9425 case QHSTA_NO_ERROR:
9426 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
9427 ASC_DBG(2,
9428 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
9429 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9430 sizeof(scp->sense_buffer));
9431 /*
9432 * Note: The 'status_byte()' macro used by
9433 * target drivers defined in scsi.h shifts the
9434 * status byte returned by host drivers right
9435 * by 1 bit. This is why target drivers also
9436 * use right shifted status byte definitions.
9437 * For instance target drivers use
9438 * CHECK_CONDITION, defined to 0x1, instead of
9439 * the SCSI defined check condition value of
9440 * 0x2. Host drivers are supposed to return
9441 * the status byte as it is defined by SCSI.
9442 */
9443 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
9444 STATUS_BYTE(qdonep->d3.scsi_stat);
9445 } else {
9446 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
9447 }
9448 break;
9449
9450 default:
9451 /* QHSTA error occurred */
9452 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
9453 qdonep->d3.host_stat);
9454 scp->result = HOST_BYTE(DID_BAD_TARGET);
9455 break;
9456 }
9457 break;
9458
9459 case QD_ABORTED_BY_HOST:
9460 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
9461 scp->result =
9462 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9463 scsi_msg) |
9464 STATUS_BYTE(qdonep->d3.scsi_stat);
9465 break;
9466
9467 default:
9468 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
9469 qdonep->d3.done_stat);
9470 scp->result =
9471 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9472 scsi_msg) |
9473 STATUS_BYTE(qdonep->d3.scsi_stat);
9474 break;
9475 }
9476
9477 /*
9478 * If the 'init_tidmask' bit isn't already set for the target and the
9479 * current request finished normally, then set the bit for the target
9480 * to indicate that a device is present.
9481 */
9482 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
9483 qdonep->d3.done_stat == QD_NO_ERROR &&
9484 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
9485 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
9486 }
1da177e4 9487
51219358 9488 asc_scsi_done(scp);
1da177e4 9489
51219358
MW
9490 return;
9491}
9492
9493static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9494{
9495 uchar next_qp;
9496 uchar n_q_used;
9497 uchar sg_list_qp;
9498 uchar sg_queue_cnt;
9499 uchar q_cnt;
9500 uchar done_q_tail;
9501 uchar tid_no;
9502 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9503 ASC_SCSI_BIT_ID_TYPE target_id;
9504 PortAddr iop_base;
9505 ushort q_addr;
9506 ushort sg_q_addr;
9507 uchar cur_target_qng;
9508 ASC_QDONE_INFO scsiq_buf;
9509 ASC_QDONE_INFO *scsiq;
9510 int false_overrun;
9511
9512 iop_base = asc_dvc->iop_base;
9513 n_q_used = 1;
9514 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9515 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9516 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9517 next_qp = AscReadLramByte(iop_base,
9518 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9519 if (next_qp != ASC_QLINK_END) {
9520 AscPutVarDoneQTail(iop_base, next_qp);
9521 q_addr = ASC_QNO_TO_QADDR(next_qp);
9522 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9523 asc_dvc->max_dma_count);
9524 AscWriteLramByte(iop_base,
9525 (ushort)(q_addr +
9526 (ushort)ASC_SCSIQ_B_STATUS),
9527 (uchar)(scsiq->
9528 q_status & (uchar)~(QS_READY |
9529 QS_ABORTED)));
9530 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9531 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9532 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9533 sg_q_addr = q_addr;
9534 sg_list_qp = next_qp;
9535 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9536 sg_list_qp = AscReadLramByte(iop_base,
9537 (ushort)(sg_q_addr
9538 + (ushort)
9539 ASC_SCSIQ_B_FWD));
9540 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9541 if (sg_list_qp == ASC_QLINK_END) {
9542 AscSetLibErrorCode(asc_dvc,
9543 ASCQ_ERR_SG_Q_LINKS);
9544 scsiq->d3.done_stat = QD_WITH_ERROR;
9545 scsiq->d3.host_stat =
9546 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9547 goto FATAL_ERR_QDONE;
9548 }
9549 AscWriteLramByte(iop_base,
9550 (ushort)(sg_q_addr + (ushort)
9551 ASC_SCSIQ_B_STATUS),
9552 QS_FREE);
9553 }
9554 n_q_used = sg_queue_cnt + 1;
9555 AscPutVarDoneQTail(iop_base, sg_list_qp);
9556 }
9557 if (asc_dvc->queue_full_or_busy & target_id) {
9558 cur_target_qng = AscReadLramByte(iop_base,
9559 (ushort)((ushort)
9560 ASC_QADR_BEG
9561 + (ushort)
9562 scsiq->d2.
9563 target_ix));
9564 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9565 scsi_busy = AscReadLramByte(iop_base, (ushort)
9566 ASCV_SCSIBUSY_B);
9567 scsi_busy &= ~target_id;
9568 AscWriteLramByte(iop_base,
9569 (ushort)ASCV_SCSIBUSY_B,
9570 scsi_busy);
9571 asc_dvc->queue_full_or_busy &= ~target_id;
9572 }
9573 }
9574 if (asc_dvc->cur_total_qng >= n_q_used) {
9575 asc_dvc->cur_total_qng -= n_q_used;
9576 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9577 asc_dvc->cur_dvc_qng[tid_no]--;
9578 }
9579 } else {
9580 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9581 scsiq->d3.done_stat = QD_WITH_ERROR;
9582 goto FATAL_ERR_QDONE;
9583 }
9584 if ((scsiq->d2.srb_ptr == 0UL) ||
9585 ((scsiq->q_status & QS_ABORTED) != 0)) {
9586 return (0x11);
9587 } else if (scsiq->q_status == QS_DONE) {
9588 false_overrun = FALSE;
9589 if (scsiq->extra_bytes != 0) {
9590 scsiq->remain_bytes +=
9591 (ADV_DCNT)scsiq->extra_bytes;
9592 }
9593 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9594 if (scsiq->d3.host_stat ==
9595 QHSTA_M_DATA_OVER_RUN) {
9596 if ((scsiq->
9597 cntl & (QC_DATA_IN | QC_DATA_OUT))
9598 == 0) {
9599 scsiq->d3.done_stat =
9600 QD_NO_ERROR;
9601 scsiq->d3.host_stat =
9602 QHSTA_NO_ERROR;
9603 } else if (false_overrun) {
9604 scsiq->d3.done_stat =
9605 QD_NO_ERROR;
9606 scsiq->d3.host_stat =
9607 QHSTA_NO_ERROR;
9608 }
9609 } else if (scsiq->d3.host_stat ==
9610 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9611 AscStopChip(iop_base);
9612 AscSetChipControl(iop_base,
9613 (uchar)(CC_SCSI_RESET
9614 | CC_HALT));
9615 udelay(60);
9616 AscSetChipControl(iop_base, CC_HALT);
9617 AscSetChipStatus(iop_base,
9618 CIW_CLR_SCSI_RESET_INT);
9619 AscSetChipStatus(iop_base, 0);
9620 AscSetChipControl(iop_base, 0);
9621 }
9622 }
9623 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9624 asc_isr_callback(asc_dvc, scsiq);
9625 } else {
9626 if ((AscReadLramByte(iop_base,
9627 (ushort)(q_addr + (ushort)
9628 ASC_SCSIQ_CDB_BEG))
9629 == START_STOP)) {
9630 asc_dvc->unit_not_ready &= ~target_id;
9631 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9632 asc_dvc->start_motor &=
9633 ~target_id;
9634 }
9635 }
9636 }
9637 return (1);
9638 } else {
9639 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9640 FATAL_ERR_QDONE:
9641 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9642 asc_isr_callback(asc_dvc, scsiq);
9643 }
9644 return (0x80);
9645 }
9646 }
9647 return (0);
9648}
1da177e4 9649
51219358
MW
9650static int AscISR(ASC_DVC_VAR *asc_dvc)
9651{
9652 ASC_CS_TYPE chipstat;
9653 PortAddr iop_base;
9654 ushort saved_ram_addr;
9655 uchar ctrl_reg;
9656 uchar saved_ctrl_reg;
9657 int int_pending;
9658 int status;
9659 uchar host_flag;
1da177e4 9660
51219358
MW
9661 iop_base = asc_dvc->iop_base;
9662 int_pending = FALSE;
1da177e4 9663
51219358
MW
9664 if (AscIsIntPending(iop_base) == 0)
9665 return int_pending;
9666
9667 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9668 return ERR;
9669 }
9670 if (asc_dvc->in_critical_cnt != 0) {
9671 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9672 return ERR;
9673 }
9674 if (asc_dvc->is_in_int) {
9675 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9676 return ERR;
9677 }
9678 asc_dvc->is_in_int = TRUE;
9679 ctrl_reg = AscGetChipControl(iop_base);
9680 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9681 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9682 chipstat = AscGetChipStatus(iop_base);
9683 if (chipstat & CSW_SCSI_RESET_LATCH) {
9684 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9685 int i = 10;
9686 int_pending = TRUE;
9687 asc_dvc->sdtr_done = 0;
9688 saved_ctrl_reg &= (uchar)(~CC_HALT);
9689 while ((AscGetChipStatus(iop_base) &
9690 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9691 mdelay(100);
9692 }
9693 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9694 AscSetChipControl(iop_base, CC_HALT);
9695 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9696 AscSetChipStatus(iop_base, 0);
9697 chipstat = AscGetChipStatus(iop_base);
9698 }
9699 }
9700 saved_ram_addr = AscGetChipLramAddr(iop_base);
9701 host_flag = AscReadLramByte(iop_base,
9702 ASCV_HOST_FLAG_B) &
9703 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9704 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9705 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9706 if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
9707 AscAckInterrupt(iop_base);
9708 int_pending = TRUE;
9709 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9710 if (AscIsrChipHalted(asc_dvc) == ERR) {
9711 goto ISR_REPORT_QDONE_FATAL_ERROR;
9712 } else {
9713 saved_ctrl_reg &= (uchar)(~CC_HALT);
9714 }
9715 } else {
9716 ISR_REPORT_QDONE_FATAL_ERROR:
9717 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9718 while (((status =
9719 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9720 }
9721 } else {
9722 do {
9723 if ((status =
9724 AscIsrQDone(asc_dvc)) == 1) {
9725 break;
9726 }
9727 } while (status == 0x11);
9728 }
9729 if ((status & 0x80) != 0)
9730 int_pending = ERR;
9731 }
9732 }
9733 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9734 AscSetChipLramAddr(iop_base, saved_ram_addr);
9735 AscSetChipControl(iop_base, saved_ctrl_reg);
9736 asc_dvc->is_in_int = FALSE;
9737 return int_pending;
9738}
1da177e4
LT
9739
9740/*
51219358 9741 * advansys_reset()
1da177e4 9742 *
51219358 9743 * Reset the bus associated with the command 'scp'.
1da177e4 9744 *
51219358
MW
9745 * This function runs its own thread. Interrupts must be blocked but
9746 * sleeping is allowed and no locking other than for host structures is
9747 * required. Returns SUCCESS or FAILED.
1da177e4 9748 */
51219358 9749static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 9750{
52fa0777
MW
9751 struct Scsi_Host *shost = scp->device->host;
9752 struct asc_board *boardp = ASC_BOARDP(shost);
9753 unsigned long flags;
27c868c2 9754 int status;
51219358 9755 int ret = SUCCESS;
27c868c2 9756
52fa0777 9757 ASC_DBG1(1, "advansys_reset: 0x%p\n", scp);
27c868c2 9758
52fa0777 9759 ASC_STATS(shost, reset);
27c868c2 9760
52fa0777 9761 scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
51219358
MW
9762
9763 if (ASC_NARROW_BOARD(boardp)) {
52fa0777 9764 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
1da177e4 9765
52fa0777 9766 /* Reset the chip and SCSI bus. */
51219358 9767 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
52fa0777 9768 status = AscInitAsc1000Driver(asc_dvc);
27c868c2 9769
51219358 9770 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
52fa0777
MW
9771 if (asc_dvc->err_code) {
9772 scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9773 "0x%x\n", asc_dvc->err_code);
51219358
MW
9774 ret = FAILED;
9775 } else if (status) {
52fa0777
MW
9776 scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9777 "0x%x\n", status);
27c868c2 9778 } else {
52fa0777
MW
9779 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9780 "successful\n");
27c868c2 9781 }
a9f4a59a 9782
51219358
MW
9783 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
9784 spin_lock_irqsave(&boardp->lock, flags);
a9f4a59a 9785 } else {
a9f4a59a 9786 /*
51219358
MW
9787 * If the suggest reset bus flags are set, then reset the bus.
9788 * Otherwise only reset the device.
a9f4a59a 9789 */
52fa0777 9790 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
a9f4a59a
MW
9791
9792 /*
51219358 9793 * Reset the target's SCSI bus.
a9f4a59a 9794 */
51219358 9795 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
52fa0777 9796 switch (AdvResetChipAndSB(adv_dvc)) {
51219358 9797 case ASC_TRUE:
52fa0777
MW
9798 scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9799 "successful\n");
51219358
MW
9800 break;
9801 case ASC_FALSE:
9802 default:
52fa0777 9803 scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
51219358
MW
9804 ret = FAILED;
9805 break;
b9d96614 9806 }
51219358 9807 spin_lock_irqsave(&boardp->lock, flags);
52fa0777 9808 AdvISR(adv_dvc);
b9d96614
MW
9809 }
9810
51219358
MW
9811 /* Save the time of the most recently completed reset. */
9812 boardp->last_reset = jiffies;
51219358 9813 spin_unlock_irqrestore(&boardp->lock, flags);
b9d96614 9814
51219358 9815 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
b9d96614 9816
51219358 9817 return ret;
b9d96614
MW
9818}
9819
1da177e4 9820/*
51219358 9821 * advansys_biosparam()
1da177e4 9822 *
51219358
MW
9823 * Translate disk drive geometry if the "BIOS greater than 1 GB"
9824 * support is enabled for a drive.
1da177e4 9825 *
51219358
MW
9826 * ip (information pointer) is an int array with the following definition:
9827 * ip[0]: heads
9828 * ip[1]: sectors
9829 * ip[2]: cylinders
1da177e4 9830 */
51219358
MW
9831static int
9832advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9833 sector_t capacity, int ip[])
1da177e4 9834{
51219358 9835 asc_board_t *boardp;
1da177e4 9836
51219358
MW
9837 ASC_DBG(1, "advansys_biosparam: begin\n");
9838 ASC_STATS(sdev->host, biosparam);
9839 boardp = ASC_BOARDP(sdev->host);
9840 if (ASC_NARROW_BOARD(boardp)) {
9841 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
9842 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
9843 ip[0] = 255;
9844 ip[1] = 63;
9845 } else {
9846 ip[0] = 64;
9847 ip[1] = 32;
9848 }
9849 } else {
9850 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
9851 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
9852 ip[0] = 255;
9853 ip[1] = 63;
9854 } else {
9855 ip[0] = 64;
9856 ip[1] = 32;
9857 }
27c868c2 9858 }
51219358
MW
9859 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
9860 ASC_DBG(1, "advansys_biosparam: end\n");
9861 return 0;
9862}
1da177e4 9863
51219358
MW
9864/*
9865 * First-level interrupt handler.
9866 *
9867 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9868 */
9869static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9870{
9871 unsigned long flags;
9872 struct Scsi_Host *shost = dev_id;
9873 asc_board_t *boardp = ASC_BOARDP(shost);
9874 irqreturn_t result = IRQ_NONE;
27c868c2 9875
51219358
MW
9876 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
9877 spin_lock_irqsave(&boardp->lock, flags);
9878 if (ASC_NARROW_BOARD(boardp)) {
9879 if (AscIsIntPending(shost->io_port)) {
9880 result = IRQ_HANDLED;
9881 ASC_STATS(shost, interrupt);
9882 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
9883 AscISR(&boardp->dvc_var.asc_dvc_var);
9884 }
9885 } else {
9886 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
9887 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9888 result = IRQ_HANDLED;
9889 ASC_STATS(shost, interrupt);
9890 }
27c868c2 9891 }
51219358 9892 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 9893
51219358
MW
9894 ASC_DBG(1, "advansys_interrupt: end\n");
9895 return result;
9896}
27c868c2 9897
51219358
MW
9898static int AscHostReqRiscHalt(PortAddr iop_base)
9899{
9900 int count = 0;
9901 int sta = 0;
9902 uchar saved_stop_code;
9903
9904 if (AscIsChipHalted(iop_base))
9905 return (1);
9906 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9907 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9908 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9909 do {
9910 if (AscIsChipHalted(iop_base)) {
9911 sta = 1;
9912 break;
27c868c2 9913 }
51219358
MW
9914 mdelay(100);
9915 } while (count++ < 20);
9916 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9917 return (sta);
9918}
1da177e4 9919
51219358
MW
9920static int
9921AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9922{
9923 int sta = FALSE;
1da177e4 9924
51219358
MW
9925 if (AscHostReqRiscHalt(iop_base)) {
9926 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9927 AscStartChip(iop_base);
27c868c2 9928 }
51219358
MW
9929 return sta;
9930}
1da177e4 9931
51219358
MW
9932static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9933{
9934 char type = sdev->type;
9935 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
27c868c2 9936
51219358
MW
9937 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9938 return;
9939 if (asc_dvc->init_sdtr & tid_bits)
9940 return;
27c868c2 9941
51219358
MW
9942 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9943 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
27c868c2 9944
51219358
MW
9945 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9946 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9947 (type == TYPE_ROM) || (type == TYPE_TAPE))
9948 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9949
9950 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9951 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
9952 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
9953}
1da177e4 9954
51219358
MW
9955static void
9956advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9957{
9958 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
9959 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
27c868c2 9960
51219358
MW
9961 if (sdev->lun == 0) {
9962 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
9963 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
9964 asc_dvc->init_sdtr |= tid_bit;
9965 } else {
9966 asc_dvc->init_sdtr &= ~tid_bit;
9967 }
9968
9969 if (orig_init_sdtr != asc_dvc->init_sdtr)
9970 AscAsyncFix(asc_dvc, sdev);
27c868c2 9971 }
1da177e4 9972
51219358
MW
9973 if (sdev->tagged_supported) {
9974 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
9975 if (sdev->lun == 0) {
9976 asc_dvc->cfg->can_tagged_qng |= tid_bit;
9977 asc_dvc->use_tagged_qng |= tid_bit;
9978 }
9979 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9980 asc_dvc->max_dvc_qng[sdev->id]);
27c868c2 9981 }
51219358
MW
9982 } else {
9983 if (sdev->lun == 0) {
9984 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9985 asc_dvc->use_tagged_qng &= ~tid_bit;
27c868c2 9986 }
51219358 9987 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
27c868c2 9988 }
1da177e4 9989
51219358
MW
9990 if ((sdev->lun == 0) &&
9991 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
9992 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
9993 asc_dvc->cfg->disc_enable);
9994 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
9995 asc_dvc->use_tagged_qng);
9996 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
9997 asc_dvc->cfg->can_tagged_qng);
27c868c2 9998
51219358
MW
9999 asc_dvc->max_dvc_qng[sdev->id] =
10000 asc_dvc->cfg->max_tag_qng[sdev->id];
10001 AscWriteLramByte(asc_dvc->iop_base,
10002 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
10003 asc_dvc->max_dvc_qng[sdev->id]);
10004 }
10005}
27c868c2 10006
51219358
MW
10007/*
10008 * Wide Transfers
10009 *
10010 * If the EEPROM enabled WDTR for the device and the device supports wide
10011 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
10012 * write the new value to the microcode.
10013 */
10014static void
10015advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
10016{
10017 unsigned short cfg_word;
10018 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
10019 if ((cfg_word & tidmask) != 0)
10020 return;
27c868c2 10021
51219358
MW
10022 cfg_word |= tidmask;
10023 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
27c868c2
MW
10024
10025 /*
51219358
MW
10026 * Clear the microcode SDTR and WDTR negotiation done indicators for
10027 * the target to cause it to negotiate with the new setting set above.
10028 * WDTR when accepted causes the target to enter asynchronous mode, so
10029 * SDTR must be negotiated.
27c868c2 10030 */
51219358
MW
10031 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10032 cfg_word &= ~tidmask;
10033 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10034 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
10035 cfg_word &= ~tidmask;
10036 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
10037}
1da177e4 10038
51219358
MW
10039/*
10040 * Synchronous Transfers
10041 *
10042 * If the EEPROM enabled SDTR for the device and the device
10043 * supports synchronous transfers, then turn on the device's
10044 * 'sdtr_able' bit. Write the new value to the microcode.
10045 */
10046static void
10047advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
10048{
10049 unsigned short cfg_word;
10050 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
10051 if ((cfg_word & tidmask) != 0)
10052 return;
1da177e4 10053
51219358
MW
10054 cfg_word |= tidmask;
10055 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
1da177e4 10056
27c868c2 10057 /*
51219358
MW
10058 * Clear the microcode "SDTR negotiation" done indicator for the
10059 * target to cause it to negotiate with the new setting set above.
27c868c2 10060 */
51219358
MW
10061 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10062 cfg_word &= ~tidmask;
10063 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10064}
27c868c2 10065
51219358
MW
10066/*
10067 * PPR (Parallel Protocol Request) Capable
10068 *
10069 * If the device supports DT mode, then it must be PPR capable.
10070 * The PPR message will be used in place of the SDTR and WDTR
10071 * messages to negotiate synchronous speed and offset, transfer
10072 * width, and protocol options.
10073 */
10074static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
10075 AdvPortAddr iop_base, unsigned short tidmask)
10076{
10077 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
10078 adv_dvc->ppr_able |= tidmask;
10079 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
10080}
27c868c2 10081
51219358
MW
10082static void
10083advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
10084{
10085 AdvPortAddr iop_base = adv_dvc->iop_base;
10086 unsigned short tidmask = 1 << sdev->id;
10087
10088 if (sdev->lun == 0) {
10089 /*
10090 * Handle WDTR, SDTR, and Tag Queuing. If the feature
10091 * is enabled in the EEPROM and the device supports the
10092 * feature, then enable it in the microcode.
10093 */
27c868c2 10094
51219358
MW
10095 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
10096 advansys_wide_enable_wdtr(iop_base, tidmask);
10097 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
10098 advansys_wide_enable_sdtr(iop_base, tidmask);
10099 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
10100 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
10101
10102 /*
10103 * Tag Queuing is disabled for the BIOS which runs in polled
10104 * mode and would see no benefit from Tag Queuing. Also by
10105 * disabling Tag Queuing in the BIOS devices with Tag Queuing
10106 * bugs will at least work with the BIOS.
10107 */
10108 if ((adv_dvc->tagqng_able & tidmask) &&
10109 sdev->tagged_supported) {
10110 unsigned short cfg_word;
10111 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
10112 cfg_word |= tidmask;
10113 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
10114 cfg_word);
10115 AdvWriteByteLram(iop_base,
10116 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
10117 adv_dvc->max_dvc_qng);
27c868c2
MW
10118 }
10119 }
1da177e4 10120
51219358
MW
10121 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
10122 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
10123 adv_dvc->max_dvc_qng);
10124 } else {
10125 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
10126 }
10127}
27c868c2 10128
51219358
MW
10129/*
10130 * Set the number of commands to queue per device for the
10131 * specified host adapter.
10132 */
10133static int advansys_slave_configure(struct scsi_device *sdev)
10134{
10135 asc_board_t *boardp = ASC_BOARDP(sdev->host);
27c868c2 10136
51219358
MW
10137 if (ASC_NARROW_BOARD(boardp))
10138 advansys_narrow_slave_configure(sdev,
10139 &boardp->dvc_var.asc_dvc_var);
10140 else
10141 advansys_wide_slave_configure(sdev,
10142 &boardp->dvc_var.adv_dvc_var);
1da177e4 10143
51219358
MW
10144 return 0;
10145}
27c868c2 10146
05848b6e
MW
10147static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
10148 struct asc_scsi_q *asc_scsi_q)
51219358 10149{
05848b6e 10150 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
27c868c2
MW
10151
10152 /*
51219358 10153 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
27c868c2 10154 */
05848b6e 10155 asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
27c868c2
MW
10156
10157 /*
51219358 10158 * Build the ASC_SCSI_Q request.
27c868c2 10159 */
05848b6e
MW
10160 asc_scsi_q->cdbptr = &scp->cmnd[0];
10161 asc_scsi_q->q2.cdb_len = scp->cmd_len;
10162 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
10163 asc_scsi_q->q1.target_lun = scp->device->lun;
10164 asc_scsi_q->q2.target_ix =
51219358 10165 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
05848b6e 10166 asc_scsi_q->q1.sense_addr =
51219358 10167 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
05848b6e 10168 asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
27c868c2
MW
10169
10170 /*
51219358
MW
10171 * If there are any outstanding requests for the current target,
10172 * then every 255th request send an ORDERED request. This heuristic
10173 * tries to retain the benefit of request sorting while preventing
10174 * request starvation. 255 is the max number of tags or pending commands
10175 * a device may have outstanding.
10176 *
10177 * The request count is incremented below for every successfully
10178 * started request.
27c868c2 10179 *
27c868c2 10180 */
51219358
MW
10181 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
10182 (boardp->reqcnt[scp->device->id] % 255) == 0) {
05848b6e 10183 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
51219358 10184 } else {
05848b6e 10185 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
51219358 10186 }
27c868c2
MW
10187
10188 /*
51219358
MW
10189 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
10190 * buffer command.
27c868c2 10191 */
51219358
MW
10192 if (scp->use_sg == 0) {
10193 /*
10194 * CDB request of single contiguous buffer.
10195 */
10196 ASC_STATS(scp->device->host, cont_cnt);
10197 scp->SCp.dma_handle = scp->request_bufflen ?
10198 dma_map_single(boardp->dev, scp->request_buffer,
10199 scp->request_bufflen,
10200 scp->sc_data_direction) : 0;
05848b6e
MW
10201 asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
10202 asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen);
51219358
MW
10203 ASC_STATS_ADD(scp->device->host, cont_xfer,
10204 ASC_CEILING(scp->request_bufflen, 512));
05848b6e
MW
10205 asc_scsi_q->q1.sg_queue_cnt = 0;
10206 asc_scsi_q->sg_head = NULL;
51219358
MW
10207 } else {
10208 /*
10209 * CDB scatter-gather request list.
10210 */
10211 int sgcnt;
10212 int use_sg;
10213 struct scatterlist *slp;
05848b6e 10214 struct asc_sg_head *asc_sg_head;
27c868c2 10215
51219358
MW
10216 slp = (struct scatterlist *)scp->request_buffer;
10217 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10218 scp->sc_data_direction);
27c868c2 10219
51219358
MW
10220 if (use_sg > scp->device->host->sg_tablesize) {
10221 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
10222 "sg_tablesize %d\n", boardp->id, use_sg,
10223 scp->device->host->sg_tablesize);
10224 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10225 scp->sc_data_direction);
10226 scp->result = HOST_BYTE(DID_ERROR);
10227 return ASC_ERROR;
10228 }
27c868c2 10229
51219358 10230 ASC_STATS(scp->device->host, sg_cnt);
27c868c2 10231
05848b6e
MW
10232 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
10233 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
10234 if (!asc_sg_head) {
10235 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10236 scp->sc_data_direction);
10237 scp->result = HOST_BYTE(DID_SOFT_ERROR);
10238 return ASC_ERROR;
10239 }
51219358 10240
05848b6e
MW
10241 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
10242 asc_scsi_q->sg_head = asc_sg_head;
10243 asc_scsi_q->q1.data_cnt = 0;
10244 asc_scsi_q->q1.data_addr = 0;
51219358 10245 /* This is a byte value, otherwise it would need to be swapped. */
05848b6e 10246 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
51219358 10247 ASC_STATS_ADD(scp->device->host, sg_elem,
05848b6e 10248 asc_sg_head->entry_cnt);
51219358
MW
10249
10250 /*
10251 * Convert scatter-gather list into ASC_SG_HEAD list.
10252 */
10253 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
05848b6e 10254 asc_sg_head->sg_list[sgcnt].addr =
51219358 10255 cpu_to_le32(sg_dma_address(slp));
05848b6e 10256 asc_sg_head->sg_list[sgcnt].bytes =
51219358
MW
10257 cpu_to_le32(sg_dma_len(slp));
10258 ASC_STATS_ADD(scp->device->host, sg_xfer,
10259 ASC_CEILING(sg_dma_len(slp), 512));
27c868c2
MW
10260 }
10261 }
1da177e4 10262
51219358
MW
10263 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
10264 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10265
10266 return ASC_NOERROR;
27c868c2 10267}
1da177e4 10268
27c868c2 10269/*
51219358 10270 * Build scatter-gather list for Adv Library (Wide Board).
27c868c2 10271 *
51219358
MW
10272 * Additional ADV_SG_BLOCK structures will need to be allocated
10273 * if the total number of scatter-gather elements exceeds
10274 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
10275 * assumed to be physically contiguous.
27c868c2 10276 *
51219358
MW
10277 * Return:
10278 * ADV_SUCCESS(1) - SG List successfully created
10279 * ADV_ERROR(-1) - SG List creation failed
27c868c2 10280 */
51219358
MW
10281static int
10282adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
10283 int use_sg)
27c868c2 10284{
51219358
MW
10285 adv_sgblk_t *sgblkp;
10286 ADV_SCSI_REQ_Q *scsiqp;
10287 struct scatterlist *slp;
10288 int sg_elem_cnt;
10289 ADV_SG_BLOCK *sg_block, *prev_sg_block;
10290 ADV_PADDR sg_block_paddr;
27c868c2 10291 int i;
27c868c2 10292
51219358
MW
10293 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10294 slp = (struct scatterlist *)scp->request_buffer;
10295 sg_elem_cnt = use_sg;
10296 prev_sg_block = NULL;
10297 reqp->sgblkp = NULL;
1da177e4 10298
51219358
MW
10299 for (;;) {
10300 /*
10301 * Allocate a 'adv_sgblk_t' structure from the board free
10302 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
10303 * (15) scatter-gather elements.
10304 */
10305 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
10306 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
10307 ASC_STATS(scp->device->host, adv_build_nosg);
1da177e4 10308
51219358
MW
10309 /*
10310 * Allocation failed. Free 'adv_sgblk_t' structures
10311 * already allocated for the request.
10312 */
10313 while ((sgblkp = reqp->sgblkp) != NULL) {
10314 /* Remove 'sgblkp' from the request list. */
10315 reqp->sgblkp = sgblkp->next_sgblkp;
27c868c2 10316
51219358
MW
10317 /* Add 'sgblkp' to the board free list. */
10318 sgblkp->next_sgblkp = boardp->adv_sgblkp;
10319 boardp->adv_sgblkp = sgblkp;
10320 }
10321 return ASC_BUSY;
10322 }
1da177e4 10323
51219358
MW
10324 /* Complete 'adv_sgblk_t' board allocation. */
10325 boardp->adv_sgblkp = sgblkp->next_sgblkp;
10326 sgblkp->next_sgblkp = NULL;
1da177e4 10327
51219358
MW
10328 /*
10329 * Get 8 byte aligned virtual and physical addresses
10330 * for the allocated ADV_SG_BLOCK structure.
10331 */
10332 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10333 sg_block_paddr = virt_to_bus(sg_block);
27c868c2 10334
51219358
MW
10335 /*
10336 * Check if this is the first 'adv_sgblk_t' for the
10337 * request.
10338 */
10339 if (reqp->sgblkp == NULL) {
10340 /* Request's first scatter-gather block. */
10341 reqp->sgblkp = sgblkp;
27c868c2 10342
51219358
MW
10343 /*
10344 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10345 * address pointers.
10346 */
10347 scsiqp->sg_list_ptr = sg_block;
10348 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
10349 } else {
10350 /* Request's second or later scatter-gather block. */
10351 sgblkp->next_sgblkp = reqp->sgblkp;
10352 reqp->sgblkp = sgblkp;
10353
10354 /*
10355 * Point the previous ADV_SG_BLOCK structure to
10356 * the newly allocated ADV_SG_BLOCK structure.
10357 */
10358 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
27c868c2 10359 }
1da177e4 10360
51219358
MW
10361 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
10362 sg_block->sg_list[i].sg_addr =
10363 cpu_to_le32(sg_dma_address(slp));
10364 sg_block->sg_list[i].sg_count =
10365 cpu_to_le32(sg_dma_len(slp));
10366 ASC_STATS_ADD(scp->device->host, sg_xfer,
10367 ASC_CEILING(sg_dma_len(slp), 512));
27c868c2 10368
51219358
MW
10369 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
10370 sg_block->sg_cnt = i + 1;
10371 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
10372 return ADV_SUCCESS;
10373 }
10374 slp++;
10375 }
10376 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10377 prev_sg_block = sg_block;
27c868c2 10378 }
51219358 10379}
1da177e4 10380
51219358
MW
10381/*
10382 * Build a request structure for the Adv Library (Wide Board).
10383 *
10384 * If an adv_req_t can not be allocated to issue the request,
10385 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
10386 *
10387 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
10388 * microcode for DMA addresses or math operations are byte swapped
10389 * to little-endian order.
10390 */
10391static int
10392adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
10393 ADV_SCSI_REQ_Q **adv_scsiqpp)
10394{
10395 adv_req_t *reqp;
10396 ADV_SCSI_REQ_Q *scsiqp;
10397 int i;
10398 int ret;
1da177e4 10399
27c868c2 10400 /*
51219358
MW
10401 * Allocate an adv_req_t structure from the board to execute
10402 * the command.
27c868c2 10403 */
51219358
MW
10404 if (boardp->adv_reqp == NULL) {
10405 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
10406 ASC_STATS(scp->device->host, adv_build_noreq);
10407 return ASC_BUSY;
10408 } else {
10409 reqp = boardp->adv_reqp;
10410 boardp->adv_reqp = reqp->next_reqp;
10411 reqp->next_reqp = NULL;
27c868c2 10412 }
1da177e4 10413
27c868c2 10414 /*
51219358 10415 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
27c868c2 10416 */
51219358 10417 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
27c868c2
MW
10418
10419 /*
51219358 10420 * Initialize the structure.
27c868c2 10421 */
51219358 10422 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
27c868c2
MW
10423
10424 /*
51219358 10425 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
27c868c2 10426 */
51219358 10427 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
27c868c2
MW
10428
10429 /*
51219358 10430 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
27c868c2 10431 */
51219358 10432 reqp->cmndp = scp;
27c868c2
MW
10433
10434 /*
51219358 10435 * Build the ADV_SCSI_REQ_Q request.
27c868c2 10436 */
51219358
MW
10437
10438 /* Set CDB length and copy it to the request structure. */
10439 scsiqp->cdb_len = scp->cmd_len;
10440 /* Copy first 12 CDB bytes to cdb[]. */
10441 for (i = 0; i < scp->cmd_len && i < 12; i++) {
10442 scsiqp->cdb[i] = scp->cmnd[i];
10443 }
10444 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
10445 for (; i < scp->cmd_len; i++) {
10446 scsiqp->cdb16[i - 12] = scp->cmnd[i];
27c868c2 10447 }
1da177e4 10448
51219358
MW
10449 scsiqp->target_id = scp->device->id;
10450 scsiqp->target_lun = scp->device->lun;
10451
10452 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10453 scsiqp->sense_len = sizeof(scp->sense_buffer);
27c868c2
MW
10454
10455 /*
51219358
MW
10456 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
10457 * buffer command.
27c868c2 10458 */
51219358
MW
10459
10460 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10461 scsiqp->vdata_addr = scp->request_buffer;
10462 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
10463
10464 if (scp->use_sg == 0) {
10465 /*
10466 * CDB request of single contiguous buffer.
10467 */
10468 reqp->sgblkp = NULL;
10469 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10470 if (scp->request_bufflen) {
10471 scsiqp->vdata_addr = scp->request_buffer;
10472 scp->SCp.dma_handle =
10473 dma_map_single(boardp->dev, scp->request_buffer,
10474 scp->request_bufflen,
10475 scp->sc_data_direction);
10476 } else {
10477 scsiqp->vdata_addr = NULL;
10478 scp->SCp.dma_handle = 0;
10479 }
10480 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
10481 scsiqp->sg_list_ptr = NULL;
10482 scsiqp->sg_real_addr = 0;
10483 ASC_STATS(scp->device->host, cont_cnt);
10484 ASC_STATS_ADD(scp->device->host, cont_xfer,
10485 ASC_CEILING(scp->request_bufflen, 512));
10486 } else {
10487 /*
10488 * CDB scatter-gather request list.
10489 */
10490 struct scatterlist *slp;
10491 int use_sg;
10492
10493 slp = (struct scatterlist *)scp->request_buffer;
10494 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10495 scp->sc_data_direction);
10496
10497 if (use_sg > ADV_MAX_SG_LIST) {
10498 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
10499 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
10500 scp->device->host->sg_tablesize);
10501 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10502 scp->sc_data_direction);
10503 scp->result = HOST_BYTE(DID_ERROR);
10504
10505 /*
10506 * Free the 'adv_req_t' structure by adding it back
10507 * to the board free list.
10508 */
10509 reqp->next_reqp = boardp->adv_reqp;
10510 boardp->adv_reqp = reqp;
10511
10512 return ASC_ERROR;
10513 }
10514
10515 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10516 if (ret != ADV_SUCCESS) {
10517 /*
10518 * Free the adv_req_t structure by adding it back to
10519 * the board free list.
10520 */
10521 reqp->next_reqp = boardp->adv_reqp;
10522 boardp->adv_reqp = reqp;
10523
10524 return ret;
10525 }
10526
10527 ASC_STATS(scp->device->host, sg_cnt);
10528 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
27c868c2 10529 }
1da177e4 10530
51219358
MW
10531 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10532 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
27c868c2 10533
51219358 10534 *adv_scsiqpp = scsiqp;
27c868c2 10535
51219358
MW
10536 return ASC_NOERROR;
10537}
10538
10539static int AscSgListToQueue(int sg_list)
10540{
10541 int n_sg_list_qs;
10542
10543 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10544 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10545 n_sg_list_qs++;
10546 return n_sg_list_qs + 1;
10547}
10548
10549static uint
10550AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10551{
10552 uint cur_used_qs;
10553 uint cur_free_qs;
10554 ASC_SCSI_BIT_ID_TYPE target_id;
10555 uchar tid_no;
10556
10557 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10558 tid_no = ASC_TIX_TO_TID(target_ix);
10559 if ((asc_dvc->unit_not_ready & target_id) ||
10560 (asc_dvc->queue_full_or_busy & target_id)) {
10561 return 0;
10562 }
10563 if (n_qs == 1) {
10564 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10565 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
10566 } else {
10567 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10568 (uint) ASC_MIN_FREE_Q;
10569 }
10570 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10571 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10572 if (asc_dvc->cur_dvc_qng[tid_no] >=
10573 asc_dvc->max_dvc_qng[tid_no]) {
10574 return 0;
10575 }
10576 return cur_free_qs;
10577 }
10578 if (n_qs > 1) {
10579 if ((n_qs > asc_dvc->last_q_shortage)
10580 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10581 asc_dvc->last_q_shortage = n_qs;
10582 }
10583 }
10584 return 0;
10585}
10586
10587static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10588{
10589 ushort q_addr;
10590 uchar next_qp;
10591 uchar q_status;
10592
10593 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10594 q_status = (uchar)AscReadLramByte(iop_base,
10595 (ushort)(q_addr +
10596 ASC_SCSIQ_B_STATUS));
10597 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10598 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
10599 return next_qp;
10600 return ASC_QLINK_END;
10601}
10602
10603static uchar
10604AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10605{
10606 uchar i;
27c868c2 10607
51219358
MW
10608 for (i = 0; i < n_free_q; i++) {
10609 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
10610 if (free_q_head == ASC_QLINK_END)
10611 break;
10612 }
10613 return free_q_head;
10614}
27c868c2 10615
51219358
MW
10616/*
10617 * void
10618 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10619 *
10620 * Calling/Exit State:
10621 * none
10622 *
10623 * Description:
10624 * Output an ASC_SCSI_Q structure to the chip
10625 */
10626static void
10627DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10628{
10629 int i;
10630
10631 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
10632 AscSetChipLramAddr(iop_base, s_addr);
10633 for (i = 0; i < 2 * words; i += 2) {
10634 if (i == 4 || i == 20) {
10635 continue;
10636 }
10637 outpw(iop_base + IOP_RAM_DATA,
10638 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
27c868c2 10639 }
51219358 10640}
1da177e4 10641
51219358
MW
10642static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10643{
10644 ushort q_addr;
10645 uchar tid_no;
10646 uchar sdtr_data;
10647 uchar syn_period_ix;
10648 uchar syn_offset;
10649 PortAddr iop_base;
10650
10651 iop_base = asc_dvc->iop_base;
10652 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10653 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10654 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10655 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10656 syn_period_ix =
10657 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
10658 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
10659 AscMsgOutSDTR(asc_dvc,
10660 asc_dvc->sdtr_period_tbl[syn_period_ix],
10661 syn_offset);
10662 scsiq->q1.cntl |= QC_MSG_OUT;
10663 }
10664 q_addr = ASC_QNO_TO_QADDR(q_no);
10665 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
10666 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
27c868c2 10667 }
51219358
MW
10668 scsiq->q1.status = QS_FREE;
10669 AscMemWordCopyPtrToLram(iop_base,
10670 q_addr + ASC_SCSIQ_CDB_BEG,
10671 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
10672
10673 DvcPutScsiQ(iop_base,
10674 q_addr + ASC_SCSIQ_CPY_BEG,
10675 (uchar *)&scsiq->q1.cntl,
10676 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
10677 AscWriteLramWord(iop_base,
10678 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
10679 (ushort)(((ushort)scsiq->q1.
10680 q_no << 8) | (ushort)QS_READY));
10681 return 1;
10682}
10683
10684static int
10685AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10686{
10687 int sta;
10688 int i;
10689 ASC_SG_HEAD *sg_head;
10690 ASC_SG_LIST_Q scsi_sg_q;
10691 ASC_DCNT saved_data_addr;
10692 ASC_DCNT saved_data_cnt;
10693 PortAddr iop_base;
10694 ushort sg_list_dwords;
10695 ushort sg_index;
10696 ushort sg_entry_cnt;
10697 ushort q_addr;
10698 uchar next_qp;
1da177e4 10699
51219358
MW
10700 iop_base = asc_dvc->iop_base;
10701 sg_head = scsiq->sg_head;
10702 saved_data_addr = scsiq->q1.data_addr;
10703 saved_data_cnt = scsiq->q1.data_cnt;
10704 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
10705 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
10706#if CC_VERY_LONG_SG_LIST
27c868c2 10707 /*
51219358
MW
10708 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
10709 * then not all SG elements will fit in the allocated queues.
10710 * The rest of the SG elements will be copied when the RISC
10711 * completes the SG elements that fit and halts.
27c868c2 10712 */
51219358
MW
10713 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10714 /*
10715 * Set sg_entry_cnt to be the number of SG elements that
10716 * will fit in the allocated SG queues. It is minus 1, because
10717 * the first SG element is handled above. ASC_MAX_SG_LIST is
10718 * already inflated by 1 to account for this. For example it
10719 * may be 50 which is 1 + 7 queues * 7 SG elements.
10720 */
10721 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
27c868c2 10722
51219358
MW
10723 /*
10724 * Keep track of remaining number of SG elements that will
10725 * need to be handled from a_isr.c.
10726 */
10727 scsiq->remain_sg_entry_cnt =
10728 sg_head->entry_cnt - ASC_MAX_SG_LIST;
10729 } else {
10730#endif /* CC_VERY_LONG_SG_LIST */
10731 /*
10732 * Set sg_entry_cnt to be the number of SG elements that
10733 * will fit in the allocated SG queues. It is minus 1, because
10734 * the first SG element is handled above.
10735 */
10736 sg_entry_cnt = sg_head->entry_cnt - 1;
10737#if CC_VERY_LONG_SG_LIST
10738 }
10739#endif /* CC_VERY_LONG_SG_LIST */
10740 if (sg_entry_cnt != 0) {
10741 scsiq->q1.cntl |= QC_SG_HEAD;
10742 q_addr = ASC_QNO_TO_QADDR(q_no);
10743 sg_index = 1;
10744 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10745 scsi_sg_q.sg_head_qp = q_no;
10746 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10747 for (i = 0; i < sg_head->queue_cnt; i++) {
10748 scsi_sg_q.seq_no = i + 1;
10749 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10750 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10751 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10752 if (i == 0) {
10753 scsi_sg_q.sg_list_cnt =
10754 ASC_SG_LIST_PER_Q;
10755 scsi_sg_q.sg_cur_list_cnt =
10756 ASC_SG_LIST_PER_Q;
10757 } else {
10758 scsi_sg_q.sg_list_cnt =
10759 ASC_SG_LIST_PER_Q - 1;
10760 scsi_sg_q.sg_cur_list_cnt =
10761 ASC_SG_LIST_PER_Q - 1;
10762 }
10763 } else {
10764#if CC_VERY_LONG_SG_LIST
10765 /*
10766 * This is the last SG queue in the list of
10767 * allocated SG queues. If there are more
10768 * SG elements than will fit in the allocated
10769 * queues, then set the QCSG_SG_XFER_MORE flag.
10770 */
10771 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10772 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10773 } else {
10774#endif /* CC_VERY_LONG_SG_LIST */
10775 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10776#if CC_VERY_LONG_SG_LIST
10777 }
10778#endif /* CC_VERY_LONG_SG_LIST */
10779 sg_list_dwords = sg_entry_cnt << 1;
10780 if (i == 0) {
10781 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10782 scsi_sg_q.sg_cur_list_cnt =
10783 sg_entry_cnt;
10784 } else {
10785 scsi_sg_q.sg_list_cnt =
10786 sg_entry_cnt - 1;
10787 scsi_sg_q.sg_cur_list_cnt =
10788 sg_entry_cnt - 1;
10789 }
10790 sg_entry_cnt = 0;
10791 }
10792 next_qp = AscReadLramByte(iop_base,
10793 (ushort)(q_addr +
10794 ASC_SCSIQ_B_FWD));
10795 scsi_sg_q.q_no = next_qp;
10796 q_addr = ASC_QNO_TO_QADDR(next_qp);
10797 AscMemWordCopyPtrToLram(iop_base,
10798 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10799 (uchar *)&scsi_sg_q,
10800 sizeof(ASC_SG_LIST_Q) >> 1);
10801 AscMemDWordCopyPtrToLram(iop_base,
10802 q_addr + ASC_SGQ_LIST_BEG,
10803 (uchar *)&sg_head->
10804 sg_list[sg_index],
10805 sg_list_dwords);
10806 sg_index += ASC_SG_LIST_PER_Q;
10807 scsiq->next_sg_index = sg_index;
27c868c2 10808 }
51219358
MW
10809 } else {
10810 scsiq->q1.cntl &= ~QC_SG_HEAD;
27c868c2 10811 }
51219358
MW
10812 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10813 scsiq->q1.data_addr = saved_data_addr;
10814 scsiq->q1.data_cnt = saved_data_cnt;
10815 return (sta);
10816}
27c868c2 10817
51219358
MW
10818static int
10819AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10820{
10821 PortAddr iop_base;
10822 uchar free_q_head;
10823 uchar next_qp;
10824 uchar tid_no;
10825 uchar target_ix;
10826 int sta;
27c868c2 10827
51219358
MW
10828 iop_base = asc_dvc->iop_base;
10829 target_ix = scsiq->q2.target_ix;
10830 tid_no = ASC_TIX_TO_TID(target_ix);
10831 sta = 0;
10832 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
10833 if (n_q_required > 1) {
10834 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
10835 (uchar)n_q_required);
10836 if (next_qp != ASC_QLINK_END) {
10837 asc_dvc->last_q_shortage = 0;
10838 scsiq->sg_head->queue_cnt = n_q_required - 1;
10839 scsiq->q1.q_no = free_q_head;
10840 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10841 free_q_head);
10842 }
10843 } else if (n_q_required == 1) {
10844 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
10845 if (next_qp != ASC_QLINK_END) {
10846 scsiq->q1.q_no = free_q_head;
10847 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
27c868c2
MW
10848 }
10849 }
51219358
MW
10850 if (sta == 1) {
10851 AscPutVarFreeQHead(iop_base, next_qp);
10852 asc_dvc->cur_total_qng += n_q_required;
10853 asc_dvc->cur_dvc_qng[tid_no]++;
27c868c2 10854 }
51219358
MW
10855 return sta;
10856}
27c868c2 10857
51219358
MW
10858#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10859static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
10860 INQUIRY,
10861 REQUEST_SENSE,
10862 READ_CAPACITY,
10863 READ_TOC,
10864 MODE_SELECT,
10865 MODE_SENSE,
10866 MODE_SELECT_10,
10867 MODE_SENSE_10,
10868 0xFF,
10869 0xFF,
10870 0xFF,
10871 0xFF,
10872 0xFF,
10873 0xFF,
10874 0xFF,
10875 0xFF
10876};
27c868c2 10877
51219358
MW
10878static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10879{
10880 PortAddr iop_base;
10881 int sta;
10882 int n_q_required;
10883 int disable_syn_offset_one_fix;
10884 int i;
10885 ASC_PADDR addr;
10886 ushort sg_entry_cnt = 0;
10887 ushort sg_entry_cnt_minus_one = 0;
10888 uchar target_ix;
10889 uchar tid_no;
10890 uchar sdtr_data;
10891 uchar extra_bytes;
10892 uchar scsi_cmd;
10893 uchar disable_cmd;
10894 ASC_SG_HEAD *sg_head;
10895 ASC_DCNT data_cnt;
27c868c2 10896
51219358
MW
10897 iop_base = asc_dvc->iop_base;
10898 sg_head = scsiq->sg_head;
10899 if (asc_dvc->err_code != 0)
10900 return (ERR);
10901 scsiq->q1.q_no = 0;
10902 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10903 scsiq->q1.extra_bytes = 0;
27c868c2 10904 }
51219358
MW
10905 sta = 0;
10906 target_ix = scsiq->q2.target_ix;
10907 tid_no = ASC_TIX_TO_TID(target_ix);
10908 n_q_required = 1;
10909 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10910 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10911 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10912 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10913 AscMsgOutSDTR(asc_dvc,
10914 asc_dvc->
10915 sdtr_period_tbl[(sdtr_data >> 4) &
10916 (uchar)(asc_dvc->
10917 max_sdtr_index -
10918 1)],
10919 (uchar)(sdtr_data & (uchar)
10920 ASC_SYN_MAX_OFFSET));
10921 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10922 }
10923 }
10924 if (asc_dvc->in_critical_cnt != 0) {
10925 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10926 return (ERR);
10927 }
10928 asc_dvc->in_critical_cnt++;
10929 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10930 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10931 asc_dvc->in_critical_cnt--;
10932 return (ERR);
10933 }
10934#if !CC_VERY_LONG_SG_LIST
10935 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10936 asc_dvc->in_critical_cnt--;
10937 return (ERR);
10938 }
10939#endif /* !CC_VERY_LONG_SG_LIST */
10940 if (sg_entry_cnt == 1) {
10941 scsiq->q1.data_addr =
10942 (ADV_PADDR)sg_head->sg_list[0].addr;
10943 scsiq->q1.data_cnt =
10944 (ADV_DCNT)sg_head->sg_list[0].bytes;
10945 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10946 }
10947 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10948 }
10949 scsi_cmd = scsiq->cdbptr[0];
10950 disable_syn_offset_one_fix = FALSE;
10951 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10952 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10953 if (scsiq->q1.cntl & QC_SG_HEAD) {
10954 data_cnt = 0;
10955 for (i = 0; i < sg_entry_cnt; i++) {
10956 data_cnt +=
10957 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
10958 bytes);
10959 }
10960 } else {
10961 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10962 }
10963 if (data_cnt != 0UL) {
10964 if (data_cnt < 512UL) {
10965 disable_syn_offset_one_fix = TRUE;
10966 } else {
10967 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
10968 i++) {
10969 disable_cmd =
10970 _syn_offset_one_disable_cmd[i];
10971 if (disable_cmd == 0xFF) {
10972 break;
10973 }
10974 if (scsi_cmd == disable_cmd) {
10975 disable_syn_offset_one_fix =
10976 TRUE;
10977 break;
10978 }
10979 }
10980 }
10981 }
10982 }
10983 if (disable_syn_offset_one_fix) {
10984 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10985 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10986 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10987 } else {
10988 scsiq->q2.tag_code &= 0x27;
10989 }
10990 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10991 if (asc_dvc->bug_fix_cntl) {
10992 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10993 if ((scsi_cmd == READ_6) ||
10994 (scsi_cmd == READ_10)) {
10995 addr =
10996 (ADV_PADDR)le32_to_cpu(sg_head->
10997 sg_list
10998 [sg_entry_cnt_minus_one].
10999 addr) +
11000 (ADV_DCNT)le32_to_cpu(sg_head->
11001 sg_list
11002 [sg_entry_cnt_minus_one].
11003 bytes);
11004 extra_bytes =
11005 (uchar)((ushort)addr & 0x0003);
11006 if ((extra_bytes != 0)
11007 &&
11008 ((scsiq->q2.
11009 tag_code &
11010 ASC_TAG_FLAG_EXTRA_BYTES)
11011 == 0)) {
11012 scsiq->q2.tag_code |=
11013 ASC_TAG_FLAG_EXTRA_BYTES;
11014 scsiq->q1.extra_bytes =
11015 extra_bytes;
11016 data_cnt =
11017 le32_to_cpu(sg_head->
11018 sg_list
11019 [sg_entry_cnt_minus_one].
11020 bytes);
11021 data_cnt -=
11022 (ASC_DCNT) extra_bytes;
11023 sg_head->
11024 sg_list
11025 [sg_entry_cnt_minus_one].
11026 bytes =
11027 cpu_to_le32(data_cnt);
11028 }
11029 }
11030 }
11031 }
11032 sg_head->entry_to_copy = sg_head->entry_cnt;
11033#if CC_VERY_LONG_SG_LIST
27c868c2 11034 /*
51219358
MW
11035 * Set the sg_entry_cnt to the maximum possible. The rest of
11036 * the SG elements will be copied when the RISC completes the
11037 * SG elements that fit and halts.
27c868c2 11038 */
51219358
MW
11039 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
11040 sg_entry_cnt = ASC_MAX_SG_LIST;
11041 }
11042#endif /* CC_VERY_LONG_SG_LIST */
11043 n_q_required = AscSgListToQueue(sg_entry_cnt);
11044 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11045 (uint) n_q_required)
11046 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11047 if ((sta =
11048 AscSendScsiQueue(asc_dvc, scsiq,
11049 n_q_required)) == 1) {
11050 asc_dvc->in_critical_cnt--;
11051 return (sta);
27c868c2 11052 }
51219358
MW
11053 }
11054 } else {
11055 if (asc_dvc->bug_fix_cntl) {
11056 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11057 if ((scsi_cmd == READ_6) ||
11058 (scsi_cmd == READ_10)) {
11059 addr =
11060 le32_to_cpu(scsiq->q1.data_addr) +
11061 le32_to_cpu(scsiq->q1.data_cnt);
11062 extra_bytes =
11063 (uchar)((ushort)addr & 0x0003);
11064 if ((extra_bytes != 0)
11065 &&
11066 ((scsiq->q2.
11067 tag_code &
11068 ASC_TAG_FLAG_EXTRA_BYTES)
11069 == 0)) {
11070 data_cnt =
11071 le32_to_cpu(scsiq->q1.
11072 data_cnt);
11073 if (((ushort)data_cnt & 0x01FF)
11074 == 0) {
11075 scsiq->q2.tag_code |=
11076 ASC_TAG_FLAG_EXTRA_BYTES;
11077 data_cnt -= (ASC_DCNT)
11078 extra_bytes;
11079 scsiq->q1.data_cnt =
11080 cpu_to_le32
11081 (data_cnt);
11082 scsiq->q1.extra_bytes =
11083 extra_bytes;
11084 }
11085 }
11086 }
11087 }
11088 }
11089 n_q_required = 1;
11090 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11091 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11092 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11093 n_q_required)) == 1) {
11094 asc_dvc->in_critical_cnt--;
11095 return (sta);
27c868c2
MW
11096 }
11097 }
11098 }
51219358
MW
11099 asc_dvc->in_critical_cnt--;
11100 return (sta);
1da177e4
LT
11101}
11102
11103/*
51219358 11104 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
1da177e4 11105 *
51219358
MW
11106 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
11107 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
11108 * RISC to notify it a new command is ready to be executed.
11109 *
11110 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
11111 * set to SCSI_MAX_RETRY.
11112 *
11113 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
11114 * for DMA addresses or math operations are byte swapped to little-endian
11115 * order.
11116 *
11117 * Return:
11118 * ADV_SUCCESS(1) - The request was successfully queued.
11119 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
11120 * request completes.
11121 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
11122 * host IC error.
11123 */
11124static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
11125{
11126 AdvPortAddr iop_base;
11127 ADV_DCNT req_size;
11128 ADV_PADDR req_paddr;
11129 ADV_CARR_T *new_carrp;
1da177e4 11130
27c868c2 11131 /*
51219358 11132 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
27c868c2 11133 */
51219358
MW
11134 if (scsiq->target_id > ADV_MAX_TID) {
11135 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
11136 scsiq->done_status = QD_WITH_ERROR;
27c868c2
MW
11137 return ADV_ERROR;
11138 }
1da177e4 11139
51219358 11140 iop_base = asc_dvc->iop_base;
1da177e4 11141
27c868c2 11142 /*
51219358
MW
11143 * Allocate a carrier ensuring at least one carrier always
11144 * remains on the freelist and initialize fields.
27c868c2 11145 */
51219358
MW
11146 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
11147 return ADV_BUSY;
27c868c2 11148 }
51219358
MW
11149 asc_dvc->carr_freelist = (ADV_CARR_T *)
11150 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
11151 asc_dvc->carr_pending_cnt++;
1da177e4 11152
27c868c2 11153 /*
51219358
MW
11154 * Set the carrier to be a stopper by setting 'next_vpa'
11155 * to the stopper value. The current stopper will be changed
11156 * below to point to the new stopper.
27c868c2 11157 */
51219358 11158 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
27c868c2
MW
11159
11160 /*
51219358 11161 * Clear the ADV_SCSI_REQ_Q done flag.
27c868c2 11162 */
51219358 11163 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
27c868c2 11164
51219358
MW
11165 req_size = sizeof(ADV_SCSI_REQ_Q);
11166 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
11167 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
27c868c2 11168
51219358
MW
11169 BUG_ON(req_paddr & 31);
11170 BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
11171
11172 /* Wait for assertion before making little-endian */
11173 req_paddr = cpu_to_le32(req_paddr);
27c868c2 11174
51219358
MW
11175 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
11176 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
11177 scsiq->scsiq_rptr = req_paddr;
11178
11179 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
27c868c2 11180 /*
51219358
MW
11181 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
11182 * order during initialization.
27c868c2 11183 */
51219358 11184 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
1da177e4 11185
27c868c2 11186 /*
51219358
MW
11187 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
11188 * the microcode. The newly allocated stopper will become the new
11189 * stopper.
27c868c2 11190 */
51219358 11191 asc_dvc->icq_sp->areq_vpa = req_paddr;
1da177e4 11192
27c868c2 11193 /*
51219358
MW
11194 * Set the 'next_vpa' pointer for the old stopper to be the
11195 * physical address of the new stopper. The RISC can only
11196 * follow physical addresses.
27c868c2 11197 */
51219358 11198 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
27c868c2
MW
11199
11200 /*
51219358 11201 * Set the host adapter stopper pointer to point to the new carrier.
27c868c2 11202 */
51219358
MW
11203 asc_dvc->icq_sp = new_carrp;
11204
11205 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
11206 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
11207 /*
11208 * Tickle the RISC to tell it to read its Command Queue Head pointer.
11209 */
11210 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
11211 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
11212 /*
11213 * Clear the tickle value. In the ASC-3550 the RISC flag
11214 * command 'clr_tickle_a' does not work unless the host
11215 * value is cleared.
11216 */
11217 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
11218 ADV_TICKLE_NOP);
11219 }
11220 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
11221 /*
11222 * Notify the RISC a carrier is ready by writing the physical
11223 * address of the new carrier stopper to the COMMA register.
11224 */
11225 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
11226 le32_to_cpu(new_carrp->carr_pa));
27c868c2 11227 }
1da177e4 11228
51219358
MW
11229 return ADV_SUCCESS;
11230}
11231
11232/*
11233 * Execute a single 'Scsi_Cmnd'.
11234 *
11235 * The function 'done' is called when the request has been completed.
11236 *
11237 * Scsi_Cmnd:
11238 *
11239 * host - board controlling device
11240 * device - device to send command
11241 * target - target of device
11242 * lun - lun of device
11243 * cmd_len - length of SCSI CDB
11244 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
11245 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
11246 *
11247 * if (use_sg == 0) {
11248 * request_buffer - buffer address for request
11249 * request_bufflen - length of request buffer
11250 * } else {
11251 * request_buffer - pointer to scatterlist structure
11252 * }
11253 *
11254 * sense_buffer - sense command buffer
11255 *
11256 * result (4 bytes of an int):
11257 * Byte Meaning
11258 * 0 SCSI Status Byte Code
11259 * 1 SCSI One Byte Message Code
11260 * 2 Host Error Code
11261 * 3 Mid-Level Error Code
11262 *
11263 * host driver fields:
11264 * SCp - Scsi_Pointer used for command processing status
11265 * scsi_done - used to save caller's done function
11266 * host_scribble - used for pointer to another struct scsi_cmnd
11267 *
11268 * If this function returns ASC_NOERROR the request will be completed
11269 * from the interrupt handler.
11270 *
11271 * If this function returns ASC_ERROR the host error code has been set,
11272 * and the called must call asc_scsi_done.
11273 *
11274 * If ASC_BUSY is returned the request will be returned to the midlayer
11275 * and re-tried later.
11276 */
11277static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
11278{
41d2493d
MW
11279 int ret, err_code;
11280 asc_board_t *boardp = ASC_BOARDP(scp->device->host);
51219358 11281
41d2493d 11282 ASC_DBG1(1, "asc_execute_scsi_cmnd: scp 0x%p\n", scp);
27c868c2 11283
51219358 11284 if (ASC_NARROW_BOARD(boardp)) {
41d2493d 11285 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
05848b6e 11286 struct asc_scsi_q asc_scsi_q;
27c868c2 11287
41d2493d 11288 /* asc_build_req() can not return ASC_BUSY. */
05848b6e
MW
11289 ret = asc_build_req(boardp, scp, &asc_scsi_q);
11290 if (ret == ASC_ERROR) {
51219358
MW
11291 ASC_STATS(scp->device->host, build_error);
11292 return ASC_ERROR;
11293 }
1da177e4 11294
41d2493d 11295 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
05848b6e 11296 kfree(asc_scsi_q.sg_head);
41d2493d 11297 err_code = asc_dvc->err_code;
51219358 11298 } else {
41d2493d
MW
11299 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
11300 ADV_SCSI_REQ_Q *adv_scsiqp;
27c868c2 11301
51219358
MW
11302 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
11303 case ASC_NOERROR:
11304 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
11305 "ASC_NOERROR\n");
11306 break;
11307 case ASC_BUSY:
11308 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
11309 "ASC_BUSY\n");
11310 /*
11311 * The asc_stats fields 'adv_build_noreq' and
11312 * 'adv_build_nosg' count wide board busy conditions.
11313 * They are updated in adv_build_req and
11314 * adv_get_sglist, respectively.
11315 */
11316 return ASC_BUSY;
11317 case ASC_ERROR:
11318 default:
11319 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
11320 "ASC_ERROR\n");
11321 ASC_STATS(scp->device->host, build_error);
11322 return ASC_ERROR;
11323 }
11324
41d2493d
MW
11325 ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
11326 err_code = adv_dvc->err_code;
11327 }
11328
11329 switch (ret) {
11330 case ASC_NOERROR:
11331 ASC_STATS(scp->device->host, exe_noerror);
11332 /*
11333 * Increment monotonically increasing per device
11334 * successful request counter. Wrapping doesn't matter.
11335 */
11336 boardp->reqcnt[scp->device->id]++;
11337 ASC_DBG(1, "asc_execute_scsi_cmnd: ExeScsiQueue(), "
11338 "ASC_NOERROR\n");
11339 break;
11340 case ASC_BUSY:
11341 ASC_STATS(scp->device->host, exe_busy);
11342 break;
11343 case ASC_ERROR:
11344 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11345 "ASC_ERROR, err_code 0x%x\n", boardp->id, err_code);
11346 ASC_STATS(scp->device->host, exe_error);
11347 scp->result = HOST_BYTE(DID_ERROR);
11348 break;
11349 default:
11350 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11351 "unknown, err_code 0x%x\n", boardp->id, err_code);
11352 ASC_STATS(scp->device->host, exe_unknown);
11353 scp->result = HOST_BYTE(DID_ERROR);
11354 break;
27c868c2 11355 }
1da177e4 11356
51219358
MW
11357 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
11358 return ret;
11359}
27c868c2 11360
51219358
MW
11361/*
11362 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11363 *
11364 * This function always returns 0. Command return status is saved
11365 * in the 'scp' result field.
11366 */
11367static int
11368advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11369{
11370 struct Scsi_Host *shost = scp->device->host;
11371 asc_board_t *boardp = ASC_BOARDP(shost);
11372 unsigned long flags;
11373 int asc_res, result = 0;
27c868c2 11374
51219358
MW
11375 ASC_STATS(shost, queuecommand);
11376 scp->scsi_done = done;
27c868c2
MW
11377
11378 /*
51219358
MW
11379 * host_lock taken by mid-level prior to call, but need
11380 * to protect against own ISR
27c868c2 11381 */
51219358
MW
11382 spin_lock_irqsave(&boardp->lock, flags);
11383 asc_res = asc_execute_scsi_cmnd(scp);
11384 spin_unlock_irqrestore(&boardp->lock, flags);
11385
11386 switch (asc_res) {
11387 case ASC_NOERROR:
11388 break;
11389 case ASC_BUSY:
11390 result = SCSI_MLQUEUE_HOST_BUSY;
11391 break;
11392 case ASC_ERROR:
11393 default:
11394 asc_scsi_done(scp);
11395 break;
11396 }
11397
11398 return result;
11399}
11400
11401static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11402{
11403 PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11404 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
11405 return inpw(eisa_cfg_iop);
11406}
11407
11408/*
11409 * Return the BIOS address of the adapter at the specified
11410 * I/O port and with the specified bus type.
11411 */
11412static unsigned short __devinit
11413AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11414{
11415 unsigned short cfg_lsw;
11416 unsigned short bios_addr;
27c868c2
MW
11417
11418 /*
51219358
MW
11419 * The PCI BIOS is re-located by the motherboard BIOS. Because
11420 * of this the driver can not determine where a PCI BIOS is
11421 * loaded and executes.
27c868c2 11422 */
51219358
MW
11423 if (bus_type & ASC_IS_PCI)
11424 return 0;
27c868c2 11425
51219358
MW
11426 if ((bus_type & ASC_IS_EISA) != 0) {
11427 cfg_lsw = AscGetEisaChipCfg(iop_base);
11428 cfg_lsw &= 0x000F;
11429 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
11430 return bios_addr;
11431 }
27c868c2 11432
51219358 11433 cfg_lsw = AscGetChipCfgLsw(iop_base);
27c868c2
MW
11434
11435 /*
51219358 11436 * ISA PnP uses the top bit as the 32K BIOS flag
27c868c2 11437 */
51219358
MW
11438 if (bus_type == ASC_IS_ISAPNP)
11439 cfg_lsw &= 0x7FFF;
11440 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
11441 return bios_addr;
11442}
11443
11444static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11445{
11446 ushort cfg_lsw;
11447
11448 if (AscGetChipScsiID(iop_base) == new_host_id) {
11449 return (new_host_id);
27c868c2 11450 }
51219358
MW
11451 cfg_lsw = AscGetChipCfgLsw(iop_base);
11452 cfg_lsw &= 0xF8FF;
11453 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
11454 AscSetChipCfgLsw(iop_base, cfg_lsw);
11455 return (AscGetChipScsiID(iop_base));
11456}
27c868c2 11457
51219358
MW
11458static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11459{
11460 unsigned char sc;
27c868c2 11461
51219358
MW
11462 AscSetBank(iop_base, 1);
11463 sc = inp(iop_base + IOP_REG_SC);
11464 AscSetBank(iop_base, 0);
11465 return sc;
11466}
27c868c2 11467
51219358
MW
11468static unsigned char __devinit
11469AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11470{
11471 if (bus_type & ASC_IS_EISA) {
11472 PortAddr eisa_iop;
11473 unsigned char revision;
11474 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11475 (PortAddr) ASC_EISA_REV_IOP_MASK;
11476 revision = inp(eisa_iop);
11477 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
27c868c2 11478 }
51219358
MW
11479 return AscGetChipVerNo(iop_base);
11480}
27c868c2 11481
51219358
MW
11482static void __devinit AscToggleIRQAct(PortAddr iop_base)
11483{
11484 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
11485 AscSetChipStatus(iop_base, 0);
11486 return;
11487}
27c868c2 11488
51219358
MW
11489static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
11490{
11491 ushort cfg_lsw;
11492 uchar chip_irq;
27c868c2 11493
51219358
MW
11494 if ((bus_type & ASC_IS_EISA) != 0) {
11495 cfg_lsw = AscGetEisaChipCfg(iop_base);
11496 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
11497 if ((chip_irq == 13) || (chip_irq > 15)) {
11498 return (0);
11499 }
11500 return (chip_irq);
11501 }
11502 if ((bus_type & ASC_IS_VL) != 0) {
11503 cfg_lsw = AscGetChipCfgLsw(iop_base);
11504 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
11505 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
11506 return (0);
11507 }
11508 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
11509 }
11510 cfg_lsw = AscGetChipCfgLsw(iop_base);
11511 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
11512 if (chip_irq == 3)
11513 chip_irq += (uchar)2;
11514 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
11515}
27c868c2 11516
51219358
MW
11517static uchar __devinit
11518AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
11519{
11520 ushort cfg_lsw;
27c868c2 11521
51219358
MW
11522 if ((bus_type & ASC_IS_VL) != 0) {
11523 if (irq_no != 0) {
11524 if ((irq_no < ASC_MIN_IRQ_NO)
11525 || (irq_no > ASC_MAX_IRQ_NO)) {
11526 irq_no = 0;
11527 } else {
11528 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
27c868c2
MW
11529 }
11530 }
51219358
MW
11531 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
11532 cfg_lsw |= (ushort)0x0010;
11533 AscSetChipCfgLsw(iop_base, cfg_lsw);
11534 AscToggleIRQAct(iop_base);
11535 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
11536 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
11537 AscSetChipCfgLsw(iop_base, cfg_lsw);
11538 AscToggleIRQAct(iop_base);
11539 return (AscGetChipIRQ(iop_base, bus_type));
11540 }
11541 if ((bus_type & (ASC_IS_ISA)) != 0) {
11542 if (irq_no == 15)
11543 irq_no -= (uchar)2;
11544 irq_no -= (uchar)ASC_MIN_IRQ_NO;
11545 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
11546 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
11547 AscSetChipCfgLsw(iop_base, cfg_lsw);
11548 return (AscGetChipIRQ(iop_base, bus_type));
27c868c2 11549 }
51219358
MW
11550 return (0);
11551}
1da177e4 11552
51219358
MW
11553#ifdef CONFIG_ISA
11554static void __devinit AscEnableIsaDma(uchar dma_channel)
11555{
11556 if (dma_channel < 4) {
11557 outp(0x000B, (ushort)(0xC0 | dma_channel));
11558 outp(0x000A, dma_channel);
11559 } else if (dma_channel < 8) {
11560 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
11561 outp(0x00D4, (ushort)(dma_channel - 4));
11562 }
11563 return;
11564}
11565#endif /* CONFIG_ISA */
11566
11567static int AscStopQueueExe(PortAddr iop_base)
11568{
11569 int count = 0;
11570
11571 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11572 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11573 ASC_STOP_REQ_RISC_STOP);
11574 do {
11575 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11576 ASC_STOP_ACK_RISC_STOP) {
11577 return (1);
11578 }
11579 mdelay(100);
11580 } while (count++ < 20);
11581 }
11582 return (0);
11583}
11584
11585static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11586{
11587 if (bus_type & ASC_IS_ISA)
11588 return ASC_MAX_ISA_DMA_COUNT;
11589 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11590 return ASC_MAX_VL_DMA_COUNT;
11591 return ASC_MAX_PCI_DMA_COUNT;
27c868c2 11592}
1da177e4 11593
51219358
MW
11594#ifdef CONFIG_ISA
11595static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
27c868c2 11596{
51219358 11597 ushort channel;
1da177e4 11598
51219358
MW
11599 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11600 if (channel == 0x03)
11601 return (0);
11602 else if (channel == 0x00)
11603 return (7);
11604 return (channel + 4);
11605}
1da177e4 11606
51219358
MW
11607static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11608{
11609 ushort cfg_lsw;
11610 uchar value;
1da177e4 11611
51219358
MW
11612 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11613 if (dma_channel == 7)
11614 value = 0x00;
11615 else
11616 value = dma_channel - 4;
11617 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11618 cfg_lsw |= value;
11619 AscSetChipCfgLsw(iop_base, cfg_lsw);
11620 return (AscGetIsaDmaChannel(iop_base));
11621 }
11622 return 0;
11623}
1da177e4 11624
51219358
MW
11625static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11626{
11627 uchar speed_value;
1da177e4 11628
51219358
MW
11629 AscSetBank(iop_base, 1);
11630 speed_value = AscReadChipDmaSpeed(iop_base);
11631 speed_value &= 0x07;
11632 AscSetBank(iop_base, 0);
11633 return speed_value;
11634}
1da177e4 11635
51219358
MW
11636static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11637{
11638 speed_value &= 0x07;
11639 AscSetBank(iop_base, 1);
11640 AscWriteChipDmaSpeed(iop_base, speed_value);
11641 AscSetBank(iop_base, 0);
11642 return AscGetIsaDmaSpeed(iop_base);
11643}
11644#endif /* CONFIG_ISA */
1da177e4 11645
51219358
MW
11646static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11647{
11648 int i;
11649 PortAddr iop_base;
11650 ushort warn_code;
11651 uchar chip_version;
1da177e4 11652
51219358
MW
11653 iop_base = asc_dvc->iop_base;
11654 warn_code = 0;
11655 asc_dvc->err_code = 0;
11656 if ((asc_dvc->bus_type &
11657 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
11658 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
27c868c2 11659 }
51219358
MW
11660 AscSetChipControl(iop_base, CC_HALT);
11661 AscSetChipStatus(iop_base, 0);
11662 asc_dvc->bug_fix_cntl = 0;
11663 asc_dvc->pci_fix_asyn_xfer = 0;
11664 asc_dvc->pci_fix_asyn_xfer_always = 0;
11665 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
11666 asc_dvc->sdtr_done = 0;
11667 asc_dvc->cur_total_qng = 0;
11668 asc_dvc->is_in_int = 0;
11669 asc_dvc->in_critical_cnt = 0;
11670 asc_dvc->last_q_shortage = 0;
11671 asc_dvc->use_tagged_qng = 0;
11672 asc_dvc->no_scam = 0;
11673 asc_dvc->unit_not_ready = 0;
11674 asc_dvc->queue_full_or_busy = 0;
11675 asc_dvc->redo_scam = 0;
11676 asc_dvc->res2 = 0;
11677 asc_dvc->host_init_sdtr_index = 0;
11678 asc_dvc->cfg->can_tagged_qng = 0;
11679 asc_dvc->cfg->cmd_qng_enabled = 0;
11680 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
11681 asc_dvc->init_sdtr = 0;
11682 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
11683 asc_dvc->scsi_reset_wait = 3;
11684 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
11685 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
11686 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
11687 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
11688 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
11689 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
11690 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
11691 ASC_LIB_VERSION_MINOR;
11692 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11693 asc_dvc->cfg->chip_version = chip_version;
11694 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
11695 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
11696 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
11697 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
11698 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
11699 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
11700 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
11701 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
11702 asc_dvc->max_sdtr_index = 7;
11703 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
11704 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
11705 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
11706 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
11707 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
11708 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
11709 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
11710 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
11711 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
11712 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
11713 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
11714 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
11715 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
11716 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
11717 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
11718 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
11719 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
11720 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
11721 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
11722 asc_dvc->max_sdtr_index = 15;
11723 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
11724 AscSetExtraControl(iop_base,
11725 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11726 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
11727 AscSetExtraControl(iop_base,
11728 (SEC_ACTIVE_NEGATE |
11729 SEC_ENABLE_FILTER));
27c868c2
MW
11730 }
11731 }
51219358
MW
11732 if (asc_dvc->bus_type == ASC_IS_PCI) {
11733 AscSetExtraControl(iop_base,
11734 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11735 }
1da177e4 11736
51219358
MW
11737 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
11738#ifdef CONFIG_ISA
11739 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
11740 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
11741 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
11742 asc_dvc->bus_type = ASC_IS_ISAPNP;
27c868c2 11743 }
51219358
MW
11744 asc_dvc->cfg->isa_dma_channel =
11745 (uchar)AscGetIsaDmaChannel(iop_base);
27c868c2 11746 }
51219358
MW
11747#endif /* CONFIG_ISA */
11748 for (i = 0; i <= ASC_MAX_TID; i++) {
11749 asc_dvc->cur_dvc_qng[i] = 0;
11750 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
11751 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
11752 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
11753 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
27c868c2 11754 }
51219358
MW
11755 return warn_code;
11756}
1da177e4 11757
51219358
MW
11758static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11759{
11760 int retry;
27c868c2 11761
51219358
MW
11762 for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
11763 unsigned char read_back;
11764 AscSetChipEEPCmd(iop_base, cmd_reg);
11765 mdelay(1);
11766 read_back = AscGetChipEEPCmd(iop_base);
11767 if (read_back == cmd_reg)
11768 return 1;
27c868c2 11769 }
51219358
MW
11770 return 0;
11771}
1da177e4 11772
51219358
MW
11773static void __devinit AscWaitEEPRead(void)
11774{
11775 mdelay(1);
27c868c2 11776}
1da177e4 11777
51219358 11778static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
27c868c2 11779{
51219358
MW
11780 ushort read_wval;
11781 uchar cmd_reg;
27c868c2 11782
51219358
MW
11783 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11784 AscWaitEEPRead();
11785 cmd_reg = addr | ASC_EEP_CMD_READ;
11786 AscWriteEEPCmdReg(iop_base, cmd_reg);
11787 AscWaitEEPRead();
11788 read_wval = AscGetChipEEPData(iop_base);
11789 AscWaitEEPRead();
11790 return read_wval;
11791}
27c868c2 11792
51219358
MW
11793static ushort __devinit
11794AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11795{
11796 ushort wval;
11797 ushort sum;
11798 ushort *wbuf;
11799 int cfg_beg;
11800 int cfg_end;
11801 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11802 int s_addr;
27c868c2 11803
51219358
MW
11804 wbuf = (ushort *)cfg_buf;
11805 sum = 0;
11806 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11807 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11808 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11809 sum += *wbuf;
11810 }
11811 if (bus_type & ASC_IS_VL) {
11812 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11813 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11814 } else {
11815 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11816 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11817 }
11818 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11819 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11820 if (s_addr <= uchar_end_in_config) {
11821 /*
11822 * Swap all char fields - must unswap bytes already swapped
11823 * by AscReadEEPWord().
11824 */
11825 *wbuf = le16_to_cpu(wval);
11826 } else {
11827 /* Don't swap word field at the end - cntl field. */
11828 *wbuf = wval;
11829 }
11830 sum += wval; /* Checksum treats all EEPROM data as words. */
11831 }
27c868c2 11832 /*
51219358
MW
11833 * Read the checksum word which will be compared against 'sum'
11834 * by the caller. Word field already swapped.
27c868c2 11835 */
51219358
MW
11836 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11837 return sum;
11838}
1da177e4 11839
51219358
MW
11840static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11841{
11842 PortAddr iop_base;
11843 ushort q_addr;
11844 ushort saved_word;
11845 int sta;
1da177e4 11846
51219358
MW
11847 iop_base = asc_dvc->iop_base;
11848 sta = 0;
11849 q_addr = ASC_QNO_TO_QADDR(241);
11850 saved_word = AscReadLramWord(iop_base, q_addr);
11851 AscSetChipLramAddr(iop_base, q_addr);
11852 AscSetChipLramData(iop_base, 0x55AA);
11853 mdelay(10);
11854 AscSetChipLramAddr(iop_base, q_addr);
11855 if (AscGetChipLramData(iop_base) == 0x55AA) {
11856 sta = 1;
11857 AscWriteLramWord(iop_base, q_addr, saved_word);
11858 }
11859 return (sta);
11860}
1da177e4 11861
51219358
MW
11862static void __devinit AscWaitEEPWrite(void)
11863{
11864 mdelay(20);
11865 return;
11866}
1da177e4 11867
51219358
MW
11868static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11869{
11870 ushort read_back;
11871 int retry;
1da177e4 11872
51219358
MW
11873 retry = 0;
11874 while (TRUE) {
11875 AscSetChipEEPData(iop_base, data_reg);
11876 mdelay(1);
11877 read_back = AscGetChipEEPData(iop_base);
11878 if (read_back == data_reg) {
11879 return (1);
11880 }
11881 if (retry++ > ASC_EEP_MAX_RETRY) {
11882 return (0);
11883 }
27c868c2 11884 }
51219358 11885}
27c868c2 11886
51219358
MW
11887static ushort __devinit
11888AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11889{
11890 ushort read_wval;
11891
11892 read_wval = AscReadEEPWord(iop_base, addr);
11893 if (read_wval != word_val) {
11894 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11895 AscWaitEEPRead();
11896 AscWriteEEPDataReg(iop_base, word_val);
11897 AscWaitEEPRead();
11898 AscWriteEEPCmdReg(iop_base,
11899 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11900 AscWaitEEPWrite();
11901 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11902 AscWaitEEPRead();
11903 return (AscReadEEPWord(iop_base, addr));
11904 }
11905 return (read_wval);
11906}
11907
11908static int __devinit
11909AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11910{
11911 int n_error;
11912 ushort *wbuf;
11913 ushort word;
11914 ushort sum;
11915 int s_addr;
11916 int cfg_beg;
11917 int cfg_end;
11918 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11919
11920 wbuf = (ushort *)cfg_buf;
11921 n_error = 0;
11922 sum = 0;
11923 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11924 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11925 sum += *wbuf;
11926 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11927 n_error++;
27c868c2 11928 }
51219358
MW
11929 }
11930 if (bus_type & ASC_IS_VL) {
11931 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11932 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11933 } else {
11934 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11935 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11936 }
11937 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11938 if (s_addr <= uchar_end_in_config) {
11939 /*
11940 * This is a char field. Swap char fields before they are
11941 * swapped again by AscWriteEEPWord().
11942 */
11943 word = cpu_to_le16(*wbuf);
11944 if (word !=
11945 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11946 n_error++;
11947 }
11948 } else {
11949 /* Don't swap word field at the end - cntl field. */
11950 if (*wbuf !=
11951 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11952 n_error++;
11953 }
27c868c2 11954 }
51219358
MW
11955 sum += *wbuf; /* Checksum calculated from word values. */
11956 }
11957 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11958 *wbuf = sum;
11959 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11960 n_error++;
27c868c2 11961 }
1da177e4 11962
51219358
MW
11963 /* Read EEPROM back again. */
11964 wbuf = (ushort *)cfg_buf;
27c868c2 11965 /*
51219358 11966 * Read two config words; Byte-swapping done by AscReadEEPWord().
27c868c2 11967 */
51219358
MW
11968 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11969 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11970 n_error++;
27c868c2
MW
11971 }
11972 }
51219358
MW
11973 if (bus_type & ASC_IS_VL) {
11974 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11975 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11976 } else {
11977 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11978 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11979 }
11980 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11981 if (s_addr <= uchar_end_in_config) {
11982 /*
11983 * Swap all char fields. Must unswap bytes already swapped
11984 * by AscReadEEPWord().
11985 */
11986 word =
11987 le16_to_cpu(AscReadEEPWord
11988 (iop_base, (uchar)s_addr));
27c868c2 11989 } else {
51219358
MW
11990 /* Don't swap word field at the end - cntl field. */
11991 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11992 }
11993 if (*wbuf != word) {
11994 n_error++;
27c868c2
MW
11995 }
11996 }
51219358
MW
11997 /* Read checksum; Byte swapping not needed. */
11998 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11999 n_error++;
27c868c2 12000 }
51219358
MW
12001 return n_error;
12002}
1da177e4 12003
51219358
MW
12004static int __devinit
12005AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
12006{
12007 int retry;
12008 int n_error;
27c868c2 12009
51219358
MW
12010 retry = 0;
12011 while (TRUE) {
12012 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
12013 bus_type)) == 0) {
12014 break;
12015 }
12016 if (++retry > ASC_EEP_MAX_RETRY) {
12017 break;
12018 }
12019 }
12020 return n_error;
12021}
27c868c2 12022
51219358
MW
12023static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
12024{
12025 ASCEEP_CONFIG eep_config_buf;
12026 ASCEEP_CONFIG *eep_config;
12027 PortAddr iop_base;
12028 ushort chksum;
12029 ushort warn_code;
12030 ushort cfg_msw, cfg_lsw;
12031 int i;
12032 int write_eep = 0;
27c868c2 12033
51219358
MW
12034 iop_base = asc_dvc->iop_base;
12035 warn_code = 0;
12036 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12037 AscStopQueueExe(iop_base);
12038 if ((AscStopChip(iop_base) == FALSE) ||
12039 (AscGetChipScsiCtrl(iop_base) != 0)) {
12040 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12041 AscResetChipAndScsiBus(asc_dvc);
12042 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
12043 }
12044 if (AscIsChipHalted(iop_base) == FALSE) {
12045 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12046 return (warn_code);
12047 }
12048 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12049 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12050 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12051 return (warn_code);
12052 }
12053 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
12054 cfg_msw = AscGetChipCfgMsw(iop_base);
12055 cfg_lsw = AscGetChipCfgLsw(iop_base);
12056 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12057 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12058 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12059 AscSetChipCfgMsw(iop_base, cfg_msw);
12060 }
12061 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12062 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12063 if (chksum == 0) {
12064 chksum = 0xaa55;
12065 }
12066 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12067 warn_code |= ASC_WARN_AUTO_CONFIG;
12068 if (asc_dvc->cfg->chip_version == 3) {
12069 if (eep_config->cfg_lsw != cfg_lsw) {
12070 warn_code |= ASC_WARN_EEPROM_RECOVER;
12071 eep_config->cfg_lsw =
12072 AscGetChipCfgLsw(iop_base);
12073 }
12074 if (eep_config->cfg_msw != cfg_msw) {
12075 warn_code |= ASC_WARN_EEPROM_RECOVER;
12076 eep_config->cfg_msw =
12077 AscGetChipCfgMsw(iop_base);
12078 }
12079 }
12080 }
12081 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12082 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12083 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12084 eep_config->chksum);
12085 if (chksum != eep_config->chksum) {
12086 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12087 ASC_CHIP_VER_PCI_ULTRA_3050) {
12088 ASC_DBG(1,
12089 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12090 eep_config->init_sdtr = 0xFF;
12091 eep_config->disc_enable = 0xFF;
12092 eep_config->start_motor = 0xFF;
12093 eep_config->use_cmd_qng = 0;
12094 eep_config->max_total_qng = 0xF0;
12095 eep_config->max_tag_qng = 0x20;
12096 eep_config->cntl = 0xBFFF;
12097 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12098 eep_config->no_scam = 0;
12099 eep_config->adapter_info[0] = 0;
12100 eep_config->adapter_info[1] = 0;
12101 eep_config->adapter_info[2] = 0;
12102 eep_config->adapter_info[3] = 0;
12103 eep_config->adapter_info[4] = 0;
12104 /* Indicate EEPROM-less board. */
12105 eep_config->adapter_info[5] = 0xBB;
27c868c2 12106 } else {
51219358
MW
12107 ASC_PRINT
12108 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12109 write_eep = 1;
12110 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12111 }
12112 }
12113 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12114 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12115 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12116 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12117 asc_dvc->start_motor = eep_config->start_motor;
12118 asc_dvc->dvc_cntl = eep_config->cntl;
12119 asc_dvc->no_scam = eep_config->no_scam;
12120 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12121 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12122 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12123 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12124 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12125 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12126 if (!AscTestExternalLram(asc_dvc)) {
12127 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
12128 ASC_IS_PCI_ULTRA)) {
12129 eep_config->max_total_qng =
12130 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12131 eep_config->max_tag_qng =
12132 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12133 } else {
12134 eep_config->cfg_msw |= 0x0800;
12135 cfg_msw |= 0x0800;
12136 AscSetChipCfgMsw(iop_base, cfg_msw);
12137 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12138 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
27c868c2 12139 }
51219358
MW
12140 } else {
12141 }
12142 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12143 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12144 }
12145 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12146 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12147 }
12148 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12149 eep_config->max_tag_qng = eep_config->max_total_qng;
12150 }
12151 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12152 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12153 }
12154 asc_dvc->max_total_qng = eep_config->max_total_qng;
12155 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12156 eep_config->use_cmd_qng) {
12157 eep_config->disc_enable = eep_config->use_cmd_qng;
12158 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12159 }
12160 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12161 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12162 }
12163 ASC_EEP_SET_CHIP_ID(eep_config,
12164 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12165 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12166 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12167 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12168 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
27c868c2 12169 }
1da177e4 12170
51219358
MW
12171 for (i = 0; i <= ASC_MAX_TID; i++) {
12172 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12173 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12174 asc_dvc->cfg->sdtr_period_offset[i] =
12175 (uchar)(ASC_DEF_SDTR_OFFSET |
12176 (asc_dvc->host_init_sdtr_index << 4));
12177 }
12178 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12179 if (write_eep) {
12180 if ((i = AscSetEEPConfig(iop_base, eep_config,
12181 asc_dvc->bus_type)) != 0) {
12182 ASC_PRINT1
12183 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
12184 i);
27c868c2 12185 } else {
51219358
MW
12186 ASC_PRINT
12187 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
27c868c2
MW
12188 }
12189 }
51219358 12190 return (warn_code);
1da177e4
LT
12191}
12192
51219358 12193static int __devinit AscInitGetConfig(asc_board_t *boardp)
1da177e4 12194{
51219358
MW
12195 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
12196 unsigned short warn_code = 0;
27c868c2 12197
51219358
MW
12198 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
12199 if (asc_dvc->err_code != 0)
12200 return asc_dvc->err_code;
27c868c2 12201
51219358
MW
12202 if (AscFindSignature(asc_dvc->iop_base)) {
12203 warn_code |= AscInitAscDvcVar(asc_dvc);
12204 warn_code |= AscInitFromEEP(asc_dvc);
12205 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
12206 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
12207 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
12208 } else {
12209 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12210 }
27c868c2 12211
51219358
MW
12212 switch (warn_code) {
12213 case 0: /* No error */
12214 break;
12215 case ASC_WARN_IO_PORT_ROTATE:
12216 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
12217 "modified\n", boardp->id);
12218 break;
12219 case ASC_WARN_AUTO_CONFIG:
12220 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
12221 "switch enabled\n", boardp->id);
12222 break;
12223 case ASC_WARN_EEPROM_CHKSUM:
12224 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
12225 "error\n", boardp->id);
12226 break;
12227 case ASC_WARN_IRQ_MODIFIED:
12228 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
12229 boardp->id);
12230 break;
12231 case ASC_WARN_CMD_QNG_CONFLICT:
12232 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
12233 "w/o disconnects\n", boardp->id);
12234 break;
12235 default:
12236 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
12237 "0x%x\n", boardp->id, warn_code);
12238 break;
12239 }
1da177e4 12240
51219358
MW
12241 if (asc_dvc->err_code != 0) {
12242 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
12243 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12244 asc_dvc->err_code);
12245 }
27c868c2 12246
51219358
MW
12247 return asc_dvc->err_code;
12248}
1da177e4 12249
51219358
MW
12250static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
12251{
12252 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
12253 PortAddr iop_base = asc_dvc->iop_base;
12254 unsigned short cfg_msw;
12255 unsigned short warn_code = 0;
1da177e4 12256
51219358
MW
12257 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12258 if (asc_dvc->err_code != 0)
12259 return asc_dvc->err_code;
12260 if (!AscFindSignature(asc_dvc->iop_base)) {
12261 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12262 return asc_dvc->err_code;
27c868c2 12263 }
1da177e4 12264
51219358
MW
12265 cfg_msw = AscGetChipCfgMsw(iop_base);
12266 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12267 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12268 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12269 AscSetChipCfgMsw(iop_base, cfg_msw);
12270 }
12271 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12272 asc_dvc->cfg->cmd_qng_enabled) {
12273 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12274 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12275 }
12276 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12277 warn_code |= ASC_WARN_AUTO_CONFIG;
12278 }
12279 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12280 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12281 != asc_dvc->irq_no) {
12282 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
27c868c2 12283 }
27c868c2 12284 }
51219358
MW
12285#ifdef CONFIG_PCI
12286 if (asc_dvc->bus_type & ASC_IS_PCI) {
12287 cfg_msw &= 0xFFC0;
12288 AscSetChipCfgMsw(iop_base, cfg_msw);
12289 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
27c868c2 12290 } else {
51219358
MW
12291 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
12292 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
12293 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12294 asc_dvc->bug_fix_cntl |=
12295 ASC_BUG_FIX_ASYN_USE_SYN;
12296 }
27c868c2 12297 }
51219358
MW
12298 } else
12299#endif /* CONFIG_PCI */
12300 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12301 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12302 == ASC_CHIP_VER_ASYN_BUG) {
12303 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
27c868c2
MW
12304 }
12305 }
51219358
MW
12306 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12307 asc_dvc->cfg->chip_scsi_id) {
12308 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12309 }
12310#ifdef CONFIG_ISA
12311 if (asc_dvc->bus_type & ASC_IS_ISA) {
12312 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12313 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12314 }
12315#endif /* CONFIG_ISA */
1da177e4 12316
51219358
MW
12317 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12318
12319 switch (warn_code) {
12320 case 0: /* No error. */
12321 break;
12322 case ASC_WARN_IO_PORT_ROTATE:
12323 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
12324 "modified\n", boardp->id);
12325 break;
12326 case ASC_WARN_AUTO_CONFIG:
12327 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
12328 "switch enabled\n", boardp->id);
12329 break;
12330 case ASC_WARN_EEPROM_CHKSUM:
12331 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
12332 "error\n", boardp->id);
12333 break;
12334 case ASC_WARN_IRQ_MODIFIED:
12335 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
12336 boardp->id);
12337 break;
12338 case ASC_WARN_CMD_QNG_CONFLICT:
12339 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
12340 "disconnects\n",
12341 boardp->id);
12342 break;
12343 default:
12344 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
12345 "0x%x\n", boardp->id, warn_code);
12346 break;
27c868c2 12347 }
1da177e4 12348
51219358
MW
12349 if (asc_dvc->err_code != 0) {
12350 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
12351 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12352 asc_dvc->err_code);
12353 }
27c868c2 12354
51219358
MW
12355 return asc_dvc->err_code;
12356}
27c868c2 12357
51219358
MW
12358/*
12359 * EEPROM Configuration.
12360 *
12361 * All drivers should use this structure to set the default EEPROM
12362 * configuration. The BIOS now uses this structure when it is built.
12363 * Additional structure information can be found in a_condor.h where
12364 * the structure is defined.
12365 *
12366 * The *_Field_IsChar structs are needed to correct for endianness.
12367 * These values are read from the board 16 bits at a time directly
12368 * into the structs. Because some fields are char, the values will be
12369 * in the wrong order. The *_Field_IsChar tells when to flip the
12370 * bytes. Data read and written to PCI memory is automatically swapped
12371 * on big-endian platforms so char fields read as words are actually being
12372 * unswapped on big-endian platforms.
12373 */
12374static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
12375 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
12376 0x0000, /* cfg_msw */
12377 0xFFFF, /* disc_enable */
12378 0xFFFF, /* wdtr_able */
12379 0xFFFF, /* sdtr_able */
12380 0xFFFF, /* start_motor */
12381 0xFFFF, /* tagqng_able */
12382 0xFFFF, /* bios_scan */
12383 0, /* scam_tolerant */
12384 7, /* adapter_scsi_id */
12385 0, /* bios_boot_delay */
12386 3, /* scsi_reset_delay */
12387 0, /* bios_id_lun */
12388 0, /* termination */
12389 0, /* reserved1 */
12390 0xFFE7, /* bios_ctrl */
12391 0xFFFF, /* ultra_able */
12392 0, /* reserved2 */
12393 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
12394 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12395 0, /* dvc_cntl */
12396 0, /* bug_fix */
12397 0, /* serial_number_word1 */
12398 0, /* serial_number_word2 */
12399 0, /* serial_number_word3 */
12400 0, /* check_sum */
12401 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12402 , /* oem_name[16] */
12403 0, /* dvc_err_code */
12404 0, /* adv_err_code */
12405 0, /* adv_err_addr */
12406 0, /* saved_dvc_err_code */
12407 0, /* saved_adv_err_code */
12408 0, /* saved_adv_err_addr */
12409 0 /* num_of_err */
12410};
27c868c2 12411
51219358
MW
12412static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
12413 0, /* cfg_lsw */
12414 0, /* cfg_msw */
12415 0, /* -disc_enable */
12416 0, /* wdtr_able */
12417 0, /* sdtr_able */
12418 0, /* start_motor */
12419 0, /* tagqng_able */
12420 0, /* bios_scan */
12421 0, /* scam_tolerant */
12422 1, /* adapter_scsi_id */
12423 1, /* bios_boot_delay */
12424 1, /* scsi_reset_delay */
12425 1, /* bios_id_lun */
12426 1, /* termination */
12427 1, /* reserved1 */
12428 0, /* bios_ctrl */
12429 0, /* ultra_able */
12430 0, /* reserved2 */
12431 1, /* max_host_qng */
12432 1, /* max_dvc_qng */
12433 0, /* dvc_cntl */
12434 0, /* bug_fix */
12435 0, /* serial_number_word1 */
12436 0, /* serial_number_word2 */
12437 0, /* serial_number_word3 */
12438 0, /* check_sum */
12439 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12440 , /* oem_name[16] */
12441 0, /* dvc_err_code */
12442 0, /* adv_err_code */
12443 0, /* adv_err_addr */
12444 0, /* saved_dvc_err_code */
12445 0, /* saved_adv_err_code */
12446 0, /* saved_adv_err_addr */
12447 0 /* num_of_err */
12448};
1da177e4 12449
51219358
MW
12450static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
12451 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12452 0x0000, /* 01 cfg_msw */
12453 0xFFFF, /* 02 disc_enable */
12454 0xFFFF, /* 03 wdtr_able */
12455 0x4444, /* 04 sdtr_speed1 */
12456 0xFFFF, /* 05 start_motor */
12457 0xFFFF, /* 06 tagqng_able */
12458 0xFFFF, /* 07 bios_scan */
12459 0, /* 08 scam_tolerant */
12460 7, /* 09 adapter_scsi_id */
12461 0, /* bios_boot_delay */
12462 3, /* 10 scsi_reset_delay */
12463 0, /* bios_id_lun */
12464 0, /* 11 termination_se */
12465 0, /* termination_lvd */
12466 0xFFE7, /* 12 bios_ctrl */
12467 0x4444, /* 13 sdtr_speed2 */
12468 0x4444, /* 14 sdtr_speed3 */
12469 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12470 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12471 0, /* 16 dvc_cntl */
12472 0x4444, /* 17 sdtr_speed4 */
12473 0, /* 18 serial_number_word1 */
12474 0, /* 19 serial_number_word2 */
12475 0, /* 20 serial_number_word3 */
12476 0, /* 21 check_sum */
12477 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12478 , /* 22-29 oem_name[16] */
12479 0, /* 30 dvc_err_code */
12480 0, /* 31 adv_err_code */
12481 0, /* 32 adv_err_addr */
12482 0, /* 33 saved_dvc_err_code */
12483 0, /* 34 saved_adv_err_code */
12484 0, /* 35 saved_adv_err_addr */
12485 0, /* 36 reserved */
12486 0, /* 37 reserved */
12487 0, /* 38 reserved */
12488 0, /* 39 reserved */
12489 0, /* 40 reserved */
12490 0, /* 41 reserved */
12491 0, /* 42 reserved */
12492 0, /* 43 reserved */
12493 0, /* 44 reserved */
12494 0, /* 45 reserved */
12495 0, /* 46 reserved */
12496 0, /* 47 reserved */
12497 0, /* 48 reserved */
12498 0, /* 49 reserved */
12499 0, /* 50 reserved */
12500 0, /* 51 reserved */
12501 0, /* 52 reserved */
12502 0, /* 53 reserved */
12503 0, /* 54 reserved */
12504 0, /* 55 reserved */
12505 0, /* 56 cisptr_lsw */
12506 0, /* 57 cisprt_msw */
12507 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12508 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
12509 0, /* 60 reserved */
12510 0, /* 61 reserved */
12511 0, /* 62 reserved */
12512 0 /* 63 reserved */
12513};
27c868c2 12514
51219358
MW
12515static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12516 0, /* 00 cfg_lsw */
12517 0, /* 01 cfg_msw */
12518 0, /* 02 disc_enable */
12519 0, /* 03 wdtr_able */
12520 0, /* 04 sdtr_speed1 */
12521 0, /* 05 start_motor */
12522 0, /* 06 tagqng_able */
12523 0, /* 07 bios_scan */
12524 0, /* 08 scam_tolerant */
12525 1, /* 09 adapter_scsi_id */
12526 1, /* bios_boot_delay */
12527 1, /* 10 scsi_reset_delay */
12528 1, /* bios_id_lun */
12529 1, /* 11 termination_se */
12530 1, /* termination_lvd */
12531 0, /* 12 bios_ctrl */
12532 0, /* 13 sdtr_speed2 */
12533 0, /* 14 sdtr_speed3 */
12534 1, /* 15 max_host_qng */
12535 1, /* max_dvc_qng */
12536 0, /* 16 dvc_cntl */
12537 0, /* 17 sdtr_speed4 */
12538 0, /* 18 serial_number_word1 */
12539 0, /* 19 serial_number_word2 */
12540 0, /* 20 serial_number_word3 */
12541 0, /* 21 check_sum */
12542 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12543 , /* 22-29 oem_name[16] */
12544 0, /* 30 dvc_err_code */
12545 0, /* 31 adv_err_code */
12546 0, /* 32 adv_err_addr */
12547 0, /* 33 saved_dvc_err_code */
12548 0, /* 34 saved_adv_err_code */
12549 0, /* 35 saved_adv_err_addr */
12550 0, /* 36 reserved */
12551 0, /* 37 reserved */
12552 0, /* 38 reserved */
12553 0, /* 39 reserved */
12554 0, /* 40 reserved */
12555 0, /* 41 reserved */
12556 0, /* 42 reserved */
12557 0, /* 43 reserved */
12558 0, /* 44 reserved */
12559 0, /* 45 reserved */
12560 0, /* 46 reserved */
12561 0, /* 47 reserved */
12562 0, /* 48 reserved */
12563 0, /* 49 reserved */
12564 0, /* 50 reserved */
12565 0, /* 51 reserved */
12566 0, /* 52 reserved */
12567 0, /* 53 reserved */
12568 0, /* 54 reserved */
12569 0, /* 55 reserved */
12570 0, /* 56 cisptr_lsw */
12571 0, /* 57 cisprt_msw */
12572 0, /* 58 subsysvid */
12573 0, /* 59 subsysid */
12574 0, /* 60 reserved */
12575 0, /* 61 reserved */
12576 0, /* 62 reserved */
12577 0 /* 63 reserved */
12578};
27c868c2 12579
51219358
MW
12580static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12581 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12582 0x0000, /* 01 cfg_msw */
12583 0xFFFF, /* 02 disc_enable */
12584 0xFFFF, /* 03 wdtr_able */
12585 0x5555, /* 04 sdtr_speed1 */
12586 0xFFFF, /* 05 start_motor */
12587 0xFFFF, /* 06 tagqng_able */
12588 0xFFFF, /* 07 bios_scan */
12589 0, /* 08 scam_tolerant */
12590 7, /* 09 adapter_scsi_id */
12591 0, /* bios_boot_delay */
12592 3, /* 10 scsi_reset_delay */
12593 0, /* bios_id_lun */
12594 0, /* 11 termination_se */
12595 0, /* termination_lvd */
12596 0xFFE7, /* 12 bios_ctrl */
12597 0x5555, /* 13 sdtr_speed2 */
12598 0x5555, /* 14 sdtr_speed3 */
12599 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
12600 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
12601 0, /* 16 dvc_cntl */
12602 0x5555, /* 17 sdtr_speed4 */
12603 0, /* 18 serial_number_word1 */
12604 0, /* 19 serial_number_word2 */
12605 0, /* 20 serial_number_word3 */
12606 0, /* 21 check_sum */
12607 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12608 , /* 22-29 oem_name[16] */
12609 0, /* 30 dvc_err_code */
12610 0, /* 31 adv_err_code */
12611 0, /* 32 adv_err_addr */
12612 0, /* 33 saved_dvc_err_code */
12613 0, /* 34 saved_adv_err_code */
12614 0, /* 35 saved_adv_err_addr */
12615 0, /* 36 reserved */
12616 0, /* 37 reserved */
12617 0, /* 38 reserved */
12618 0, /* 39 reserved */
12619 0, /* 40 reserved */
12620 0, /* 41 reserved */
12621 0, /* 42 reserved */
12622 0, /* 43 reserved */
12623 0, /* 44 reserved */
12624 0, /* 45 reserved */
12625 0, /* 46 reserved */
12626 0, /* 47 reserved */
12627 0, /* 48 reserved */
12628 0, /* 49 reserved */
12629 0, /* 50 reserved */
12630 0, /* 51 reserved */
12631 0, /* 52 reserved */
12632 0, /* 53 reserved */
12633 0, /* 54 reserved */
12634 0, /* 55 reserved */
12635 0, /* 56 cisptr_lsw */
12636 0, /* 57 cisprt_msw */
12637 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
12638 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
12639 0, /* 60 reserved */
12640 0, /* 61 reserved */
12641 0, /* 62 reserved */
12642 0 /* 63 reserved */
12643};
1da177e4 12644
51219358
MW
12645static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12646 0, /* 00 cfg_lsw */
12647 0, /* 01 cfg_msw */
12648 0, /* 02 disc_enable */
12649 0, /* 03 wdtr_able */
12650 0, /* 04 sdtr_speed1 */
12651 0, /* 05 start_motor */
12652 0, /* 06 tagqng_able */
12653 0, /* 07 bios_scan */
12654 0, /* 08 scam_tolerant */
12655 1, /* 09 adapter_scsi_id */
12656 1, /* bios_boot_delay */
12657 1, /* 10 scsi_reset_delay */
12658 1, /* bios_id_lun */
12659 1, /* 11 termination_se */
12660 1, /* termination_lvd */
12661 0, /* 12 bios_ctrl */
12662 0, /* 13 sdtr_speed2 */
12663 0, /* 14 sdtr_speed3 */
12664 1, /* 15 max_host_qng */
12665 1, /* max_dvc_qng */
12666 0, /* 16 dvc_cntl */
12667 0, /* 17 sdtr_speed4 */
12668 0, /* 18 serial_number_word1 */
12669 0, /* 19 serial_number_word2 */
12670 0, /* 20 serial_number_word3 */
12671 0, /* 21 check_sum */
12672 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12673 , /* 22-29 oem_name[16] */
12674 0, /* 30 dvc_err_code */
12675 0, /* 31 adv_err_code */
12676 0, /* 32 adv_err_addr */
12677 0, /* 33 saved_dvc_err_code */
12678 0, /* 34 saved_adv_err_code */
12679 0, /* 35 saved_adv_err_addr */
12680 0, /* 36 reserved */
12681 0, /* 37 reserved */
12682 0, /* 38 reserved */
12683 0, /* 39 reserved */
12684 0, /* 40 reserved */
12685 0, /* 41 reserved */
12686 0, /* 42 reserved */
12687 0, /* 43 reserved */
12688 0, /* 44 reserved */
12689 0, /* 45 reserved */
12690 0, /* 46 reserved */
12691 0, /* 47 reserved */
12692 0, /* 48 reserved */
12693 0, /* 49 reserved */
12694 0, /* 50 reserved */
12695 0, /* 51 reserved */
12696 0, /* 52 reserved */
12697 0, /* 53 reserved */
12698 0, /* 54 reserved */
12699 0, /* 55 reserved */
12700 0, /* 56 cisptr_lsw */
12701 0, /* 57 cisprt_msw */
12702 0, /* 58 subsysvid */
12703 0, /* 59 subsysid */
12704 0, /* 60 reserved */
12705 0, /* 61 reserved */
12706 0, /* 62 reserved */
12707 0 /* 63 reserved */
12708};
1da177e4 12709
51219358 12710#ifdef CONFIG_PCI
1da177e4 12711/*
51219358 12712 * Wait for EEPROM command to complete
1da177e4 12713 */
51219358 12714static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 12715{
51219358 12716 int eep_delay_ms;
27c868c2 12717
51219358
MW
12718 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
12719 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
12720 ASC_EEP_CMD_DONE) {
12721 break;
27c868c2 12722 }
51219358 12723 mdelay(1);
27c868c2 12724 }
51219358
MW
12725 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12726 0)
12727 BUG();
1da177e4
LT
12728}
12729
12730/*
51219358 12731 * Read the EEPROM from specified location
1da177e4 12732 */
51219358
MW
12733static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12734{
12735 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12736 ASC_EEP_CMD_READ | eep_word_addr);
12737 AdvWaitEEPCmd(iop_base);
12738 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
12739}
12740
12741/*
12742 * Write the EEPROM from 'cfg_buf'.
12743 */
12744void __devinit
12745AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
1da177e4 12746{
27c868c2 12747 ushort *wbuf;
51219358 12748 ushort addr, chksum;
27c868c2
MW
12749 ushort *charfields;
12750
27c868c2 12751 wbuf = (ushort *)cfg_buf;
51219358 12752 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
27c868c2
MW
12753 chksum = 0;
12754
51219358
MW
12755 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12756 AdvWaitEEPCmd(iop_base);
12757
12758 /*
12759 * Write EEPROM from word 0 to word 20.
12760 */
12761 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12762 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12763 ushort word;
12764
27c868c2 12765 if (*charfields++) {
51219358 12766 word = cpu_to_le16(*wbuf);
27c868c2 12767 } else {
51219358 12768 word = *wbuf;
27c868c2 12769 }
51219358
MW
12770 chksum += *wbuf; /* Checksum is calculated from word values. */
12771 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12772 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12773 ASC_EEP_CMD_WRITE | addr);
12774 AdvWaitEEPCmd(iop_base);
12775 mdelay(ADV_EEP_DELAY_MS);
27c868c2 12776 }
51219358
MW
12777
12778 /*
12779 * Write EEPROM checksum at word 21.
12780 */
12781 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12782 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12783 AdvWaitEEPCmd(iop_base);
27c868c2
MW
12784 wbuf++;
12785 charfields++;
12786
51219358
MW
12787 /*
12788 * Write EEPROM OEM name at words 22 to 29.
12789 */
12790 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12791 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12792 ushort word;
12793
27c868c2 12794 if (*charfields++) {
51219358
MW
12795 word = cpu_to_le16(*wbuf);
12796 } else {
12797 word = *wbuf;
27c868c2 12798 }
51219358
MW
12799 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12800 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12801 ASC_EEP_CMD_WRITE | addr);
12802 AdvWaitEEPCmd(iop_base);
27c868c2 12803 }
51219358
MW
12804 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12805 AdvWaitEEPCmd(iop_base);
1da177e4
LT
12806}
12807
12808/*
51219358 12809 * Write the EEPROM from 'cfg_buf'.
1da177e4 12810 */
51219358
MW
12811void __devinit
12812AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 12813{
27c868c2 12814 ushort *wbuf;
27c868c2 12815 ushort *charfields;
51219358 12816 ushort addr, chksum;
27c868c2 12817
27c868c2 12818 wbuf = (ushort *)cfg_buf;
51219358 12819 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
27c868c2
MW
12820 chksum = 0;
12821
51219358
MW
12822 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12823 AdvWaitEEPCmd(iop_base);
12824
12825 /*
12826 * Write EEPROM from word 0 to word 20.
12827 */
12828 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12829 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12830 ushort word;
12831
27c868c2 12832 if (*charfields++) {
51219358 12833 word = cpu_to_le16(*wbuf);
27c868c2 12834 } else {
51219358 12835 word = *wbuf;
27c868c2 12836 }
51219358
MW
12837 chksum += *wbuf; /* Checksum is calculated from word values. */
12838 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12839 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12840 ASC_EEP_CMD_WRITE | addr);
12841 AdvWaitEEPCmd(iop_base);
12842 mdelay(ADV_EEP_DELAY_MS);
27c868c2 12843 }
51219358
MW
12844
12845 /*
12846 * Write EEPROM checksum at word 21.
12847 */
12848 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12849 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12850 AdvWaitEEPCmd(iop_base);
27c868c2
MW
12851 wbuf++;
12852 charfields++;
12853
51219358
MW
12854 /*
12855 * Write EEPROM OEM name at words 22 to 29.
12856 */
12857 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12858 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12859 ushort word;
12860
27c868c2 12861 if (*charfields++) {
51219358
MW
12862 word = cpu_to_le16(*wbuf);
12863 } else {
12864 word = *wbuf;
27c868c2 12865 }
51219358
MW
12866 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12867 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12868 ASC_EEP_CMD_WRITE | addr);
12869 AdvWaitEEPCmd(iop_base);
27c868c2 12870 }
51219358 12871 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
27c868c2 12872 AdvWaitEEPCmd(iop_base);
1da177e4
LT
12873}
12874
12875/*
12876 * Write the EEPROM from 'cfg_buf'.
12877 */
78e77d8b 12878void __devinit
51219358 12879AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 12880{
27c868c2 12881 ushort *wbuf;
27c868c2 12882 ushort *charfields;
51219358 12883 ushort addr, chksum;
27c868c2
MW
12884
12885 wbuf = (ushort *)cfg_buf;
51219358 12886 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
27c868c2
MW
12887 chksum = 0;
12888
12889 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12890 AdvWaitEEPCmd(iop_base);
12891
12892 /*
12893 * Write EEPROM from word 0 to word 20.
12894 */
12895 for (addr = ADV_EEP_DVC_CFG_BEGIN;
12896 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12897 ushort word;
12898
12899 if (*charfields++) {
12900 word = cpu_to_le16(*wbuf);
12901 } else {
12902 word = *wbuf;
12903 }
12904 chksum += *wbuf; /* Checksum is calculated from word values. */
12905 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12906 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12907 ASC_EEP_CMD_WRITE | addr);
12908 AdvWaitEEPCmd(iop_base);
b009bef6 12909 mdelay(ADV_EEP_DELAY_MS);
27c868c2 12910 }
1da177e4 12911
27c868c2
MW
12912 /*
12913 * Write EEPROM checksum at word 21.
12914 */
12915 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12916 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12917 AdvWaitEEPCmd(iop_base);
12918 wbuf++;
12919 charfields++;
12920
12921 /*
12922 * Write EEPROM OEM name at words 22 to 29.
12923 */
12924 for (addr = ADV_EEP_DVC_CTL_BEGIN;
12925 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12926 ushort word;
12927
12928 if (*charfields++) {
12929 word = cpu_to_le16(*wbuf);
12930 } else {
12931 word = *wbuf;
12932 }
12933 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12934 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12935 ASC_EEP_CMD_WRITE | addr);
12936 AdvWaitEEPCmd(iop_base);
12937 }
12938 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12939 AdvWaitEEPCmd(iop_base);
1da177e4
LT
12940}
12941
12942/*
51219358
MW
12943 * Read EEPROM configuration into the specified buffer.
12944 *
12945 * Return a checksum based on the EEPROM configuration read.
1da177e4 12946 */
51219358
MW
12947static ushort __devinit
12948AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
1da177e4 12949{
51219358 12950 ushort wval, chksum;
27c868c2 12951 ushort *wbuf;
51219358 12952 int eep_addr;
27c868c2 12953 ushort *charfields;
27c868c2 12954
51219358 12955 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
27c868c2 12956 wbuf = (ushort *)cfg_buf;
27c868c2
MW
12957 chksum = 0;
12958
51219358
MW
12959 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12960 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12961 wval = AdvReadEEPWord(iop_base, eep_addr);
12962 chksum += wval; /* Checksum is calculated from word values. */
12963 if (*charfields++) {
12964 *wbuf = le16_to_cpu(wval);
12965 } else {
12966 *wbuf = wval;
12967 }
12968 }
12969 /* Read checksum word. */
12970 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12971 wbuf++;
12972 charfields++;
27c868c2 12973
51219358
MW
12974 /* Read rest of EEPROM not covered by the checksum. */
12975 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12976 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12977 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12978 if (*charfields++) {
12979 *wbuf = le16_to_cpu(*wbuf);
12980 }
12981 }
12982 return chksum;
12983}
12984
12985/*
12986 * Read EEPROM configuration into the specified buffer.
12987 *
12988 * Return a checksum based on the EEPROM configuration read.
12989 */
12990static ushort __devinit
12991AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12992{
12993 ushort wval, chksum;
12994 ushort *wbuf;
12995 int eep_addr;
12996 ushort *charfields;
27c868c2 12997
51219358
MW
12998 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12999 wbuf = (ushort *)cfg_buf;
13000 chksum = 0;
13001
13002 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13003 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13004 wval = AdvReadEEPWord(iop_base, eep_addr);
13005 chksum += wval; /* Checksum is calculated from word values. */
27c868c2 13006 if (*charfields++) {
51219358 13007 *wbuf = le16_to_cpu(wval);
27c868c2 13008 } else {
51219358 13009 *wbuf = wval;
27c868c2 13010 }
27c868c2 13011 }
51219358
MW
13012 /* Read checksum word. */
13013 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
27c868c2
MW
13014 wbuf++;
13015 charfields++;
13016
51219358
MW
13017 /* Read rest of EEPROM not covered by the checksum. */
13018 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13019 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13020 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
27c868c2 13021 if (*charfields++) {
51219358 13022 *wbuf = le16_to_cpu(*wbuf);
27c868c2 13023 }
27c868c2 13024 }
51219358 13025 return chksum;
1da177e4
LT
13026}
13027
13028/*
51219358
MW
13029 * Read EEPROM configuration into the specified buffer.
13030 *
13031 * Return a checksum based on the EEPROM configuration read.
1da177e4 13032 */
51219358
MW
13033static ushort __devinit
13034AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 13035{
51219358 13036 ushort wval, chksum;
27c868c2 13037 ushort *wbuf;
51219358 13038 int eep_addr;
27c868c2 13039 ushort *charfields;
27c868c2 13040
27c868c2 13041 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
51219358 13042 wbuf = (ushort *)cfg_buf;
27c868c2
MW
13043 chksum = 0;
13044
51219358
MW
13045 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13046 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13047 wval = AdvReadEEPWord(iop_base, eep_addr);
13048 chksum += wval; /* Checksum is calculated from word values. */
27c868c2 13049 if (*charfields++) {
51219358 13050 *wbuf = le16_to_cpu(wval);
27c868c2 13051 } else {
51219358 13052 *wbuf = wval;
27c868c2 13053 }
27c868c2 13054 }
51219358
MW
13055 /* Read checksum word. */
13056 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
27c868c2
MW
13057 wbuf++;
13058 charfields++;
13059
51219358
MW
13060 /* Read rest of EEPROM not covered by the checksum. */
13061 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13062 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13063 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
27c868c2 13064 if (*charfields++) {
51219358 13065 *wbuf = le16_to_cpu(*wbuf);
27c868c2 13066 }
27c868c2 13067 }
51219358 13068 return chksum;
1da177e4
LT
13069}
13070
1da177e4 13071/*
51219358
MW
13072 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
13073 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
13074 * all of this is done.
1da177e4 13075 *
51219358 13076 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4 13077 *
51219358
MW
13078 * For a non-fatal error return a warning code. If there are no warnings
13079 * then 0 is returned.
1da177e4 13080 *
51219358 13081 * Note: Chip is stopped on entry.
1da177e4 13082 */
51219358 13083static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13084{
27c868c2 13085 AdvPortAddr iop_base;
51219358
MW
13086 ushort warn_code;
13087 ADVEEP_3550_CONFIG eep_config;
1da177e4 13088
27c868c2 13089 iop_base = asc_dvc->iop_base;
1da177e4 13090
51219358 13091 warn_code = 0;
27c868c2
MW
13092
13093 /*
51219358
MW
13094 * Read the board's EEPROM configuration.
13095 *
13096 * Set default values if a bad checksum is found.
27c868c2 13097 */
51219358
MW
13098 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
13099 warn_code |= ASC_WARN_EEPROM_CHKSUM;
27c868c2 13100
51219358
MW
13101 /*
13102 * Set EEPROM default values.
13103 */
13104 memcpy(&eep_config, &Default_3550_EEPROM_Config,
13105 sizeof(ADVEEP_3550_CONFIG));
27c868c2 13106
51219358
MW
13107 /*
13108 * Assume the 6 byte board serial number that was read from
13109 * EEPROM is correct even if the EEPROM checksum failed.
13110 */
13111 eep_config.serial_number_word3 =
13112 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
27c868c2 13113
51219358
MW
13114 eep_config.serial_number_word2 =
13115 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 13116
51219358
MW
13117 eep_config.serial_number_word1 =
13118 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
27c868c2 13119
51219358
MW
13120 AdvSet3550EEPConfig(iop_base, &eep_config);
13121 }
13122 /*
13123 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13124 * EEPROM configuration that was read.
13125 *
13126 * This is the mapping of EEPROM fields to Adv Library fields.
13127 */
13128 asc_dvc->wdtr_able = eep_config.wdtr_able;
13129 asc_dvc->sdtr_able = eep_config.sdtr_able;
13130 asc_dvc->ultra_able = eep_config.ultra_able;
13131 asc_dvc->tagqng_able = eep_config.tagqng_able;
13132 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13133 asc_dvc->max_host_qng = eep_config.max_host_qng;
13134 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13135 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13136 asc_dvc->start_motor = eep_config.start_motor;
13137 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13138 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13139 asc_dvc->no_scam = eep_config.scam_tolerant;
13140 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13141 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13142 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
27c868c2 13143
27c868c2 13144 /*
51219358
MW
13145 * Set the host maximum queuing (max. 253, min. 16) and the per device
13146 * maximum queuing (max. 63, min. 4).
27c868c2 13147 */
51219358
MW
13148 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13149 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13150 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13151 /* If the value is zero, assume it is uninitialized. */
13152 if (eep_config.max_host_qng == 0) {
13153 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13154 } else {
13155 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13156 }
13157 }
13158
13159 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13160 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13161 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13162 /* If the value is zero, assume it is uninitialized. */
13163 if (eep_config.max_dvc_qng == 0) {
13164 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13165 } else {
13166 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13167 }
13168 }
27c868c2
MW
13169
13170 /*
51219358
MW
13171 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13172 * set 'max_dvc_qng' to 'max_host_qng'.
27c868c2 13173 */
51219358
MW
13174 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13175 eep_config.max_dvc_qng = eep_config.max_host_qng;
13176 }
27c868c2
MW
13177
13178 /*
51219358
MW
13179 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13180 * values based on possibly adjusted EEPROM values.
27c868c2 13181 */
51219358
MW
13182 asc_dvc->max_host_qng = eep_config.max_host_qng;
13183 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
27c868c2
MW
13184
13185 /*
51219358
MW
13186 * If the EEPROM 'termination' field is set to automatic (0), then set
13187 * the ADV_DVC_CFG 'termination' field to automatic also.
13188 *
13189 * If the termination is specified with a non-zero 'termination'
13190 * value check that a legal value is set and set the ADV_DVC_CFG
13191 * 'termination' field appropriately.
27c868c2 13192 */
51219358
MW
13193 if (eep_config.termination == 0) {
13194 asc_dvc->cfg->termination = 0; /* auto termination */
13195 } else {
13196 /* Enable manual control with low off / high off. */
13197 if (eep_config.termination == 1) {
13198 asc_dvc->cfg->termination = TERM_CTL_SEL;
27c868c2 13199
51219358
MW
13200 /* Enable manual control with low off / high on. */
13201 } else if (eep_config.termination == 2) {
13202 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
13203
13204 /* Enable manual control with low on / high on. */
13205 } else if (eep_config.termination == 3) {
13206 asc_dvc->cfg->termination =
13207 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
13208 } else {
27c868c2 13209 /*
51219358
MW
13210 * The EEPROM 'termination' field contains a bad value. Use
13211 * automatic termination instead.
27c868c2 13212 */
51219358
MW
13213 asc_dvc->cfg->termination = 0;
13214 warn_code |= ASC_WARN_EEPROM_TERMINATION;
27c868c2 13215 }
27c868c2 13216 }
1da177e4 13217
51219358 13218 return warn_code;
1da177e4
LT
13219}
13220
13221/*
51219358
MW
13222 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
13223 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
13224 * all of this is done.
1da177e4 13225 *
51219358
MW
13226 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13227 *
13228 * For a non-fatal error return a warning code. If there are no warnings
13229 * then 0 is returned.
13230 *
13231 * Note: Chip is stopped on entry.
1da177e4 13232 */
51219358 13233static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13234{
51219358
MW
13235 AdvPortAddr iop_base;
13236 ushort warn_code;
13237 ADVEEP_38C0800_CONFIG eep_config;
13238 uchar tid, termination;
13239 ushort sdtr_speed = 0;
27c868c2 13240
51219358 13241 iop_base = asc_dvc->iop_base;
1da177e4 13242
51219358 13243 warn_code = 0;
27c868c2
MW
13244
13245 /*
51219358
MW
13246 * Read the board's EEPROM configuration.
13247 *
13248 * Set default values if a bad checksum is found.
27c868c2 13249 */
51219358
MW
13250 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
13251 eep_config.check_sum) {
13252 warn_code |= ASC_WARN_EEPROM_CHKSUM;
27c868c2 13253
51219358
MW
13254 /*
13255 * Set EEPROM default values.
13256 */
13257 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
13258 sizeof(ADVEEP_38C0800_CONFIG));
1da177e4 13259
51219358
MW
13260 /*
13261 * Assume the 6 byte board serial number that was read from
13262 * EEPROM is correct even if the EEPROM checksum failed.
13263 */
13264 eep_config.serial_number_word3 =
13265 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 13266
51219358
MW
13267 eep_config.serial_number_word2 =
13268 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 13269
51219358
MW
13270 eep_config.serial_number_word1 =
13271 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
27c868c2 13272
51219358 13273 AdvSet38C0800EEPConfig(iop_base, &eep_config);
27c868c2 13274 }
27c868c2 13275 /*
51219358
MW
13276 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
13277 * EEPROM configuration that was read.
13278 *
13279 * This is the mapping of EEPROM fields to Adv Library fields.
27c868c2 13280 */
51219358
MW
13281 asc_dvc->wdtr_able = eep_config.wdtr_able;
13282 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13283 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13284 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13285 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13286 asc_dvc->tagqng_able = eep_config.tagqng_able;
13287 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13288 asc_dvc->max_host_qng = eep_config.max_host_qng;
13289 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13290 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13291 asc_dvc->start_motor = eep_config.start_motor;
13292 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13293 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13294 asc_dvc->no_scam = eep_config.scam_tolerant;
13295 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13296 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13297 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
27c868c2
MW
13298
13299 /*
51219358
MW
13300 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13301 * are set, then set an 'sdtr_able' bit for it.
27c868c2 13302 */
51219358
MW
13303 asc_dvc->sdtr_able = 0;
13304 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13305 if (tid == 0) {
13306 sdtr_speed = asc_dvc->sdtr_speed1;
13307 } else if (tid == 4) {
13308 sdtr_speed = asc_dvc->sdtr_speed2;
13309 } else if (tid == 8) {
13310 sdtr_speed = asc_dvc->sdtr_speed3;
13311 } else if (tid == 12) {
13312 sdtr_speed = asc_dvc->sdtr_speed4;
13313 }
13314 if (sdtr_speed & ADV_MAX_TID) {
13315 asc_dvc->sdtr_able |= (1 << tid);
13316 }
13317 sdtr_speed >>= 4;
13318 }
27c868c2
MW
13319
13320 /*
51219358
MW
13321 * Set the host maximum queuing (max. 253, min. 16) and the per device
13322 * maximum queuing (max. 63, min. 4).
27c868c2 13323 */
51219358
MW
13324 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13325 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13326 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13327 /* If the value is zero, assume it is uninitialized. */
13328 if (eep_config.max_host_qng == 0) {
13329 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13330 } else {
13331 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13332 }
27c868c2 13333 }
1da177e4 13334
51219358
MW
13335 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13336 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13337 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13338 /* If the value is zero, assume it is uninitialized. */
13339 if (eep_config.max_dvc_qng == 0) {
13340 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13341 } else {
13342 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13343 }
13344 }
13345
13346 /*
13347 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13348 * set 'max_dvc_qng' to 'max_host_qng'.
13349 */
13350 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13351 eep_config.max_dvc_qng = eep_config.max_host_qng;
27c868c2 13352 }
1da177e4 13353
27c868c2 13354 /*
51219358
MW
13355 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13356 * values based on possibly adjusted EEPROM values.
27c868c2 13357 */
51219358
MW
13358 asc_dvc->max_host_qng = eep_config.max_host_qng;
13359 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
27c868c2
MW
13360
13361 /*
51219358
MW
13362 * If the EEPROM 'termination' field is set to automatic (0), then set
13363 * the ADV_DVC_CFG 'termination' field to automatic also.
13364 *
13365 * If the termination is specified with a non-zero 'termination'
13366 * value check that a legal value is set and set the ADV_DVC_CFG
13367 * 'termination' field appropriately.
27c868c2 13368 */
51219358
MW
13369 if (eep_config.termination_se == 0) {
13370 termination = 0; /* auto termination for SE */
13371 } else {
13372 /* Enable manual control with low off / high off. */
13373 if (eep_config.termination_se == 1) {
13374 termination = 0;
13375
13376 /* Enable manual control with low off / high on. */
13377 } else if (eep_config.termination_se == 2) {
13378 termination = TERM_SE_HI;
13379
13380 /* Enable manual control with low on / high on. */
13381 } else if (eep_config.termination_se == 3) {
13382 termination = TERM_SE;
13383 } else {
13384 /*
13385 * The EEPROM 'termination_se' field contains a bad value.
13386 * Use automatic termination instead.
13387 */
13388 termination = 0;
13389 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13390 }
27c868c2 13391 }
51219358
MW
13392
13393 if (eep_config.termination_lvd == 0) {
13394 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13395 } else {
13396 /* Enable manual control with low off / high off. */
13397 if (eep_config.termination_lvd == 1) {
13398 asc_dvc->cfg->termination = termination;
13399
13400 /* Enable manual control with low off / high on. */
13401 } else if (eep_config.termination_lvd == 2) {
13402 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13403
13404 /* Enable manual control with low on / high on. */
13405 } else if (eep_config.termination_lvd == 3) {
13406 asc_dvc->cfg->termination = termination | TERM_LVD;
13407 } else {
13408 /*
13409 * The EEPROM 'termination_lvd' field contains a bad value.
13410 * Use automatic termination instead.
13411 */
13412 asc_dvc->cfg->termination = termination;
13413 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13414 }
27c868c2 13415 }
1da177e4 13416
51219358 13417 return warn_code;
1da177e4
LT
13418}
13419
13420/*
51219358
MW
13421 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13422 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13423 * all of this is done.
1da177e4 13424 *
51219358 13425 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4 13426 *
51219358
MW
13427 * For a non-fatal error return a warning code. If there are no warnings
13428 * then 0 is returned.
1da177e4 13429 *
51219358 13430 * Note: Chip is stopped on entry.
1da177e4 13431 */
51219358 13432static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13433{
27c868c2 13434 AdvPortAddr iop_base;
51219358
MW
13435 ushort warn_code;
13436 ADVEEP_38C1600_CONFIG eep_config;
13437 uchar tid, termination;
13438 ushort sdtr_speed = 0;
1da177e4 13439
27c868c2
MW
13440 iop_base = asc_dvc->iop_base;
13441
51219358 13442 warn_code = 0;
27c868c2 13443
51219358
MW
13444 /*
13445 * Read the board's EEPROM configuration.
13446 *
13447 * Set default values if a bad checksum is found.
13448 */
13449 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13450 eep_config.check_sum) {
13451 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
13452 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13453
13454 /*
13455 * Set EEPROM default values.
13456 */
13457 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13458 sizeof(ADVEEP_38C1600_CONFIG));
13459
13460 if (PCI_FUNC(pdev->devfn) != 0) {
13461 u8 ints;
13462 /*
13463 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13464 * and old Mac system booting problem. The Expansion
13465 * ROM must be disabled in Function 1 for these systems
13466 */
13467 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13468 /*
13469 * Clear the INTAB (bit 11) if the GPIO 0 input
13470 * indicates the Function 1 interrupt line is wired
13471 * to INTB.
13472 *
13473 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13474 * 1 - Function 1 interrupt line wired to INT A.
13475 * 0 - Function 1 interrupt line wired to INT B.
13476 *
13477 * Note: Function 0 is always wired to INTA.
13478 * Put all 5 GPIO bits in input mode and then read
13479 * their input values.
13480 */
13481 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13482 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13483 if ((ints & 0x01) == 0)
13484 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
13485 }
13486
13487 /*
13488 * Assume the 6 byte board serial number that was read from
13489 * EEPROM is correct even if the EEPROM checksum failed.
13490 */
13491 eep_config.serial_number_word3 =
13492 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13493 eep_config.serial_number_word2 =
13494 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13495 eep_config.serial_number_word1 =
13496 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13497
13498 AdvSet38C1600EEPConfig(iop_base, &eep_config);
27c868c2
MW
13499 }
13500
13501 /*
51219358
MW
13502 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13503 * EEPROM configuration that was read.
13504 *
13505 * This is the mapping of EEPROM fields to Adv Library fields.
27c868c2 13506 */
51219358
MW
13507 asc_dvc->wdtr_able = eep_config.wdtr_able;
13508 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13509 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13510 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13511 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13512 asc_dvc->ppr_able = 0;
13513 asc_dvc->tagqng_able = eep_config.tagqng_able;
13514 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13515 asc_dvc->max_host_qng = eep_config.max_host_qng;
13516 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13517 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13518 asc_dvc->start_motor = eep_config.start_motor;
13519 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13520 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13521 asc_dvc->no_scam = eep_config.scam_tolerant;
27c868c2 13522
51219358
MW
13523 /*
13524 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13525 * are set, then set an 'sdtr_able' bit for it.
13526 */
13527 asc_dvc->sdtr_able = 0;
13528 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13529 if (tid == 0) {
13530 sdtr_speed = asc_dvc->sdtr_speed1;
13531 } else if (tid == 4) {
13532 sdtr_speed = asc_dvc->sdtr_speed2;
13533 } else if (tid == 8) {
13534 sdtr_speed = asc_dvc->sdtr_speed3;
13535 } else if (tid == 12) {
13536 sdtr_speed = asc_dvc->sdtr_speed4;
13537 }
13538 if (sdtr_speed & ASC_MAX_TID) {
13539 asc_dvc->sdtr_able |= (1 << tid);
13540 }
13541 sdtr_speed >>= 4;
13542 }
27c868c2 13543
51219358
MW
13544 /*
13545 * Set the host maximum queuing (max. 253, min. 16) and the per device
13546 * maximum queuing (max. 63, min. 4).
13547 */
13548 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13549 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13550 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13551 /* If the value is zero, assume it is uninitialized. */
13552 if (eep_config.max_host_qng == 0) {
13553 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13554 } else {
13555 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
27c868c2 13556 }
51219358 13557 }
27c868c2 13558
51219358
MW
13559 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13560 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13561 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13562 /* If the value is zero, assume it is uninitialized. */
13563 if (eep_config.max_dvc_qng == 0) {
13564 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13565 } else {
13566 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13567 }
13568 }
13569
13570 /*
13571 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13572 * set 'max_dvc_qng' to 'max_host_qng'.
13573 */
13574 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13575 eep_config.max_dvc_qng = eep_config.max_host_qng;
27c868c2
MW
13576 }
13577
13578 /*
51219358
MW
13579 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13580 * values based on possibly adjusted EEPROM values.
13581 */
13582 asc_dvc->max_host_qng = eep_config.max_host_qng;
13583 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13584
13585 /*
13586 * If the EEPROM 'termination' field is set to automatic (0), then set
13587 * the ASC_DVC_CFG 'termination' field to automatic also.
13588 *
13589 * If the termination is specified with a non-zero 'termination'
13590 * value check that a legal value is set and set the ASC_DVC_CFG
13591 * 'termination' field appropriately.
27c868c2 13592 */
51219358
MW
13593 if (eep_config.termination_se == 0) {
13594 termination = 0; /* auto termination for SE */
13595 } else {
13596 /* Enable manual control with low off / high off. */
13597 if (eep_config.termination_se == 1) {
13598 termination = 0;
27c868c2 13599
51219358
MW
13600 /* Enable manual control with low off / high on. */
13601 } else if (eep_config.termination_se == 2) {
13602 termination = TERM_SE_HI;
27c868c2 13603
51219358
MW
13604 /* Enable manual control with low on / high on. */
13605 } else if (eep_config.termination_se == 3) {
13606 termination = TERM_SE;
13607 } else {
13608 /*
13609 * The EEPROM 'termination_se' field contains a bad value.
13610 * Use automatic termination instead.
13611 */
13612 termination = 0;
13613 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13614 }
13615 }
27c868c2 13616
51219358
MW
13617 if (eep_config.termination_lvd == 0) {
13618 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13619 } else {
13620 /* Enable manual control with low off / high off. */
13621 if (eep_config.termination_lvd == 1) {
13622 asc_dvc->cfg->termination = termination;
27c868c2 13623
51219358
MW
13624 /* Enable manual control with low off / high on. */
13625 } else if (eep_config.termination_lvd == 2) {
13626 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
27c868c2 13627
51219358
MW
13628 /* Enable manual control with low on / high on. */
13629 } else if (eep_config.termination_lvd == 3) {
13630 asc_dvc->cfg->termination = termination | TERM_LVD;
13631 } else {
13632 /*
13633 * The EEPROM 'termination_lvd' field contains a bad value.
13634 * Use automatic termination instead.
13635 */
13636 asc_dvc->cfg->termination = termination;
13637 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13638 }
27c868c2 13639 }
51219358
MW
13640
13641 return warn_code;
1da177e4
LT
13642}
13643
13644/*
51219358 13645 * Initialize the ADV_DVC_VAR structure.
1da177e4 13646 *
51219358 13647 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4 13648 *
51219358
MW
13649 * For a non-fatal error return a warning code. If there are no warnings
13650 * then 0 is returned.
1da177e4 13651 */
51219358
MW
13652static int __devinit
13653AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 13654{
51219358
MW
13655 ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
13656 unsigned short warn_code = 0;
13657 AdvPortAddr iop_base = asc_dvc->iop_base;
13658 u16 cmd;
13659 int status;
27c868c2 13660
51219358 13661 asc_dvc->err_code = 0;
27c868c2
MW
13662
13663 /*
51219358
MW
13664 * Save the state of the PCI Configuration Command Register
13665 * "Parity Error Response Control" Bit. If the bit is clear (0),
13666 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13667 * DMA parity errors.
27c868c2 13668 */
51219358
MW
13669 asc_dvc->cfg->control_flag = 0;
13670 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13671 if ((cmd & PCI_COMMAND_PARITY) == 0)
13672 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
27c868c2 13673
51219358
MW
13674 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13675 ADV_LIB_VERSION_MINOR;
13676 asc_dvc->cfg->chip_version =
13677 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13678
13679 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13680 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13681 (ushort)ADV_CHIP_ID_BYTE);
13682
13683 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13684 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13685 (ushort)ADV_CHIP_ID_WORD);
27c868c2
MW
13686
13687 /*
51219358 13688 * Reset the chip to start and allow register writes.
27c868c2 13689 */
51219358
MW
13690 if (AdvFindSignature(iop_base) == 0) {
13691 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13692 return ADV_ERROR;
13693 } else {
27c868c2 13694 /*
51219358 13695 * The caller must set 'chip_type' to a valid setting.
27c868c2 13696 */
51219358
MW
13697 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13698 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13699 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13700 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13701 return ADV_ERROR;
13702 }
1da177e4 13703
51219358
MW
13704 /*
13705 * Reset Chip.
13706 */
13707 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13708 ADV_CTRL_REG_CMD_RESET);
13709 mdelay(100);
13710 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13711 ADV_CTRL_REG_CMD_WR_IO_REG);
13712
13713 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13714 status = AdvInitFrom38C1600EEP(asc_dvc);
13715 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13716 status = AdvInitFrom38C0800EEP(asc_dvc);
13717 } else {
13718 status = AdvInitFrom3550EEP(asc_dvc);
27c868c2 13719 }
51219358 13720 warn_code |= status;
27c868c2 13721 }
1da177e4 13722
51219358
MW
13723 if (warn_code != 0) {
13724 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
13725 boardp->id, warn_code);
13726 }
13727
13728 if (asc_dvc->err_code) {
13729 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
13730 boardp->id, asc_dvc->err_code);
13731 }
13732
13733 return asc_dvc->err_code;
1da177e4 13734}
51219358
MW
13735#endif
13736
13737static struct scsi_host_template advansys_template = {
13738 .proc_name = DRV_NAME,
13739#ifdef CONFIG_PROC_FS
13740 .proc_info = advansys_proc_info,
13741#endif
13742 .name = DRV_NAME,
13743 .info = advansys_info,
13744 .queuecommand = advansys_queuecommand,
13745 .eh_bus_reset_handler = advansys_reset,
13746 .bios_param = advansys_biosparam,
13747 .slave_configure = advansys_slave_configure,
13748 /*
13749 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
13750 * must be set. The flag will be cleared in advansys_board_found
13751 * for non-ISA adapters.
13752 */
13753 .unchecked_isa_dma = 1,
13754 /*
13755 * All adapters controlled by this driver are capable of large
13756 * scatter-gather lists. According to the mid-level SCSI documentation
13757 * this obviates any performance gain provided by setting
13758 * 'use_clustering'. But empirically while CPU utilization is increased
13759 * by enabling clustering, I/O throughput increases as well.
13760 */
13761 .use_clustering = ENABLE_CLUSTERING,
13762};
1da177e4 13763
b2c16f58
MW
13764static int __devinit
13765advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
13766{
13767 int req_cnt = 0;
13768 adv_req_t *reqp = NULL;
13769 int sg_cnt = 0;
13770 adv_sgblk_t *sgp;
13771 int warn_code, err_code;
13772
13773 /*
13774 * Allocate buffer carrier structures. The total size
13775 * is about 4 KB, so allocate all at once.
13776 */
13777 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13778 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
13779
13780 if (!boardp->carrp)
13781 goto kmalloc_failed;
13782
13783 /*
13784 * Allocate up to 'max_host_qng' request structures for the Wide
13785 * board. The total size is about 16 KB, so allocate all at once.
13786 * If the allocation fails decrement and try again.
13787 */
13788 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
13789 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13790
13791 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
13792 "bytes %lu\n", reqp, req_cnt,
13793 (ulong)sizeof(adv_req_t) * req_cnt);
13794
13795 if (reqp)
13796 break;
13797 }
13798
13799 if (!reqp)
13800 goto kmalloc_failed;
13801
13802 boardp->orig_reqp = reqp;
13803
13804 /*
13805 * Allocate up to ADV_TOT_SG_BLOCK request structures for
13806 * the Wide board. Each structure is about 136 bytes.
13807 */
13808 boardp->adv_sgblkp = NULL;
13809 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13810 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13811
13812 if (!sgp)
13813 break;
13814
13815 sgp->next_sgblkp = boardp->adv_sgblkp;
13816 boardp->adv_sgblkp = sgp;
13817
13818 }
13819
13820 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
13821 sg_cnt, sizeof(adv_sgblk_t),
13822 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
13823
13824 if (!boardp->adv_sgblkp)
13825 goto kmalloc_failed;
13826
13827 adv_dvc_varp->carrier_buf = boardp->carrp;
13828
13829 /*
13830 * Point 'adv_reqp' to the request structures and
13831 * link them together.
13832 */
13833 req_cnt--;
13834 reqp[req_cnt].next_reqp = NULL;
13835 for (; req_cnt > 0; req_cnt--) {
13836 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
13837 }
13838 boardp->adv_reqp = &reqp[0];
13839
13840 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13841 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
13842 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
13843 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13844 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
13845 "\n");
13846 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
13847 } else {
13848 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
13849 "\n");
13850 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
13851 }
13852 err_code = adv_dvc_varp->err_code;
13853
13854 if (warn_code || err_code) {
13855 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
13856 " error 0x%x\n", boardp->id, warn_code, err_code);
13857 }
13858
13859 goto exit;
13860
13861 kmalloc_failed:
13862 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
13863 "failed\n", boardp->id);
13864 err_code = ADV_ERROR;
13865 exit:
13866 return err_code;
13867}
13868
13869static void advansys_wide_free_mem(asc_board_t *boardp)
13870{
13871 kfree(boardp->carrp);
13872 boardp->carrp = NULL;
13873 kfree(boardp->orig_reqp);
13874 boardp->orig_reqp = boardp->adv_reqp = NULL;
13875 while (boardp->adv_sgblkp) {
13876 adv_sgblk_t *sgp = boardp->adv_sgblkp;
13877 boardp->adv_sgblkp = sgp->next_sgblkp;
13878 kfree(sgp);
13879 }
13880}
13881
27c868c2
MW
13882static struct Scsi_Host *__devinit
13883advansys_board_found(int iop, struct device *dev, int bus_type)
13884{
13885 struct Scsi_Host *shost;
13886 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
13887 asc_board_t *boardp;
13888 ASC_DVC_VAR *asc_dvc_varp = NULL;
13889 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 13890 int share_irq;
27c868c2
MW
13891 int warn_code, err_code;
13892 int ret;
13893
13894 /*
27c868c2
MW
13895 * Register the adapter, get its configuration, and
13896 * initialize it.
13897 */
8dfb5379
MW
13898 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
13899 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
13900 if (!shost)
13901 return NULL;
13902
27c868c2
MW
13903 /* Initialize private per board data */
13904 boardp = ASC_BOARDP(shost);
13905 memset(boardp, 0, sizeof(asc_board_t));
78e77d8b 13906 boardp->id = asc_board_count++;
27c868c2 13907 spin_lock_init(&boardp->lock);
394dbf3f 13908 boardp->dev = dev;
27c868c2
MW
13909
13910 /*
13911 * Handle both narrow and wide boards.
13912 *
13913 * If a Wide board was detected, set the board structure
13914 * wide board flag. Set-up the board structure based on
13915 * the board type.
13916 */
13917#ifdef CONFIG_PCI
13918 if (bus_type == ASC_IS_PCI &&
13919 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
13920 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
13921 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
13922 boardp->flags |= ASC_IS_WIDE_BOARD;
13923 }
13924#endif /* CONFIG_PCI */
13925
13926 if (ASC_NARROW_BOARD(boardp)) {
13927 ASC_DBG(1, "advansys_board_found: narrow board\n");
13928 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
13929 asc_dvc_varp->bus_type = bus_type;
13930 asc_dvc_varp->drv_ptr = boardp;
13931 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
13932 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
13933 asc_dvc_varp->iop_base = iop;
27c868c2 13934 } else {
57ba5fe9 13935#ifdef CONFIG_PCI
27c868c2
MW
13936 ASC_DBG(1, "advansys_board_found: wide board\n");
13937 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
13938 adv_dvc_varp->drv_ptr = boardp;
13939 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
27c868c2
MW
13940 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
13941 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
13942 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13943 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
13944 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
13945 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13946 } else {
13947 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
13948 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13949 }
27c868c2 13950
57ba5fe9
MW
13951 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
13952 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
13953 boardp->asc_n_io_port);
13954 if (!boardp->ioremap_addr) {
27c868c2
MW
13955 ASC_PRINT3
13956 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
57ba5fe9
MW
13957 boardp->id, pci_resource_start(pdev, 1),
13958 boardp->asc_n_io_port);
b2c16f58 13959 goto err_shost;
27c868c2 13960 }
57ba5fe9 13961 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
71f36115 13962 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
27c868c2 13963 adv_dvc_varp->iop_base);
27c868c2
MW
13964
13965 /*
13966 * Even though it isn't used to access wide boards, other
13967 * than for the debug line below, save I/O Port address so
13968 * that it can be reported.
13969 */
13970 boardp->ioport = iop;
13971
57ba5fe9
MW
13972 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
13973 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
13974 (ushort)inpw(iop));
13975#endif /* CONFIG_PCI */
27c868c2
MW
13976 }
13977
13978#ifdef CONFIG_PROC_FS
13979 /*
13980 * Allocate buffer for printing information from
13981 * /proc/scsi/advansys/[0...].
13982 */
b2c16f58
MW
13983 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13984 if (!boardp->prtbuf) {
13985 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
13986 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
13987 goto err_unmap;
27c868c2
MW
13988 }
13989#endif /* CONFIG_PROC_FS */
13990
13991 if (ASC_NARROW_BOARD(boardp)) {
27c868c2
MW
13992 /*
13993 * Set the board bus type and PCI IRQ before
13994 * calling AscInitGetConfig().
13995 */
13996 switch (asc_dvc_varp->bus_type) {
13997#ifdef CONFIG_ISA
13998 case ASC_IS_ISA:
13999 shost->unchecked_isa_dma = TRUE;
074c8fe4 14000 share_irq = 0;
27c868c2
MW
14001 break;
14002 case ASC_IS_VL:
14003 shost->unchecked_isa_dma = FALSE;
074c8fe4 14004 share_irq = 0;
27c868c2
MW
14005 break;
14006 case ASC_IS_EISA:
14007 shost->unchecked_isa_dma = FALSE;
074c8fe4 14008 share_irq = IRQF_SHARED;
27c868c2
MW
14009 break;
14010#endif /* CONFIG_ISA */
14011#ifdef CONFIG_PCI
14012 case ASC_IS_PCI:
14013 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
27c868c2 14014 shost->unchecked_isa_dma = FALSE;
074c8fe4 14015 share_irq = IRQF_SHARED;
27c868c2
MW
14016 break;
14017#endif /* CONFIG_PCI */
14018 default:
14019 ASC_PRINT2
14020 ("advansys_board_found: board %d: unknown adapter type: %d\n",
14021 boardp->id, asc_dvc_varp->bus_type);
14022 shost->unchecked_isa_dma = TRUE;
074c8fe4 14023 share_irq = 0;
27c868c2
MW
14024 break;
14025 }
27c868c2 14026
27c868c2
MW
14027 /*
14028 * NOTE: AscInitGetConfig() may change the board's
14029 * bus_type value. The bus_type value should no
14030 * longer be used. If the bus_type field must be
14031 * referenced only use the bit-wise AND operator "&".
14032 */
14033 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
c2dce2fa 14034 err_code = AscInitGetConfig(boardp);
27c868c2 14035 } else {
c2dce2fa
MW
14036#ifdef CONFIG_PCI
14037 /*
14038 * For Wide boards set PCI information before calling
14039 * AdvInitGetConfig().
14040 */
14041 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
14042 shost->unchecked_isa_dma = FALSE;
14043 share_irq = IRQF_SHARED;
27c868c2 14044 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
394dbf3f 14045
c2dce2fa
MW
14046 err_code = AdvInitGetConfig(pdev, boardp);
14047#endif /* CONFIG_PCI */
27c868c2
MW
14048 }
14049
b2c16f58
MW
14050 if (err_code != 0)
14051 goto err_free_proc;
27c868c2
MW
14052
14053 /*
14054 * Save the EEPROM configuration so that it can be displayed
14055 * from /proc/scsi/advansys/[0...].
14056 */
14057 if (ASC_NARROW_BOARD(boardp)) {
14058
14059 ASCEEP_CONFIG *ep;
14060
14061 /*
14062 * Set the adapter's target id bit in the 'init_tidmask' field.
14063 */
14064 boardp->init_tidmask |=
14065 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
14066
14067 /*
14068 * Save EEPROM settings for the board.
14069 */
14070 ep = &boardp->eep_config.asc_eep;
14071
14072 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
14073 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
14074 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
14075 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
14076 ep->start_motor = asc_dvc_varp->start_motor;
14077 ep->cntl = asc_dvc_varp->dvc_cntl;
14078 ep->no_scam = asc_dvc_varp->no_scam;
14079 ep->max_total_qng = asc_dvc_varp->max_total_qng;
14080 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
14081 /* 'max_tag_qng' is set to the same value for every device. */
14082 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
14083 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
14084 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
14085 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
14086 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
14087 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
14088 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
14089
14090 /*
14091 * Modify board configuration.
14092 */
14093 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
c2dce2fa
MW
14094 err_code = AscInitSetConfig(pdev, boardp);
14095 if (err_code)
b2c16f58 14096 goto err_free_proc;
27c868c2
MW
14097
14098 /*
14099 * Finish initializing the 'Scsi_Host' structure.
14100 */
14101 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
14102 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
14103 shost->irq = asc_dvc_varp->irq_no;
14104 }
14105 } else {
14106 ADVEEP_3550_CONFIG *ep_3550;
14107 ADVEEP_38C0800_CONFIG *ep_38C0800;
14108 ADVEEP_38C1600_CONFIG *ep_38C1600;
14109
14110 /*
14111 * Save Wide EEP Configuration Information.
14112 */
14113 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
14114 ep_3550 = &boardp->eep_config.adv_3550_eep;
14115
14116 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
14117 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
14118 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14119 ep_3550->termination = adv_dvc_varp->cfg->termination;
14120 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
14121 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
14122 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
14123 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
14124 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
14125 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
14126 ep_3550->start_motor = adv_dvc_varp->start_motor;
14127 ep_3550->scsi_reset_delay =
14128 adv_dvc_varp->scsi_reset_wait;
14129 ep_3550->serial_number_word1 =
14130 adv_dvc_varp->cfg->serial1;
14131 ep_3550->serial_number_word2 =
14132 adv_dvc_varp->cfg->serial2;
14133 ep_3550->serial_number_word3 =
14134 adv_dvc_varp->cfg->serial3;
14135 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14136 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
14137
14138 ep_38C0800->adapter_scsi_id =
14139 adv_dvc_varp->chip_scsi_id;
14140 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
14141 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14142 ep_38C0800->termination_lvd =
14143 adv_dvc_varp->cfg->termination;
14144 ep_38C0800->disc_enable =
14145 adv_dvc_varp->cfg->disc_enable;
14146 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
14147 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
14148 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14149 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14150 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14151 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14152 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14153 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14154 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
14155 ep_38C0800->scsi_reset_delay =
14156 adv_dvc_varp->scsi_reset_wait;
14157 ep_38C0800->serial_number_word1 =
14158 adv_dvc_varp->cfg->serial1;
14159 ep_38C0800->serial_number_word2 =
14160 adv_dvc_varp->cfg->serial2;
14161 ep_38C0800->serial_number_word3 =
14162 adv_dvc_varp->cfg->serial3;
14163 } else {
14164 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
14165
14166 ep_38C1600->adapter_scsi_id =
14167 adv_dvc_varp->chip_scsi_id;
14168 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
14169 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14170 ep_38C1600->termination_lvd =
14171 adv_dvc_varp->cfg->termination;
14172 ep_38C1600->disc_enable =
14173 adv_dvc_varp->cfg->disc_enable;
14174 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
14175 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
14176 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14177 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14178 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14179 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14180 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14181 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14182 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
14183 ep_38C1600->scsi_reset_delay =
14184 adv_dvc_varp->scsi_reset_wait;
14185 ep_38C1600->serial_number_word1 =
14186 adv_dvc_varp->cfg->serial1;
14187 ep_38C1600->serial_number_word2 =
14188 adv_dvc_varp->cfg->serial2;
14189 ep_38C1600->serial_number_word3 =
14190 adv_dvc_varp->cfg->serial3;
14191 }
14192
14193 /*
14194 * Set the adapter's target id bit in the 'init_tidmask' field.
14195 */
14196 boardp->init_tidmask |=
14197 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
27c868c2
MW
14198 }
14199
14200 /*
14201 * Channels are numbered beginning with 0. For AdvanSys one host
14202 * structure supports one channel. Multi-channel boards have a
14203 * separate host structure for each channel.
14204 */
14205 shost->max_channel = 0;
14206 if (ASC_NARROW_BOARD(boardp)) {
14207 shost->max_id = ASC_MAX_TID + 1;
14208 shost->max_lun = ASC_MAX_LUN + 1;
f05ec594 14209 shost->max_cmd_len = ASC_MAX_CDB_LEN;
27c868c2
MW
14210
14211 shost->io_port = asc_dvc_varp->iop_base;
14212 boardp->asc_n_io_port = ASC_IOADR_GAP;
14213 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
14214
14215 /* Set maximum number of queues the adapter can handle. */
14216 shost->can_queue = asc_dvc_varp->max_total_qng;
14217 } else {
14218 shost->max_id = ADV_MAX_TID + 1;
14219 shost->max_lun = ADV_MAX_LUN + 1;
f05ec594 14220 shost->max_cmd_len = ADV_MAX_CDB_LEN;
27c868c2
MW
14221
14222 /*
14223 * Save the I/O Port address and length even though
14224 * I/O ports are not used to access Wide boards.
14225 * Instead the Wide boards are accessed with
14226 * PCI Memory Mapped I/O.
14227 */
14228 shost->io_port = iop;
27c868c2
MW
14229
14230 shost->this_id = adv_dvc_varp->chip_scsi_id;
14231
14232 /* Set maximum number of queues the adapter can handle. */
14233 shost->can_queue = adv_dvc_varp->max_host_qng;
14234 }
14235
27c868c2
MW
14236 /*
14237 * Following v1.3.89, 'cmd_per_lun' is no longer needed
14238 * and should be set to zero.
14239 *
14240 * But because of a bug introduced in v1.3.89 if the driver is
14241 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
14242 * SCSI function 'allocate_device' will panic. To allow the driver
14243 * to work as a module in these kernels set 'cmd_per_lun' to 1.
14244 *
14245 * Note: This is wrong. cmd_per_lun should be set to the depth
14246 * you want on untagged devices always.
14247 #ifdef MODULE
14248 */
14249 shost->cmd_per_lun = 1;
14250/* #else
14251 shost->cmd_per_lun = 0;
14252#endif */
14253
14254 /*
14255 * Set the maximum number of scatter-gather elements the
14256 * adapter can handle.
14257 */
14258 if (ASC_NARROW_BOARD(boardp)) {
14259 /*
14260 * Allow two commands with 'sg_tablesize' scatter-gather
14261 * elements to be executed simultaneously. This value is
14262 * the theoretical hardware limit. It may be decreased
14263 * below.
14264 */
14265 shost->sg_tablesize =
14266 (((asc_dvc_varp->max_total_qng - 2) / 2) *
14267 ASC_SG_LIST_PER_Q) + 1;
14268 } else {
14269 shost->sg_tablesize = ADV_MAX_SG_LIST;
14270 }
14271
14272 /*
14273 * The value of 'sg_tablesize' can not exceed the SCSI
14274 * mid-level driver definition of SG_ALL. SG_ALL also
14275 * must not be exceeded, because it is used to define the
14276 * size of the scatter-gather table in 'struct asc_sg_head'.
14277 */
14278 if (shost->sg_tablesize > SG_ALL) {
14279 shost->sg_tablesize = SG_ALL;
14280 }
14281
14282 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
14283
14284 /* BIOS start address. */
14285 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
14286 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
14287 asc_dvc_varp->bus_type);
27c868c2
MW
14288 } else {
14289 /*
14290 * Fill-in BIOS board variables. The Wide BIOS saves
14291 * information in LRAM that is used by the driver.
14292 */
14293 AdvReadWordLram(adv_dvc_varp->iop_base,
14294 BIOS_SIGNATURE, boardp->bios_signature);
14295 AdvReadWordLram(adv_dvc_varp->iop_base,
14296 BIOS_VERSION, boardp->bios_version);
14297 AdvReadWordLram(adv_dvc_varp->iop_base,
14298 BIOS_CODESEG, boardp->bios_codeseg);
14299 AdvReadWordLram(adv_dvc_varp->iop_base,
14300 BIOS_CODELEN, boardp->bios_codelen);
14301
14302 ASC_DBG2(1,
14303 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
14304 boardp->bios_signature, boardp->bios_version);
14305
14306 ASC_DBG2(1,
14307 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
14308 boardp->bios_codeseg, boardp->bios_codelen);
14309
14310 /*
14311 * If the BIOS saved a valid signature, then fill in
14312 * the BIOS code segment base address.
14313 */
14314 if (boardp->bios_signature == 0x55AA) {
14315 /*
14316 * Convert x86 realmode code segment to a linear
14317 * address by shifting left 4.
14318 */
14319 shost->base = ((ulong)boardp->bios_codeseg << 4);
14320 } else {
14321 shost->base = 0;
14322 }
14323 }
14324
14325 /*
14326 * Register Board Resources - I/O Port, DMA, IRQ
14327 */
14328
27c868c2
MW
14329 /* Register DMA Channel for Narrow boards. */
14330 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
14331#ifdef CONFIG_ISA
14332 if (ASC_NARROW_BOARD(boardp)) {
14333 /* Register DMA channel for ISA bus. */
14334 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
14335 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
01fbfe0b 14336 ret = request_dma(shost->dma_channel, DRV_NAME);
b2c16f58 14337 if (ret) {
27c868c2
MW
14338 ASC_PRINT3
14339 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
14340 boardp->id, shost->dma_channel, ret);
71f36115 14341 goto err_free_proc;
27c868c2
MW
14342 }
14343 AscEnableIsaDma(shost->dma_channel);
14344 }
14345 }
14346#endif /* CONFIG_ISA */
14347
14348 /* Register IRQ Number. */
14349 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
14350
14351 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
01fbfe0b 14352 DRV_NAME, shost);
074c8fe4
MW
14353
14354 if (ret) {
27c868c2
MW
14355 if (ret == -EBUSY) {
14356 ASC_PRINT2
14357 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14358 boardp->id, shost->irq);
14359 } else if (ret == -EINVAL) {
14360 ASC_PRINT2
14361 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14362 boardp->id, shost->irq);
14363 } else {
14364 ASC_PRINT3
14365 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14366 boardp->id, shost->irq, ret);
14367 }
b2c16f58 14368 goto err_free_dma;
27c868c2
MW
14369 }
14370
14371 /*
14372 * Initialize board RISC chip and enable interrupts.
14373 */
14374 if (ASC_NARROW_BOARD(boardp)) {
14375 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
14376 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14377 err_code = asc_dvc_varp->err_code;
14378
14379 if (warn_code || err_code) {
14380 ASC_PRINT4
14381 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
14382 boardp->id,
14383 asc_dvc_varp->init_state, warn_code, err_code);
14384 }
14385 } else {
b2c16f58 14386 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
14387 }
14388
b2c16f58
MW
14389 if (err_code != 0)
14390 goto err_free_wide_mem;
14391
27c868c2
MW
14392 ASC_DBG_PRT_SCSI_HOST(2, shost);
14393
8dfb5379
MW
14394 ret = scsi_add_host(shost, dev);
14395 if (ret)
14396 goto err_free_wide_mem;
14397
14398 scsi_scan_host(shost);
27c868c2 14399 return shost;
b2c16f58
MW
14400
14401 err_free_wide_mem:
14402 advansys_wide_free_mem(boardp);
14403 free_irq(shost->irq, shost);
14404 err_free_dma:
14405 if (shost->dma_channel != NO_ISA_DMA)
14406 free_dma(shost->dma_channel);
b2c16f58
MW
14407 err_free_proc:
14408 kfree(boardp->prtbuf);
14409 err_unmap:
14410 if (boardp->ioremap_addr)
14411 iounmap(boardp->ioremap_addr);
14412 err_shost:
8dfb5379 14413 scsi_host_put(shost);
b2c16f58 14414 return NULL;
27c868c2
MW
14415}
14416
27c868c2
MW
14417/*
14418 * advansys_release()
14419 *
14420 * Release resources allocated for a single AdvanSys adapter.
14421 */
14422static int advansys_release(struct Scsi_Host *shost)
14423{
14424 asc_board_t *boardp;
14425
14426 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 14427 scsi_remove_host(shost);
27c868c2 14428 boardp = ASC_BOARDP(shost);
074c8fe4 14429 free_irq(shost->irq, shost);
27c868c2
MW
14430 if (shost->dma_channel != NO_ISA_DMA) {
14431 ASC_DBG(1, "advansys_release: free_dma()\n");
14432 free_dma(shost->dma_channel);
14433 }
9a256fa5 14434 if (!ASC_NARROW_BOARD(boardp)) {
27c868c2 14435 iounmap(boardp->ioremap_addr);
b2c16f58 14436 advansys_wide_free_mem(boardp);
27c868c2 14437 }
27c868c2 14438 kfree(boardp->prtbuf);
8dfb5379 14439 scsi_host_put(shost);
27c868c2
MW
14440 ASC_DBG(1, "advansys_release: end\n");
14441 return 0;
14442}
14443
95c9f162
MW
14444#define ASC_IOADR_TABLE_MAX_IX 11
14445
c304ec94
MW
14446static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14447 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14448 0x0210, 0x0230, 0x0250, 0x0330
14449};
14450
14451static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14452{
14453 PortAddr iop_base = _asc_def_iop_base[id];
14454 struct Scsi_Host *shost;
14455
01fbfe0b 14456 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
71f36115
MW
14457 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
14458 iop_base);
c304ec94
MW
14459 return -ENODEV;
14460 }
14461 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
14462 if (!AscFindSignature(iop_base))
14463 goto nodev;
14464 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14465 goto nodev;
14466
14467 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
c304ec94
MW
14468 if (!shost)
14469 goto nodev;
14470
14471 dev_set_drvdata(dev, shost);
14472 return 0;
14473
14474 nodev:
71f36115 14475 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
14476 return -ENODEV;
14477}
14478
14479static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14480{
71f36115 14481 int ioport = _asc_def_iop_base[id];
c304ec94 14482 advansys_release(dev_get_drvdata(dev));
71f36115 14483 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
14484 return 0;
14485}
14486
14487static struct isa_driver advansys_isa_driver = {
14488 .probe = advansys_isa_probe,
14489 .remove = __devexit_p(advansys_isa_remove),
14490 .driver = {
14491 .owner = THIS_MODULE,
01fbfe0b 14492 .name = DRV_NAME,
c304ec94
MW
14493 },
14494};
14495
14496static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14497{
14498 PortAddr iop_base = _asc_def_iop_base[id];
14499 struct Scsi_Host *shost;
14500
01fbfe0b 14501 if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
71f36115
MW
14502 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
14503 iop_base);
c304ec94
MW
14504 return -ENODEV;
14505 }
14506 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
14507 if (!AscFindSignature(iop_base))
14508 goto nodev;
14509 /*
14510 * I don't think this condition can actually happen, but the old
14511 * driver did it, and the chances of finding a VLB setup in 2007
14512 * to do testing with is slight to none.
14513 */
14514 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14515 goto nodev;
14516
14517 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
c304ec94
MW
14518 if (!shost)
14519 goto nodev;
14520
14521 dev_set_drvdata(dev, shost);
14522 return 0;
14523
14524 nodev:
71f36115 14525 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
14526 return -ENODEV;
14527}
14528
14529static struct isa_driver advansys_vlb_driver = {
14530 .probe = advansys_vlb_probe,
14531 .remove = __devexit_p(advansys_isa_remove),
14532 .driver = {
14533 .owner = THIS_MODULE,
b8e5152b 14534 .name = "advansys_vlb",
c304ec94
MW
14535 },
14536};
14537
b09e05a7
MW
14538static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14539 { "ABP7401" },
14540 { "ABP7501" },
14541 { "" }
14542};
14543
14544MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14545
14546/*
14547 * EISA is a little more tricky than PCI; each EISA device may have two
14548 * channels, and this driver is written to make each channel its own Scsi_Host
14549 */
14550struct eisa_scsi_data {
14551 struct Scsi_Host *host[2];
14552};
14553
14554static int __devinit advansys_eisa_probe(struct device *dev)
14555{
14556 int i, ioport;
14557 int err;
14558 struct eisa_device *edev = to_eisa_device(dev);
14559 struct eisa_scsi_data *data;
14560
14561 err = -ENOMEM;
14562 data = kzalloc(sizeof(*data), GFP_KERNEL);
14563 if (!data)
14564 goto fail;
14565 ioport = edev->base_addr + 0xc30;
14566
14567 err = -ENODEV;
14568 for (i = 0; i < 2; i++, ioport += 0x20) {
01fbfe0b 14569 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
71f36115
MW
14570 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14571 ioport + ASC_IOADR_GAP - 1);
14572 continue;
14573 }
14574 if (!AscFindSignature(ioport)) {
14575 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 14576 continue;
71f36115
MW
14577 }
14578
b09e05a7
MW
14579 /*
14580 * I don't know why we need to do this for EISA chips, but
14581 * not for any others. It looks to be equivalent to
14582 * AscGetChipCfgMsw, but I may have overlooked something,
14583 * so I'm not converting it until I get an EISA board to
14584 * test with.
14585 */
14586 inw(ioport + 4);
14587 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
71f36115 14588 if (data->host[i]) {
b09e05a7 14589 err = 0;
71f36115
MW
14590 } else {
14591 release_region(ioport, ASC_IOADR_GAP);
14592 }
b09e05a7
MW
14593 }
14594
14595 if (err) {
14596 kfree(data);
14597 } else {
14598 dev_set_drvdata(dev, data);
14599 }
14600
14601 fail:
14602 return err;
14603}
14604
14605static __devexit int advansys_eisa_remove(struct device *dev)
14606{
14607 int i;
14608 struct eisa_scsi_data *data = dev_get_drvdata(dev);
14609
14610 for (i = 0; i < 2; i++) {
71f36115 14611 int ioport;
b09e05a7
MW
14612 struct Scsi_Host *shost = data->host[i];
14613 if (!shost)
14614 continue;
71f36115 14615 ioport = shost->io_port;
b09e05a7 14616 advansys_release(shost);
71f36115 14617 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
14618 }
14619
14620 kfree(data);
14621 return 0;
14622}
14623
14624static struct eisa_driver advansys_eisa_driver = {
14625 .id_table = advansys_eisa_table,
14626 .driver = {
01fbfe0b 14627 .name = DRV_NAME,
b09e05a7
MW
14628 .probe = advansys_eisa_probe,
14629 .remove = __devexit_p(advansys_eisa_remove),
14630 }
14631};
14632
2672ea86
DJ
14633/* PCI Devices supported by this driver */
14634static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
14635 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14636 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14637 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14638 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14639 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14640 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14641 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14642 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14643 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14644 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14645 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14646 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14647 {}
2672ea86 14648};
27c868c2 14649
2672ea86 14650MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b 14651
9649af39
MW
14652static void __devinit advansys_set_latency(struct pci_dev *pdev)
14653{
14654 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14655 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14656 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14657 } else {
14658 u8 latency;
14659 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14660 if (latency < 0x20)
14661 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14662 }
14663}
14664
78e77d8b
MW
14665static int __devinit
14666advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14667{
14668 int err, ioport;
14669 struct Scsi_Host *shost;
14670
14671 err = pci_enable_device(pdev);
14672 if (err)
14673 goto fail;
01fbfe0b 14674 err = pci_request_regions(pdev, DRV_NAME);
71f36115
MW
14675 if (err)
14676 goto disable_device;
9649af39
MW
14677 pci_set_master(pdev);
14678 advansys_set_latency(pdev);
78e77d8b
MW
14679
14680 if (pci_resource_len(pdev, 0) == 0)
14681 goto nodev;
14682
14683 ioport = pci_resource_start(pdev, 0);
14684 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
14685
14686 if (!shost)
14687 goto nodev;
14688
14689 pci_set_drvdata(pdev, shost);
14690 return 0;
14691
14692 nodev:
14693 err = -ENODEV;
71f36115
MW
14694 pci_release_regions(pdev);
14695 disable_device:
78e77d8b
MW
14696 pci_disable_device(pdev);
14697 fail:
14698 return err;
14699}
14700
14701static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14702{
14703 advansys_release(pci_get_drvdata(pdev));
71f36115 14704 pci_release_regions(pdev);
78e77d8b
MW
14705 pci_disable_device(pdev);
14706}
14707
14708static struct pci_driver advansys_pci_driver = {
01fbfe0b 14709 .name = DRV_NAME,
78e77d8b
MW
14710 .id_table = advansys_pci_tbl,
14711 .probe = advansys_pci_probe,
14712 .remove = __devexit_p(advansys_pci_remove),
14713};
8c6af9e1 14714
8dfb5379
MW
14715static int __init advansys_init(void)
14716{
c304ec94 14717 int error;
b09e05a7 14718
c304ec94
MW
14719 error = isa_register_driver(&advansys_isa_driver,
14720 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
14721 if (error)
14722 goto fail;
8dfb5379 14723
c304ec94
MW
14724 error = isa_register_driver(&advansys_vlb_driver,
14725 ASC_IOADR_TABLE_MAX_IX);
14726 if (error)
14727 goto unregister_isa;
14728
14729 error = eisa_driver_register(&advansys_eisa_driver);
14730 if (error)
14731 goto unregister_vlb;
14732
b09e05a7
MW
14733 error = pci_register_driver(&advansys_pci_driver);
14734 if (error)
14735 goto unregister_eisa;
14736
8dfb5379 14737 return 0;
78e77d8b 14738
b09e05a7
MW
14739 unregister_eisa:
14740 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
14741 unregister_vlb:
14742 isa_unregister_driver(&advansys_vlb_driver);
14743 unregister_isa:
14744 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 14745 fail:
78e77d8b 14746 return error;
8dfb5379
MW
14747}
14748
14749static void __exit advansys_exit(void)
14750{
78e77d8b 14751 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 14752 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
14753 isa_unregister_driver(&advansys_vlb_driver);
14754 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
14755}
14756
14757module_init(advansys_init);
14758module_exit(advansys_exit);
14759
8c6af9e1 14760MODULE_LICENSE("GPL");
This page took 1.106324 seconds and 5 git commands to generate.