[SCSI] advansys: Comment/indentation/macro cleanup
[deliverable/linux.git] / drivers / scsi / advansys.c
CommitLineData
8c6af9e1 1#define ASC_VERSION "3.4" /* AdvanSys Driver Version */
1da177e4
LT
2
3/*
4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5 *
6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
7 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8c6af9e1 8 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
1da177e4
LT
9 * All Rights Reserved.
10 *
8c6af9e1
MW
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17/*
1da177e4
LT
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
8c6af9e1 20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
1da177e4
LT
21 */
22
1da177e4 23#include <linux/module.h>
1da177e4
LT
24#include <linux/string.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/ioport.h>
28#include <linux/interrupt.h>
29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <linux/mm.h>
32#include <linux/proc_fs.h>
33#include <linux/init.h>
34#include <linux/blkdev.h>
c304ec94 35#include <linux/isa.h>
b09e05a7 36#include <linux/eisa.h>
8c6af9e1 37#include <linux/pci.h>
1da177e4
LT
38#include <linux/spinlock.h>
39#include <linux/dma-mapping.h>
40
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/dma.h>
44
8c6af9e1
MW
45#include <scsi/scsi_cmnd.h>
46#include <scsi/scsi_device.h>
47#include <scsi/scsi_tcq.h>
48#include <scsi/scsi.h>
49#include <scsi/scsi_host.h>
50
4bd6d7f3 51/* FIXME:
1da177e4 52 *
4bd6d7f3
MW
53 * 1. Although all of the necessary command mapping places have the
54 * appropriate dma_map.. APIs, the driver still processes its internal
55 * queue using bus_to_virt() and virt_to_bus() which are illegal under
56 * the API. The entire queue processing structure will need to be
57 * altered to fix this.
58 * 2. Need to add memory mapping workaround. Test the memory mapping.
59 * If it doesn't work revert to I/O port access. Can a test be done
60 * safely?
61 * 3. Handle an interrupt not working. Keep an interrupt counter in
62 * the interrupt handler. In the timeout function if the interrupt
63 * has not occurred then print a message and run in polled mode.
64 * 4. Need to add support for target mode commands, cf. CAM XPT.
65 * 5. check DMA mapping functions for failure
349d2c44
MW
66 * 6. Use scsi_transport_spi
67 * 7. advansys_info is not safe against multiple simultaneous callers
68 * 8. Kill boardp->id
69 * 9. Add module_param to override ISA/VLB ioport array
1da177e4
LT
70 */
71#warning this driver is still not properly converted to the DMA API
72
1da177e4
LT
73/* Enable driver /proc statistics. */
74#define ADVANSYS_STATS
75
76/* Enable driver tracing. */
77/* #define ADVANSYS_DEBUG */
78
1da177e4
LT
79#define ASC_LIB_VERSION_MAJOR 1
80#define ASC_LIB_VERSION_MINOR 24
81#define ASC_LIB_SERIAL_NUMBER 123
82
83/*
84 * Portable Data Types
85 *
86 * Any instance where a 32-bit long or pointer type is assumed
87 * for precision or HW defined structures, the following define
88 * types must be used. In Linux the char, short, and int types
89 * are all consistent at 8, 16, and 32 bits respectively. Pointers
90 * and long types are 64 bits on Alpha and UltraSPARC.
91 */
27c868c2
MW
92#define ASC_PADDR __u32 /* Physical/Bus address data type. */
93#define ASC_VADDR __u32 /* Virtual address data type. */
94#define ASC_DCNT __u32 /* Unsigned Data count type. */
95#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
96
97/*
98 * These macros are used to convert a virtual address to a
99 * 32-bit value. This currently can be used on Linux Alpha
100 * which uses 64-bit virtual address but a 32-bit bus address.
101 * This is likely to break in the future, but doing this now
102 * will give us time to change the HW and FW to handle 64-bit
103 * addresses.
104 */
105#define ASC_VADDR_TO_U32 virt_to_bus
106#define ASC_U32_TO_VADDR bus_to_virt
107
108typedef unsigned char uchar;
109
110#ifndef TRUE
111#define TRUE (1)
112#endif
113#ifndef FALSE
114#define FALSE (0)
115#endif
116
1da177e4
LT
117#define ERR (-1)
118#define UW_ERR (uint)(0xFFFF)
119#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
1da177e4 120
2672ea86
DJ
121#define PCI_VENDOR_ID_ASP 0x10cd
122#define PCI_DEVICE_ID_ASP_1200A 0x1100
123#define PCI_DEVICE_ID_ASP_ABP940 0x1200
124#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
125#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
126#define PCI_DEVICE_ID_38C0800_REV1 0x2500
127#define PCI_DEVICE_ID_38C1600_REV1 0x2700
128
1da177e4
LT
129/*
130 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
131 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
132 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
133 * SRB structure.
134 */
135#define CC_VERY_LONG_SG_LIST 0
136#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
137
27c868c2 138#define PortAddr unsigned short /* port address size */
1da177e4
LT
139#define inp(port) inb(port)
140#define outp(port, byte) outb((byte), (port))
141
142#define inpw(port) inw(port)
143#define outpw(port, word) outw((word), (port))
144
145#define ASC_MAX_SG_QUEUE 7
146#define ASC_MAX_SG_LIST 255
147
148#define ASC_CS_TYPE unsigned short
149
150#define ASC_IS_ISA (0x0001)
151#define ASC_IS_ISAPNP (0x0081)
152#define ASC_IS_EISA (0x0002)
153#define ASC_IS_PCI (0x0004)
154#define ASC_IS_PCI_ULTRA (0x0104)
155#define ASC_IS_PCMCIA (0x0008)
156#define ASC_IS_MCA (0x0020)
157#define ASC_IS_VL (0x0040)
1da177e4
LT
158#define ASC_IS_WIDESCSI_16 (0x0100)
159#define ASC_IS_WIDESCSI_32 (0x0200)
160#define ASC_IS_BIG_ENDIAN (0x8000)
95c9f162 161
1da177e4
LT
162#define ASC_CHIP_MIN_VER_VL (0x01)
163#define ASC_CHIP_MAX_VER_VL (0x07)
164#define ASC_CHIP_MIN_VER_PCI (0x09)
165#define ASC_CHIP_MAX_VER_PCI (0x0F)
166#define ASC_CHIP_VER_PCI_BIT (0x08)
167#define ASC_CHIP_MIN_VER_ISA (0x11)
168#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
169#define ASC_CHIP_MAX_VER_ISA (0x27)
170#define ASC_CHIP_VER_ISA_BIT (0x30)
171#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
172#define ASC_CHIP_VER_ASYN_BUG (0x21)
173#define ASC_CHIP_VER_PCI 0x08
174#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
175#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
176#define ASC_CHIP_MIN_VER_EISA (0x41)
177#define ASC_CHIP_MAX_VER_EISA (0x47)
178#define ASC_CHIP_VER_EISA_BIT (0x40)
179#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
1da177e4 180#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
1da177e4 181#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
1da177e4 182#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
1da177e4
LT
183
184#define ASC_SCSI_ID_BITS 3
185#define ASC_SCSI_TIX_TYPE uchar
186#define ASC_ALL_DEVICE_BIT_SET 0xFF
187#define ASC_SCSI_BIT_ID_TYPE uchar
188#define ASC_MAX_TID 7
189#define ASC_MAX_LUN 7
190#define ASC_SCSI_WIDTH_BIT_SET 0xFF
191#define ASC_MAX_SENSE_LEN 32
192#define ASC_MIN_SENSE_LEN 14
1da177e4
LT
193#define ASC_SCSI_RESET_HOLD_TIME_US 60
194
f05ec594
MW
195/*
196 * Narrow boards only support 12-byte commands, while wide boards
197 * extend to 16-byte commands.
198 */
199#define ASC_MAX_CDB_LEN 12
200#define ADV_MAX_CDB_LEN 16
201
1da177e4 202#define MS_SDTR_LEN 0x03
1da177e4 203#define MS_WDTR_LEN 0x02
1da177e4
LT
204
205#define ASC_SG_LIST_PER_Q 7
206#define QS_FREE 0x00
207#define QS_READY 0x01
208#define QS_DISC1 0x02
209#define QS_DISC2 0x04
210#define QS_BUSY 0x08
211#define QS_ABORTED 0x40
212#define QS_DONE 0x80
213#define QC_NO_CALLBACK 0x01
214#define QC_SG_SWAP_QUEUE 0x02
215#define QC_SG_HEAD 0x04
216#define QC_DATA_IN 0x08
217#define QC_DATA_OUT 0x10
218#define QC_URGENT 0x20
219#define QC_MSG_OUT 0x40
220#define QC_REQ_SENSE 0x80
221#define QCSG_SG_XFER_LIST 0x02
222#define QCSG_SG_XFER_MORE 0x04
223#define QCSG_SG_XFER_END 0x08
224#define QD_IN_PROGRESS 0x00
225#define QD_NO_ERROR 0x01
226#define QD_ABORTED_BY_HOST 0x02
227#define QD_WITH_ERROR 0x04
228#define QD_INVALID_REQUEST 0x80
229#define QD_INVALID_HOST_NUM 0x81
230#define QD_INVALID_DEVICE 0x82
231#define QD_ERR_INTERNAL 0xFF
232#define QHSTA_NO_ERROR 0x00
233#define QHSTA_M_SEL_TIMEOUT 0x11
234#define QHSTA_M_DATA_OVER_RUN 0x12
235#define QHSTA_M_DATA_UNDER_RUN 0x12
236#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
237#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
238#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
239#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
240#define QHSTA_D_HOST_ABORT_FAILED 0x23
241#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
242#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
243#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
244#define QHSTA_M_WTM_TIMEOUT 0x41
245#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
246#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
247#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
248#define QHSTA_M_TARGET_STATUS_BUSY 0x45
249#define QHSTA_M_BAD_TAG_CODE 0x46
250#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
251#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
252#define QHSTA_D_LRAM_CMP_ERROR 0x81
253#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
254#define ASC_FLAG_SCSIQ_REQ 0x01
255#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
256#define ASC_FLAG_BIOS_ASYNC_IO 0x04
257#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
258#define ASC_FLAG_WIN16 0x10
259#define ASC_FLAG_WIN32 0x20
260#define ASC_FLAG_ISA_OVER_16MB 0x40
261#define ASC_FLAG_DOS_VM_CALLBACK 0x80
262#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
263#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
264#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
265#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
266#define ASC_SCSIQ_CPY_BEG 4
267#define ASC_SCSIQ_SGHD_CPY_BEG 2
268#define ASC_SCSIQ_B_FWD 0
269#define ASC_SCSIQ_B_BWD 1
270#define ASC_SCSIQ_B_STATUS 2
271#define ASC_SCSIQ_B_QNO 3
272#define ASC_SCSIQ_B_CNTL 4
273#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
274#define ASC_SCSIQ_D_DATA_ADDR 8
275#define ASC_SCSIQ_D_DATA_CNT 12
276#define ASC_SCSIQ_B_SENSE_LEN 20
277#define ASC_SCSIQ_DONE_INFO_BEG 22
278#define ASC_SCSIQ_D_SRBPTR 22
279#define ASC_SCSIQ_B_TARGET_IX 26
280#define ASC_SCSIQ_B_CDB_LEN 28
281#define ASC_SCSIQ_B_TAG_CODE 29
282#define ASC_SCSIQ_W_VM_ID 30
283#define ASC_SCSIQ_DONE_STATUS 32
284#define ASC_SCSIQ_HOST_STATUS 33
285#define ASC_SCSIQ_SCSI_STATUS 34
286#define ASC_SCSIQ_CDB_BEG 36
287#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
288#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
289#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
290#define ASC_SCSIQ_B_SG_WK_QP 49
291#define ASC_SCSIQ_B_SG_WK_IX 50
292#define ASC_SCSIQ_W_ALT_DC1 52
293#define ASC_SCSIQ_B_LIST_CNT 6
294#define ASC_SCSIQ_B_CUR_LIST_CNT 7
295#define ASC_SGQ_B_SG_CNTL 4
296#define ASC_SGQ_B_SG_HEAD_QP 5
297#define ASC_SGQ_B_SG_LIST_CNT 6
298#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
299#define ASC_SGQ_LIST_BEG 8
300#define ASC_DEF_SCSI1_QNG 4
301#define ASC_MAX_SCSI1_QNG 4
302#define ASC_DEF_SCSI2_QNG 16
303#define ASC_MAX_SCSI2_QNG 32
304#define ASC_TAG_CODE_MASK 0x23
305#define ASC_STOP_REQ_RISC_STOP 0x01
306#define ASC_STOP_ACK_RISC_STOP 0x03
307#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
308#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
309#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
310#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
311#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
312#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
313#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
314#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
315#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
316#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
317
318typedef struct asc_scsiq_1 {
27c868c2
MW
319 uchar status;
320 uchar q_no;
321 uchar cntl;
322 uchar sg_queue_cnt;
323 uchar target_id;
324 uchar target_lun;
325 ASC_PADDR data_addr;
326 ASC_DCNT data_cnt;
327 ASC_PADDR sense_addr;
328 uchar sense_len;
329 uchar extra_bytes;
1da177e4
LT
330} ASC_SCSIQ_1;
331
332typedef struct asc_scsiq_2 {
27c868c2
MW
333 ASC_VADDR srb_ptr;
334 uchar target_ix;
335 uchar flag;
336 uchar cdb_len;
337 uchar tag_code;
338 ushort vm_id;
1da177e4
LT
339} ASC_SCSIQ_2;
340
341typedef struct asc_scsiq_3 {
27c868c2
MW
342 uchar done_stat;
343 uchar host_stat;
344 uchar scsi_stat;
345 uchar scsi_msg;
1da177e4
LT
346} ASC_SCSIQ_3;
347
348typedef struct asc_scsiq_4 {
27c868c2
MW
349 uchar cdb[ASC_MAX_CDB_LEN];
350 uchar y_first_sg_list_qp;
351 uchar y_working_sg_qp;
352 uchar y_working_sg_ix;
353 uchar y_res;
354 ushort x_req_count;
355 ushort x_reconnect_rtn;
356 ASC_PADDR x_saved_data_addr;
357 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
358} ASC_SCSIQ_4;
359
360typedef struct asc_q_done_info {
27c868c2
MW
361 ASC_SCSIQ_2 d2;
362 ASC_SCSIQ_3 d3;
363 uchar q_status;
364 uchar q_no;
365 uchar cntl;
366 uchar sense_len;
367 uchar extra_bytes;
368 uchar res;
369 ASC_DCNT remain_bytes;
1da177e4
LT
370} ASC_QDONE_INFO;
371
372typedef struct asc_sg_list {
27c868c2
MW
373 ASC_PADDR addr;
374 ASC_DCNT bytes;
1da177e4
LT
375} ASC_SG_LIST;
376
377typedef struct asc_sg_head {
27c868c2
MW
378 ushort entry_cnt;
379 ushort queue_cnt;
380 ushort entry_to_copy;
381 ushort res;
382 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
383} ASC_SG_HEAD;
384
1da177e4 385typedef struct asc_scsi_q {
27c868c2
MW
386 ASC_SCSIQ_1 q1;
387 ASC_SCSIQ_2 q2;
388 uchar *cdbptr;
389 ASC_SG_HEAD *sg_head;
390 ushort remain_sg_entry_cnt;
391 ushort next_sg_index;
1da177e4
LT
392} ASC_SCSI_Q;
393
394typedef struct asc_scsi_req_q {
27c868c2
MW
395 ASC_SCSIQ_1 r1;
396 ASC_SCSIQ_2 r2;
397 uchar *cdbptr;
398 ASC_SG_HEAD *sg_head;
399 uchar *sense_ptr;
400 ASC_SCSIQ_3 r3;
401 uchar cdb[ASC_MAX_CDB_LEN];
402 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
403} ASC_SCSI_REQ_Q;
404
405typedef struct asc_scsi_bios_req_q {
27c868c2
MW
406 ASC_SCSIQ_1 r1;
407 ASC_SCSIQ_2 r2;
408 uchar *cdbptr;
409 ASC_SG_HEAD *sg_head;
410 uchar *sense_ptr;
411 ASC_SCSIQ_3 r3;
412 uchar cdb[ASC_MAX_CDB_LEN];
413 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
414} ASC_SCSI_BIOS_REQ_Q;
415
416typedef struct asc_risc_q {
27c868c2
MW
417 uchar fwd;
418 uchar bwd;
419 ASC_SCSIQ_1 i1;
420 ASC_SCSIQ_2 i2;
421 ASC_SCSIQ_3 i3;
422 ASC_SCSIQ_4 i4;
1da177e4
LT
423} ASC_RISC_Q;
424
425typedef struct asc_sg_list_q {
27c868c2
MW
426 uchar seq_no;
427 uchar q_no;
428 uchar cntl;
429 uchar sg_head_qp;
430 uchar sg_list_cnt;
431 uchar sg_cur_list_cnt;
1da177e4
LT
432} ASC_SG_LIST_Q;
433
434typedef struct asc_risc_sg_list_q {
27c868c2
MW
435 uchar fwd;
436 uchar bwd;
437 ASC_SG_LIST_Q sg;
438 ASC_SG_LIST sg_list[7];
1da177e4
LT
439} ASC_RISC_SG_LIST_Q;
440
1da177e4 441#define ASCQ_ERR_Q_STATUS 0x0D
1da177e4
LT
442#define ASCQ_ERR_CUR_QNG 0x17
443#define ASCQ_ERR_SG_Q_LINKS 0x18
1da177e4
LT
444#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
445#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
446#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1da177e4
LT
447
448/*
449 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
450 */
451#define ASC_WARN_NO_ERROR 0x0000
452#define ASC_WARN_IO_PORT_ROTATE 0x0001
453#define ASC_WARN_EEPROM_CHKSUM 0x0002
454#define ASC_WARN_IRQ_MODIFIED 0x0004
455#define ASC_WARN_AUTO_CONFIG 0x0008
456#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
457#define ASC_WARN_EEPROM_RECOVER 0x0020
458#define ASC_WARN_CFG_MSW_RECOVER 0x0040
1da177e4
LT
459
460/*
461 * Error code values are set in ASC_DVC_VAR 'err_code'.
462 */
463#define ASC_IERR_WRITE_EEPROM 0x0001
464#define ASC_IERR_MCODE_CHKSUM 0x0002
465#define ASC_IERR_SET_PC_ADDR 0x0004
466#define ASC_IERR_START_STOP_CHIP 0x0008
467#define ASC_IERR_IRQ_NO 0x0010
468#define ASC_IERR_SET_IRQ_NO 0x0020
469#define ASC_IERR_CHIP_VERSION 0x0040
470#define ASC_IERR_SET_SCSI_ID 0x0080
471#define ASC_IERR_GET_PHY_ADDR 0x0100
472#define ASC_IERR_BAD_SIGNATURE 0x0200
473#define ASC_IERR_NO_BUS_TYPE 0x0400
474#define ASC_IERR_SCAM 0x0800
475#define ASC_IERR_SET_SDTR 0x1000
476#define ASC_IERR_RW_LRAM 0x8000
477
1da177e4
LT
478#define ASC_MAX_IRQ_NO 15
479#define ASC_MIN_IRQ_NO 10
1da177e4
LT
480#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
481#define ASC_MIN_TAG_Q_PER_DVC (0x04)
95c9f162 482#define ASC_MIN_FREE_Q (0x02)
1da177e4
LT
483#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
484#define ASC_MAX_TOTAL_QNG 240
485#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
486#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
487#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
488#define ASC_MAX_INRAM_TAG_QNG 16
1da177e4 489#define ASC_IOADR_GAP 0x10
1da177e4
LT
490#define ASC_MAX_SYN_XFER_NO 16
491#define ASC_SYN_MAX_OFFSET 0x0F
492#define ASC_DEF_SDTR_OFFSET 0x0F
1da177e4
LT
493#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
494#define SYN_XFER_NS_0 25
495#define SYN_XFER_NS_1 30
496#define SYN_XFER_NS_2 35
497#define SYN_XFER_NS_3 40
498#define SYN_XFER_NS_4 50
499#define SYN_XFER_NS_5 60
500#define SYN_XFER_NS_6 70
501#define SYN_XFER_NS_7 85
502#define SYN_ULTRA_XFER_NS_0 12
503#define SYN_ULTRA_XFER_NS_1 19
504#define SYN_ULTRA_XFER_NS_2 25
505#define SYN_ULTRA_XFER_NS_3 32
506#define SYN_ULTRA_XFER_NS_4 38
507#define SYN_ULTRA_XFER_NS_5 44
508#define SYN_ULTRA_XFER_NS_6 50
509#define SYN_ULTRA_XFER_NS_7 57
510#define SYN_ULTRA_XFER_NS_8 63
511#define SYN_ULTRA_XFER_NS_9 69
512#define SYN_ULTRA_XFER_NS_10 75
513#define SYN_ULTRA_XFER_NS_11 82
514#define SYN_ULTRA_XFER_NS_12 88
515#define SYN_ULTRA_XFER_NS_13 94
516#define SYN_ULTRA_XFER_NS_14 100
517#define SYN_ULTRA_XFER_NS_15 107
518
519typedef struct ext_msg {
27c868c2
MW
520 uchar msg_type;
521 uchar msg_len;
522 uchar msg_req;
523 union {
524 struct {
525 uchar sdtr_xfer_period;
526 uchar sdtr_req_ack_offset;
527 } sdtr;
528 struct {
529 uchar wdtr_width;
530 } wdtr;
531 struct {
532 uchar mdp_b3;
533 uchar mdp_b2;
534 uchar mdp_b1;
535 uchar mdp_b0;
536 } mdp;
537 } u_ext_msg;
538 uchar res;
1da177e4
LT
539} EXT_MSG;
540
541#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
542#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
543#define wdtr_width u_ext_msg.wdtr.wdtr_width
544#define mdp_b3 u_ext_msg.mdp_b3
545#define mdp_b2 u_ext_msg.mdp_b2
546#define mdp_b1 u_ext_msg.mdp_b1
547#define mdp_b0 u_ext_msg.mdp_b0
548
549typedef struct asc_dvc_cfg {
27c868c2
MW
550 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
551 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
552 ASC_SCSI_BIT_ID_TYPE disc_enable;
553 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
554 uchar chip_scsi_id;
555 uchar isa_dma_speed;
556 uchar isa_dma_channel;
557 uchar chip_version;
558 ushort lib_serial_no;
559 ushort lib_version;
560 ushort mcode_date;
561 ushort mcode_version;
562 uchar max_tag_qng[ASC_MAX_TID + 1];
563 uchar *overrun_buf;
564 uchar sdtr_period_offset[ASC_MAX_TID + 1];
27c868c2 565 uchar adapter_info[6];
1da177e4
LT
566} ASC_DVC_CFG;
567
568#define ASC_DEF_DVC_CNTL 0xFFFF
569#define ASC_DEF_CHIP_SCSI_ID 7
570#define ASC_DEF_ISA_DMA_SPEED 4
1da177e4
LT
571#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
572#define ASC_INIT_STATE_END_GET_CFG 0x0002
573#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
574#define ASC_INIT_STATE_END_SET_CFG 0x0008
575#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
576#define ASC_INIT_STATE_END_LOAD_MC 0x0020
577#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
578#define ASC_INIT_STATE_END_INQUIRY 0x0080
579#define ASC_INIT_RESET_SCSI_DONE 0x0100
580#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
581#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
582#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
583#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
584#define ASC_MIN_TAGGED_CMD 7
585#define ASC_MAX_SCSI_RESET_WAIT 30
586
27c868c2 587struct asc_dvc_var; /* Forward Declaration. */
1da177e4 588
1da177e4 589typedef struct asc_dvc_var {
27c868c2
MW
590 PortAddr iop_base;
591 ushort err_code;
592 ushort dvc_cntl;
593 ushort bug_fix_cntl;
594 ushort bus_type;
27c868c2
MW
595 ASC_SCSI_BIT_ID_TYPE init_sdtr;
596 ASC_SCSI_BIT_ID_TYPE sdtr_done;
597 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
598 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
599 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
600 ASC_SCSI_BIT_ID_TYPE start_motor;
601 uchar scsi_reset_wait;
602 uchar chip_no;
603 char is_in_int;
604 uchar max_total_qng;
605 uchar cur_total_qng;
606 uchar in_critical_cnt;
607 uchar irq_no;
608 uchar last_q_shortage;
609 ushort init_state;
610 uchar cur_dvc_qng[ASC_MAX_TID + 1];
611 uchar max_dvc_qng[ASC_MAX_TID + 1];
612 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
613 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
614 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
615 ASC_DVC_CFG *cfg;
616 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
617 char redo_scam;
618 ushort res2;
619 uchar dos_int13_table[ASC_MAX_TID + 1];
620 ASC_DCNT max_dma_count;
621 ASC_SCSI_BIT_ID_TYPE no_scam;
622 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
623 uchar max_sdtr_index;
624 uchar host_init_sdtr_index;
625 struct asc_board *drv_ptr;
626 ASC_DCNT uc_break;
1da177e4
LT
627} ASC_DVC_VAR;
628
629typedef struct asc_dvc_inq_info {
27c868c2 630 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
631} ASC_DVC_INQ_INFO;
632
633typedef struct asc_cap_info {
27c868c2
MW
634 ASC_DCNT lba;
635 ASC_DCNT blk_size;
1da177e4
LT
636} ASC_CAP_INFO;
637
638typedef struct asc_cap_info_array {
27c868c2 639 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
640} ASC_CAP_INFO_ARRAY;
641
642#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
643#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
644#define ASC_CNTL_INITIATOR (ushort)0x0001
645#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
646#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
647#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
648#define ASC_CNTL_NO_SCAM (ushort)0x0010
649#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
650#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
651#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
652#define ASC_CNTL_RESET_SCSI (ushort)0x0200
653#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
654#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
655#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
656#define ASC_CNTL_BURST_MODE (ushort)0x2000
657#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
658#define ASC_EEP_DVC_CFG_BEG_VL 2
659#define ASC_EEP_MAX_DVC_ADDR_VL 15
660#define ASC_EEP_DVC_CFG_BEG 32
661#define ASC_EEP_MAX_DVC_ADDR 45
1da177e4 662#define ASC_EEP_MAX_RETRY 20
1da177e4
LT
663
664/*
665 * These macros keep the chip SCSI id and ISA DMA speed
666 * bitfields in board order. C bitfields aren't portable
667 * between big and little-endian platforms so they are
668 * not used.
669 */
670
671#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
672#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
673#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
674 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
675#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
676 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
677
678typedef struct asceep_config {
27c868c2
MW
679 ushort cfg_lsw;
680 ushort cfg_msw;
681 uchar init_sdtr;
682 uchar disc_enable;
683 uchar use_cmd_qng;
684 uchar start_motor;
685 uchar max_total_qng;
686 uchar max_tag_qng;
687 uchar bios_scan;
688 uchar power_up_wait;
689 uchar no_scam;
690 uchar id_speed; /* low order 4 bits is chip scsi id */
691 /* high order 4 bits is isa dma speed */
692 uchar dos_int13_table[ASC_MAX_TID + 1];
693 uchar adapter_info[6];
694 ushort cntl;
695 ushort chksum;
1da177e4
LT
696} ASCEEP_CONFIG;
697
1da177e4
LT
698#define ASC_EEP_CMD_READ 0x80
699#define ASC_EEP_CMD_WRITE 0x40
700#define ASC_EEP_CMD_WRITE_ABLE 0x30
701#define ASC_EEP_CMD_WRITE_DISABLE 0x00
702#define ASC_OVERRUN_BSIZE 0x00000048UL
1da177e4
LT
703#define ASCV_MSGOUT_BEG 0x0000
704#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
705#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
706#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
707#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
708#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
709#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
710#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
711#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
712#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
713#define ASCV_BREAK_ADDR (ushort)0x0028
714#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
715#define ASCV_BREAK_CONTROL (ushort)0x002C
716#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
717
718#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
719#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
720#define ASCV_MCODE_SIZE_W (ushort)0x0034
721#define ASCV_STOP_CODE_B (ushort)0x0036
722#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
723#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
724#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
725#define ASCV_HALTCODE_W (ushort)0x0040
726#define ASCV_CHKSUM_W (ushort)0x0042
727#define ASCV_MC_DATE_W (ushort)0x0044
728#define ASCV_MC_VER_W (ushort)0x0046
729#define ASCV_NEXTRDY_B (ushort)0x0048
730#define ASCV_DONENEXT_B (ushort)0x0049
731#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
732#define ASCV_SCSIBUSY_B (ushort)0x004B
733#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
734#define ASCV_CURCDB_B (ushort)0x004D
735#define ASCV_RCLUN_B (ushort)0x004E
736#define ASCV_BUSY_QHEAD_B (ushort)0x004F
737#define ASCV_DISC1_QHEAD_B (ushort)0x0050
738#define ASCV_DISC_ENABLE_B (ushort)0x0052
739#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
740#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
741#define ASCV_MCODE_CNTL_B (ushort)0x0056
742#define ASCV_NULL_TARGET_B (ushort)0x0057
743#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
744#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
745#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
746#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
747#define ASCV_HOST_FLAG_B (ushort)0x005D
748#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
749#define ASCV_VER_SERIAL_B (ushort)0x0065
750#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
751#define ASCV_WTM_FLAG_B (ushort)0x0068
752#define ASCV_RISC_FLAG_B (ushort)0x006A
753#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
754#define ASC_HOST_FLAG_IN_ISR 0x01
755#define ASC_HOST_FLAG_ACK_INT 0x02
756#define ASC_RISC_FLAG_GEN_INT 0x01
757#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
758#define IOP_CTRL (0x0F)
759#define IOP_STATUS (0x0E)
760#define IOP_INT_ACK IOP_STATUS
761#define IOP_REG_IFC (0x0D)
762#define IOP_SYN_OFFSET (0x0B)
763#define IOP_EXTRA_CONTROL (0x0D)
764#define IOP_REG_PC (0x0C)
765#define IOP_RAM_ADDR (0x0A)
766#define IOP_RAM_DATA (0x08)
767#define IOP_EEP_DATA (0x06)
768#define IOP_EEP_CMD (0x07)
769#define IOP_VERSION (0x03)
770#define IOP_CONFIG_HIGH (0x04)
771#define IOP_CONFIG_LOW (0x02)
772#define IOP_SIG_BYTE (0x01)
773#define IOP_SIG_WORD (0x00)
774#define IOP_REG_DC1 (0x0E)
775#define IOP_REG_DC0 (0x0C)
776#define IOP_REG_SB (0x0B)
777#define IOP_REG_DA1 (0x0A)
778#define IOP_REG_DA0 (0x08)
779#define IOP_REG_SC (0x09)
780#define IOP_DMA_SPEED (0x07)
781#define IOP_REG_FLAG (0x07)
782#define IOP_FIFO_H (0x06)
783#define IOP_FIFO_L (0x04)
784#define IOP_REG_ID (0x05)
785#define IOP_REG_QP (0x03)
786#define IOP_REG_IH (0x02)
787#define IOP_REG_IX (0x01)
788#define IOP_REG_AX (0x00)
789#define IFC_REG_LOCK (0x00)
790#define IFC_REG_UNLOCK (0x09)
791#define IFC_WR_EN_FILTER (0x10)
792#define IFC_RD_NO_EEPROM (0x10)
793#define IFC_SLEW_RATE (0x20)
794#define IFC_ACT_NEG (0x40)
795#define IFC_INP_FILTER (0x80)
796#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
797#define SC_SEL (uchar)(0x80)
798#define SC_BSY (uchar)(0x40)
799#define SC_ACK (uchar)(0x20)
800#define SC_REQ (uchar)(0x10)
801#define SC_ATN (uchar)(0x08)
802#define SC_IO (uchar)(0x04)
803#define SC_CD (uchar)(0x02)
804#define SC_MSG (uchar)(0x01)
805#define SEC_SCSI_CTL (uchar)(0x80)
806#define SEC_ACTIVE_NEGATE (uchar)(0x40)
807#define SEC_SLEW_RATE (uchar)(0x20)
808#define SEC_ENABLE_FILTER (uchar)(0x10)
809#define ASC_HALT_EXTMSG_IN (ushort)0x8000
810#define ASC_HALT_CHK_CONDITION (ushort)0x8100
811#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
812#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
813#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
814#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
815#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
816#define ASC_MAX_QNO 0xF8
817#define ASC_DATA_SEC_BEG (ushort)0x0080
818#define ASC_DATA_SEC_END (ushort)0x0080
819#define ASC_CODE_SEC_BEG (ushort)0x0080
820#define ASC_CODE_SEC_END (ushort)0x0080
821#define ASC_QADR_BEG (0x4000)
822#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
823#define ASC_QADR_END (ushort)0x7FFF
824#define ASC_QLAST_ADR (ushort)0x7FC0
825#define ASC_QBLK_SIZE 0x40
826#define ASC_BIOS_DATA_QBEG 0xF8
827#define ASC_MIN_ACTIVE_QNO 0x01
828#define ASC_QLINK_END 0xFF
829#define ASC_EEPROM_WORDS 0x10
830#define ASC_MAX_MGS_LEN 0x10
831#define ASC_BIOS_ADDR_DEF 0xDC00
832#define ASC_BIOS_SIZE 0x3800
833#define ASC_BIOS_RAM_OFF 0x3800
834#define ASC_BIOS_RAM_SIZE 0x800
835#define ASC_BIOS_MIN_ADDR 0xC000
836#define ASC_BIOS_MAX_ADDR 0xEC00
837#define ASC_BIOS_BANK_SIZE 0x0400
838#define ASC_MCODE_START_ADDR 0x0080
839#define ASC_CFG0_HOST_INT_ON 0x0020
840#define ASC_CFG0_BIOS_ON 0x0040
841#define ASC_CFG0_VERA_BURST_ON 0x0080
842#define ASC_CFG0_SCSI_PARITY_ON 0x0800
843#define ASC_CFG1_SCSI_TARGET_ON 0x0080
844#define ASC_CFG1_LRAM_8BITS_ON 0x0800
845#define ASC_CFG_MSW_CLR_MASK 0x3080
846#define CSW_TEST1 (ASC_CS_TYPE)0x8000
847#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
848#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
849#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
850#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
851#define CSW_TEST2 (ASC_CS_TYPE)0x0400
852#define CSW_TEST3 (ASC_CS_TYPE)0x0200
853#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
854#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
855#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
856#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
857#define CSW_HALTED (ASC_CS_TYPE)0x0010
858#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
859#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
860#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
861#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
862#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
863#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
864#define CIW_TEST1 (ASC_CS_TYPE)0x0200
865#define CIW_TEST2 (ASC_CS_TYPE)0x0400
866#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
867#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
868#define CC_CHIP_RESET (uchar)0x80
869#define CC_SCSI_RESET (uchar)0x40
870#define CC_HALT (uchar)0x20
871#define CC_SINGLE_STEP (uchar)0x10
872#define CC_DMA_ABLE (uchar)0x08
873#define CC_TEST (uchar)0x04
874#define CC_BANK_ONE (uchar)0x02
875#define CC_DIAG (uchar)0x01
876#define ASC_1000_ID0W 0x04C1
877#define ASC_1000_ID0W_FIX 0x00C1
878#define ASC_1000_ID1B 0x25
1da177e4
LT
879#define ASC_EISA_REV_IOP_MASK (0x0C83)
880#define ASC_EISA_PID_IOP_MASK (0x0C80)
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)
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));
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
27c868c2
MW
964static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
965static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
966static void AscWaitEEPRead(void);
967static void AscWaitEEPWrite(void);
968static ushort AscReadEEPWord(PortAddr, uchar);
969static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
970static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
971static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
972static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
973static int AscStartChip(PortAddr);
974static int AscStopChip(PortAddr);
975static void AscSetChipIH(PortAddr, ushort);
976static int AscIsChipHalted(PortAddr);
977static void AscAckInterrupt(PortAddr);
978static void AscDisableInterrupt(PortAddr);
979static void AscEnableInterrupt(PortAddr);
980static void AscSetBank(PortAddr, uchar);
981static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 982#ifdef CONFIG_ISA
27c868c2 983static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 984#endif /* CONFIG_ISA */
27c868c2
MW
985static uchar AscReadLramByte(PortAddr, ushort);
986static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 987#if CC_VERY_LONG_SG_LIST
27c868c2 988static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 989#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
990static void AscWriteLramWord(PortAddr, ushort, ushort);
991static void AscWriteLramByte(PortAddr, ushort, uchar);
992static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
993static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
994static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
995static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
996static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
997static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
998static ushort AscInitFromEEP(ASC_DVC_VAR *);
27c868c2
MW
999static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1000static int AscTestExternalLram(ASC_DVC_VAR *);
1001static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1002static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1003static void AscSetChipSDTR(PortAddr, uchar, uchar);
1004static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1005static uchar AscAllocFreeQueue(PortAddr, uchar);
1006static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1007static int AscHostReqRiscHalt(PortAddr);
1008static int AscStopQueueExe(PortAddr);
1009static int AscSendScsiQueue(ASC_DVC_VAR *,
1010 ASC_SCSI_Q *scsiq, uchar n_q_required);
1011static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1012static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1013static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1014static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1015static ushort AscInitLram(ASC_DVC_VAR *);
27c868c2
MW
1016static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1017static int AscIsrChipHalted(ASC_DVC_VAR *);
1018static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1019 ASC_QDONE_INFO *, ASC_DCNT);
1020static int AscIsrQDone(ASC_DVC_VAR *);
1da177e4 1021#ifdef CONFIG_ISA
27c868c2 1022static ushort AscGetEisaChipCfg(PortAddr);
1da177e4 1023#endif /* CONFIG_ISA */
27c868c2 1024static uchar AscGetChipScsiCtrl(PortAddr);
27c868c2 1025static uchar AscGetChipVersion(PortAddr, ushort);
27c868c2 1026static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
27c868c2 1027static void AscToggleIRQAct(PortAddr);
27c868c2
MW
1028static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1029static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
27c868c2 1030static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
47d853cc 1031static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
27c868c2
MW
1032static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1033static int AscISR(ASC_DVC_VAR *);
1034static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1035static int AscSgListToQueue(int);
1da177e4 1036#ifdef CONFIG_ISA
27c868c2 1037static void AscEnableIsaDma(uchar);
1da177e4 1038#endif /* CONFIG_ISA */
27c868c2 1039static const char *advansys_info(struct Scsi_Host *shost);
1da177e4 1040
1da177e4
LT
1041#define ADV_LIB_VERSION_MAJOR 5
1042#define ADV_LIB_VERSION_MINOR 14
1043
1044/*
1045 * Define Adv Library required special types.
1046 */
1047
1048/*
1049 * Portable Data Types
1050 *
1051 * Any instance where a 32-bit long or pointer type is assumed
1052 * for precision or HW defined structures, the following define
1053 * types must be used. In Linux the char, short, and int types
1054 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1055 * and long types are 64 bits on Alpha and UltraSPARC.
1056 */
27c868c2
MW
1057#define ADV_PADDR __u32 /* Physical address data type. */
1058#define ADV_VADDR __u32 /* Virtual address data type. */
1059#define ADV_DCNT __u32 /* Unsigned Data count type. */
1060#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
1061
1062/*
1063 * These macros are used to convert a virtual address to a
1064 * 32-bit value. This currently can be used on Linux Alpha
1065 * which uses 64-bit virtual address but a 32-bit bus address.
1066 * This is likely to break in the future, but doing this now
1067 * will give us time to change the HW and FW to handle 64-bit
1068 * addresses.
1069 */
1070#define ADV_VADDR_TO_U32 virt_to_bus
1071#define ADV_U32_TO_VADDR bus_to_virt
1072
27c868c2 1073#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
1074
1075/*
1076 * Define Adv Library required memory access macros.
1077 */
1078#define ADV_MEM_READB(addr) readb(addr)
1079#define ADV_MEM_READW(addr) readw(addr)
1080#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1081#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1082#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1083
1084#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1085
1da177e4
LT
1086/*
1087 * Define total number of simultaneous maximum element scatter-gather
1088 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1089 * maximum number of outstanding commands per wide host adapter. Each
1090 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1091 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1092 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1093 * structures or 255 scatter-gather elements.
1094 *
1095 */
1096#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1097
1098/*
1099 * Define Adv Library required maximum number of scatter-gather
1100 * elements per request.
1101 */
1102#define ADV_MAX_SG_LIST 255
1103
1104/* Number of SG blocks needed. */
1105#define ADV_NUM_SG_BLOCK \
1106 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1107
1108/* Total contiguous memory needed for SG blocks. */
1109#define ADV_SG_TOTAL_MEM_SIZE \
1110 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1111
1112#define ADV_PAGE_SIZE PAGE_SIZE
1113
1114#define ADV_NUM_PAGE_CROSSING \
1115 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1116
1da177e4
LT
1117#define ADV_EEP_DVC_CFG_BEGIN (0x00)
1118#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 1119#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
1120#define ADV_EEP_MAX_WORD_ADDR (0x1E)
1121
1122#define ADV_EEP_DELAY_MS 100
1123
27c868c2
MW
1124#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1125#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
1126/*
1127 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1128 * For later ICs Bit 13 controls whether the CIS (Card Information
1129 * Service Section) is loaded from EEPROM.
1130 */
27c868c2
MW
1131#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1132#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
1133/*
1134 * ASC38C1600 Bit 11
1135 *
1136 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1137 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1138 * Function 0 will specify INT B.
1139 *
1140 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1141 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1142 * Function 1 will specify INT A.
1143 */
27c868c2
MW
1144#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1145
1146typedef struct adveep_3550_config {
1147 /* Word Offset, Description */
1148
1149 ushort cfg_lsw; /* 00 power up initialization */
1150 /* bit 13 set - Term Polarity Control */
1151 /* bit 14 set - BIOS Enable */
1152 /* bit 15 set - Big Endian Mode */
1153 ushort cfg_msw; /* 01 unused */
1154 ushort disc_enable; /* 02 disconnect enable */
1155 ushort wdtr_able; /* 03 Wide DTR able */
1156 ushort sdtr_able; /* 04 Synchronous DTR able */
1157 ushort start_motor; /* 05 send start up motor */
1158 ushort tagqng_able; /* 06 tag queuing able */
1159 ushort bios_scan; /* 07 BIOS device control */
1160 ushort scam_tolerant; /* 08 no scam */
1161
1162 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1163 uchar bios_boot_delay; /* power up wait */
1164
1165 uchar scsi_reset_delay; /* 10 reset delay */
1166 uchar bios_id_lun; /* first boot device scsi id & lun */
1167 /* high nibble is lun */
1168 /* low nibble is scsi id */
1169
1170 uchar termination; /* 11 0 - automatic */
1171 /* 1 - low off / high off */
1172 /* 2 - low off / high on */
1173 /* 3 - low on / high on */
1174 /* There is no low on / high off */
1175
1176 uchar reserved1; /* reserved byte (not used) */
1177
1178 ushort bios_ctrl; /* 12 BIOS control bits */
1179 /* bit 0 BIOS don't act as initiator. */
1180 /* bit 1 BIOS > 1 GB support */
1181 /* bit 2 BIOS > 2 Disk Support */
1182 /* bit 3 BIOS don't support removables */
1183 /* bit 4 BIOS support bootable CD */
1184 /* bit 5 BIOS scan enabled */
1185 /* bit 6 BIOS support multiple LUNs */
1186 /* bit 7 BIOS display of message */
1187 /* bit 8 SCAM disabled */
1188 /* bit 9 Reset SCSI bus during init. */
1189 /* bit 10 */
1190 /* bit 11 No verbose initialization. */
1191 /* bit 12 SCSI parity enabled */
1192 /* bit 13 */
1193 /* bit 14 */
1194 /* bit 15 */
1195 ushort ultra_able; /* 13 ULTRA speed able */
1196 ushort reserved2; /* 14 reserved */
1197 uchar max_host_qng; /* 15 maximum host queuing */
1198 uchar max_dvc_qng; /* maximum per device queuing */
1199 ushort dvc_cntl; /* 16 control bit for driver */
1200 ushort bug_fix; /* 17 control bit for bug fix */
1201 ushort serial_number_word1; /* 18 Board serial number word 1 */
1202 ushort serial_number_word2; /* 19 Board serial number word 2 */
1203 ushort serial_number_word3; /* 20 Board serial number word 3 */
1204 ushort check_sum; /* 21 EEP check sum */
1205 uchar oem_name[16]; /* 22 OEM name */
1206 ushort dvc_err_code; /* 30 last device driver error code */
1207 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1208 ushort adv_err_addr; /* 32 last uc error address */
1209 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1210 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1211 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1212 ushort num_of_err; /* 36 number of error */
1da177e4
LT
1213} ADVEEP_3550_CONFIG;
1214
27c868c2
MW
1215typedef struct adveep_38C0800_config {
1216 /* Word Offset, Description */
1217
1218 ushort cfg_lsw; /* 00 power up initialization */
1219 /* bit 13 set - Load CIS */
1220 /* bit 14 set - BIOS Enable */
1221 /* bit 15 set - Big Endian Mode */
1222 ushort cfg_msw; /* 01 unused */
1223 ushort disc_enable; /* 02 disconnect enable */
1224 ushort wdtr_able; /* 03 Wide DTR able */
1225 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1226 ushort start_motor; /* 05 send start up motor */
1227 ushort tagqng_able; /* 06 tag queuing able */
1228 ushort bios_scan; /* 07 BIOS device control */
1229 ushort scam_tolerant; /* 08 no scam */
1230
1231 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1232 uchar bios_boot_delay; /* power up wait */
1233
1234 uchar scsi_reset_delay; /* 10 reset delay */
1235 uchar bios_id_lun; /* first boot device scsi id & lun */
1236 /* high nibble is lun */
1237 /* low nibble is scsi id */
1238
1239 uchar termination_se; /* 11 0 - automatic */
1240 /* 1 - low off / high off */
1241 /* 2 - low off / high on */
1242 /* 3 - low on / high on */
1243 /* There is no low on / high off */
1244
1245 uchar termination_lvd; /* 11 0 - automatic */
1246 /* 1 - low off / high off */
1247 /* 2 - low off / high on */
1248 /* 3 - low on / high on */
1249 /* There is no low on / high off */
1250
1251 ushort bios_ctrl; /* 12 BIOS control bits */
1252 /* bit 0 BIOS don't act as initiator. */
1253 /* bit 1 BIOS > 1 GB support */
1254 /* bit 2 BIOS > 2 Disk Support */
1255 /* bit 3 BIOS don't support removables */
1256 /* bit 4 BIOS support bootable CD */
1257 /* bit 5 BIOS scan enabled */
1258 /* bit 6 BIOS support multiple LUNs */
1259 /* bit 7 BIOS display of message */
1260 /* bit 8 SCAM disabled */
1261 /* bit 9 Reset SCSI bus during init. */
1262 /* bit 10 */
1263 /* bit 11 No verbose initialization. */
1264 /* bit 12 SCSI parity enabled */
1265 /* bit 13 */
1266 /* bit 14 */
1267 /* bit 15 */
1268 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1269 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1270 uchar max_host_qng; /* 15 maximum host queueing */
1271 uchar max_dvc_qng; /* maximum per device queuing */
1272 ushort dvc_cntl; /* 16 control bit for driver */
1273 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1274 ushort serial_number_word1; /* 18 Board serial number word 1 */
1275 ushort serial_number_word2; /* 19 Board serial number word 2 */
1276 ushort serial_number_word3; /* 20 Board serial number word 3 */
1277 ushort check_sum; /* 21 EEP check sum */
1278 uchar oem_name[16]; /* 22 OEM name */
1279 ushort dvc_err_code; /* 30 last device driver error code */
1280 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1281 ushort adv_err_addr; /* 32 last uc error address */
1282 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1283 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1284 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1285 ushort reserved36; /* 36 reserved */
1286 ushort reserved37; /* 37 reserved */
1287 ushort reserved38; /* 38 reserved */
1288 ushort reserved39; /* 39 reserved */
1289 ushort reserved40; /* 40 reserved */
1290 ushort reserved41; /* 41 reserved */
1291 ushort reserved42; /* 42 reserved */
1292 ushort reserved43; /* 43 reserved */
1293 ushort reserved44; /* 44 reserved */
1294 ushort reserved45; /* 45 reserved */
1295 ushort reserved46; /* 46 reserved */
1296 ushort reserved47; /* 47 reserved */
1297 ushort reserved48; /* 48 reserved */
1298 ushort reserved49; /* 49 reserved */
1299 ushort reserved50; /* 50 reserved */
1300 ushort reserved51; /* 51 reserved */
1301 ushort reserved52; /* 52 reserved */
1302 ushort reserved53; /* 53 reserved */
1303 ushort reserved54; /* 54 reserved */
1304 ushort reserved55; /* 55 reserved */
1305 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1306 ushort cisprt_msw; /* 57 CIS PTR MSW */
1307 ushort subsysvid; /* 58 SubSystem Vendor ID */
1308 ushort subsysid; /* 59 SubSystem ID */
1309 ushort reserved60; /* 60 reserved */
1310 ushort reserved61; /* 61 reserved */
1311 ushort reserved62; /* 62 reserved */
1312 ushort reserved63; /* 63 reserved */
1da177e4
LT
1313} ADVEEP_38C0800_CONFIG;
1314
27c868c2
MW
1315typedef struct adveep_38C1600_config {
1316 /* Word Offset, Description */
1317
1318 ushort cfg_lsw; /* 00 power up initialization */
1319 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1320 /* clear - Func. 0 INTA, Func. 1 INTB */
1321 /* bit 13 set - Load CIS */
1322 /* bit 14 set - BIOS Enable */
1323 /* bit 15 set - Big Endian Mode */
1324 ushort cfg_msw; /* 01 unused */
1325 ushort disc_enable; /* 02 disconnect enable */
1326 ushort wdtr_able; /* 03 Wide DTR able */
1327 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1328 ushort start_motor; /* 05 send start up motor */
1329 ushort tagqng_able; /* 06 tag queuing able */
1330 ushort bios_scan; /* 07 BIOS device control */
1331 ushort scam_tolerant; /* 08 no scam */
1332
1333 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1334 uchar bios_boot_delay; /* power up wait */
1335
1336 uchar scsi_reset_delay; /* 10 reset delay */
1337 uchar bios_id_lun; /* first boot device scsi id & lun */
1338 /* high nibble is lun */
1339 /* low nibble is scsi id */
1340
1341 uchar termination_se; /* 11 0 - automatic */
1342 /* 1 - low off / high off */
1343 /* 2 - low off / high on */
1344 /* 3 - low on / high on */
1345 /* There is no low on / high off */
1346
1347 uchar termination_lvd; /* 11 0 - automatic */
1348 /* 1 - low off / high off */
1349 /* 2 - low off / high on */
1350 /* 3 - low on / high on */
1351 /* There is no low on / high off */
1352
1353 ushort bios_ctrl; /* 12 BIOS control bits */
1354 /* bit 0 BIOS don't act as initiator. */
1355 /* bit 1 BIOS > 1 GB support */
1356 /* bit 2 BIOS > 2 Disk Support */
1357 /* bit 3 BIOS don't support removables */
1358 /* bit 4 BIOS support bootable CD */
1359 /* bit 5 BIOS scan enabled */
1360 /* bit 6 BIOS support multiple LUNs */
1361 /* bit 7 BIOS display of message */
1362 /* bit 8 SCAM disabled */
1363 /* bit 9 Reset SCSI bus during init. */
1364 /* bit 10 Basic Integrity Checking disabled */
1365 /* bit 11 No verbose initialization. */
1366 /* bit 12 SCSI parity enabled */
1367 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1368 /* bit 14 */
1369 /* bit 15 */
1370 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1371 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1372 uchar max_host_qng; /* 15 maximum host queueing */
1373 uchar max_dvc_qng; /* maximum per device queuing */
1374 ushort dvc_cntl; /* 16 control bit for driver */
1375 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1376 ushort serial_number_word1; /* 18 Board serial number word 1 */
1377 ushort serial_number_word2; /* 19 Board serial number word 2 */
1378 ushort serial_number_word3; /* 20 Board serial number word 3 */
1379 ushort check_sum; /* 21 EEP check sum */
1380 uchar oem_name[16]; /* 22 OEM name */
1381 ushort dvc_err_code; /* 30 last device driver error code */
1382 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1383 ushort adv_err_addr; /* 32 last uc error address */
1384 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1385 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1386 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1387 ushort reserved36; /* 36 reserved */
1388 ushort reserved37; /* 37 reserved */
1389 ushort reserved38; /* 38 reserved */
1390 ushort reserved39; /* 39 reserved */
1391 ushort reserved40; /* 40 reserved */
1392 ushort reserved41; /* 41 reserved */
1393 ushort reserved42; /* 42 reserved */
1394 ushort reserved43; /* 43 reserved */
1395 ushort reserved44; /* 44 reserved */
1396 ushort reserved45; /* 45 reserved */
1397 ushort reserved46; /* 46 reserved */
1398 ushort reserved47; /* 47 reserved */
1399 ushort reserved48; /* 48 reserved */
1400 ushort reserved49; /* 49 reserved */
1401 ushort reserved50; /* 50 reserved */
1402 ushort reserved51; /* 51 reserved */
1403 ushort reserved52; /* 52 reserved */
1404 ushort reserved53; /* 53 reserved */
1405 ushort reserved54; /* 54 reserved */
1406 ushort reserved55; /* 55 reserved */
1407 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1408 ushort cisprt_msw; /* 57 CIS PTR MSW */
1409 ushort subsysvid; /* 58 SubSystem Vendor ID */
1410 ushort subsysid; /* 59 SubSystem ID */
1411 ushort reserved60; /* 60 reserved */
1412 ushort reserved61; /* 61 reserved */
1413 ushort reserved62; /* 62 reserved */
1414 ushort reserved63; /* 63 reserved */
1da177e4
LT
1415} ADVEEP_38C1600_CONFIG;
1416
1417/*
1418 * EEPROM Commands
1419 */
1420#define ASC_EEP_CMD_DONE 0x0200
1da177e4
LT
1421
1422/* bios_ctrl */
1423#define BIOS_CTRL_BIOS 0x0001
1424#define BIOS_CTRL_EXTENDED_XLAT 0x0002
1425#define BIOS_CTRL_GT_2_DISK 0x0004
1426#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1427#define BIOS_CTRL_BOOTABLE_CD 0x0010
1428#define BIOS_CTRL_MULTIPLE_LUN 0x0040
1429#define BIOS_CTRL_DISPLAY_MSG 0x0080
1430#define BIOS_CTRL_NO_SCAM 0x0100
1431#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1432#define BIOS_CTRL_INIT_VERBOSE 0x0800
1433#define BIOS_CTRL_SCSI_PARITY 0x1000
1434#define BIOS_CTRL_AIPP_DIS 0x2000
1435
27c868c2 1436#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1da177e4 1437
27c868c2 1438#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1439
1440/*
1441 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1442 * a special 16K Adv Library and Microcode version. After the issue is
1443 * resolved, should restore 32K support.
1444 *
1445 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1446 */
27c868c2 1447#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1448
1449/*
1450 * Byte I/O register address from base of 'iop_base'.
1451 */
1452#define IOPB_INTR_STATUS_REG 0x00
1453#define IOPB_CHIP_ID_1 0x01
1454#define IOPB_INTR_ENABLES 0x02
1455#define IOPB_CHIP_TYPE_REV 0x03
1456#define IOPB_RES_ADDR_4 0x04
1457#define IOPB_RES_ADDR_5 0x05
1458#define IOPB_RAM_DATA 0x06
1459#define IOPB_RES_ADDR_7 0x07
1460#define IOPB_FLAG_REG 0x08
1461#define IOPB_RES_ADDR_9 0x09
1462#define IOPB_RISC_CSR 0x0A
1463#define IOPB_RES_ADDR_B 0x0B
1464#define IOPB_RES_ADDR_C 0x0C
1465#define IOPB_RES_ADDR_D 0x0D
1466#define IOPB_SOFT_OVER_WR 0x0E
1467#define IOPB_RES_ADDR_F 0x0F
1468#define IOPB_MEM_CFG 0x10
1469#define IOPB_RES_ADDR_11 0x11
1470#define IOPB_GPIO_DATA 0x12
1471#define IOPB_RES_ADDR_13 0x13
1472#define IOPB_FLASH_PAGE 0x14
1473#define IOPB_RES_ADDR_15 0x15
1474#define IOPB_GPIO_CNTL 0x16
1475#define IOPB_RES_ADDR_17 0x17
1476#define IOPB_FLASH_DATA 0x18
1477#define IOPB_RES_ADDR_19 0x19
1478#define IOPB_RES_ADDR_1A 0x1A
1479#define IOPB_RES_ADDR_1B 0x1B
1480#define IOPB_RES_ADDR_1C 0x1C
1481#define IOPB_RES_ADDR_1D 0x1D
1482#define IOPB_RES_ADDR_1E 0x1E
1483#define IOPB_RES_ADDR_1F 0x1F
1484#define IOPB_DMA_CFG0 0x20
1485#define IOPB_DMA_CFG1 0x21
1486#define IOPB_TICKLE 0x22
1487#define IOPB_DMA_REG_WR 0x23
1488#define IOPB_SDMA_STATUS 0x24
1489#define IOPB_SCSI_BYTE_CNT 0x25
1490#define IOPB_HOST_BYTE_CNT 0x26
1491#define IOPB_BYTE_LEFT_TO_XFER 0x27
1492#define IOPB_BYTE_TO_XFER_0 0x28
1493#define IOPB_BYTE_TO_XFER_1 0x29
1494#define IOPB_BYTE_TO_XFER_2 0x2A
1495#define IOPB_BYTE_TO_XFER_3 0x2B
1496#define IOPB_ACC_GRP 0x2C
1497#define IOPB_RES_ADDR_2D 0x2D
1498#define IOPB_DEV_ID 0x2E
1499#define IOPB_RES_ADDR_2F 0x2F
1500#define IOPB_SCSI_DATA 0x30
1501#define IOPB_RES_ADDR_31 0x31
1502#define IOPB_RES_ADDR_32 0x32
1503#define IOPB_SCSI_DATA_HSHK 0x33
1504#define IOPB_SCSI_CTRL 0x34
1505#define IOPB_RES_ADDR_35 0x35
1506#define IOPB_RES_ADDR_36 0x36
1507#define IOPB_RES_ADDR_37 0x37
1508#define IOPB_RAM_BIST 0x38
1509#define IOPB_PLL_TEST 0x39
1510#define IOPB_PCI_INT_CFG 0x3A
1511#define IOPB_RES_ADDR_3B 0x3B
1512#define IOPB_RFIFO_CNT 0x3C
1513#define IOPB_RES_ADDR_3D 0x3D
1514#define IOPB_RES_ADDR_3E 0x3E
1515#define IOPB_RES_ADDR_3F 0x3F
1516
1517/*
1518 * Word I/O register address from base of 'iop_base'.
1519 */
27c868c2
MW
1520#define IOPW_CHIP_ID_0 0x00 /* CID0 */
1521#define IOPW_CTRL_REG 0x02 /* CC */
1522#define IOPW_RAM_ADDR 0x04 /* LA */
1523#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 1524#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
1525#define IOPW_RISC_CSR 0x0A /* CSR */
1526#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1527#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 1528#define IOPW_RES_ADDR_10 0x10
27c868c2 1529#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 1530#define IOPW_RES_ADDR_14 0x14
27c868c2 1531#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 1532#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
1533#define IOPW_EE_CMD 0x1A /* EC */
1534#define IOPW_EE_DATA 0x1C /* ED */
1535#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 1536#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
1537#define IOPW_Q_BASE 0x22 /* QB */
1538#define IOPW_QP 0x24 /* QP */
1539#define IOPW_IX 0x26 /* IX */
1540#define IOPW_SP 0x28 /* SP */
1541#define IOPW_PC 0x2A /* PC */
1da177e4
LT
1542#define IOPW_RES_ADDR_2C 0x2C
1543#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
1544#define IOPW_SCSI_DATA 0x30 /* SD */
1545#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1546#define IOPW_SCSI_CTRL 0x34 /* SC */
1547#define IOPW_HSHK_CFG 0x36 /* HCFG */
1548#define IOPW_SXFR_STATUS 0x36 /* SXS */
1549#define IOPW_SXFR_CNTL 0x38 /* SXL */
1550#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 1551#define IOPW_RES_ADDR_3C 0x3C
27c868c2 1552#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
1553
1554/*
1555 * Doubleword I/O register address from base of 'iop_base'.
1556 */
1557#define IOPDW_RES_ADDR_0 0x00
1558#define IOPDW_RAM_DATA 0x04
1559#define IOPDW_RES_ADDR_8 0x08
1560#define IOPDW_RES_ADDR_C 0x0C
1561#define IOPDW_RES_ADDR_10 0x10
1562#define IOPDW_COMMA 0x14
1563#define IOPDW_COMMB 0x18
1564#define IOPDW_RES_ADDR_1C 0x1C
1565#define IOPDW_SDMA_ADDR0 0x20
1566#define IOPDW_SDMA_ADDR1 0x24
1567#define IOPDW_SDMA_COUNT 0x28
1568#define IOPDW_SDMA_ERROR 0x2C
1569#define IOPDW_RDMA_ADDR0 0x30
1570#define IOPDW_RDMA_ADDR1 0x34
1571#define IOPDW_RDMA_COUNT 0x38
1572#define IOPDW_RDMA_ERROR 0x3C
1573
1574#define ADV_CHIP_ID_BYTE 0x25
1575#define ADV_CHIP_ID_WORD 0x04C1
1576
1da177e4
LT
1577#define ADV_INTR_ENABLE_HOST_INTR 0x01
1578#define ADV_INTR_ENABLE_SEL_INTR 0x02
1579#define ADV_INTR_ENABLE_DPR_INTR 0x04
1580#define ADV_INTR_ENABLE_RTA_INTR 0x08
1581#define ADV_INTR_ENABLE_RMA_INTR 0x10
1582#define ADV_INTR_ENABLE_RST_INTR 0x20
1583#define ADV_INTR_ENABLE_DPE_INTR 0x40
1584#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1585
1586#define ADV_INTR_STATUS_INTRA 0x01
1587#define ADV_INTR_STATUS_INTRB 0x02
1588#define ADV_INTR_STATUS_INTRC 0x04
1589
1590#define ADV_RISC_CSR_STOP (0x0000)
1591#define ADV_RISC_TEST_COND (0x2000)
1592#define ADV_RISC_CSR_RUN (0x4000)
1593#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1594
1595#define ADV_CTRL_REG_HOST_INTR 0x0100
1596#define ADV_CTRL_REG_SEL_INTR 0x0200
1597#define ADV_CTRL_REG_DPR_INTR 0x0400
1598#define ADV_CTRL_REG_RTA_INTR 0x0800
1599#define ADV_CTRL_REG_RMA_INTR 0x1000
1600#define ADV_CTRL_REG_RES_BIT14 0x2000
1601#define ADV_CTRL_REG_DPE_INTR 0x4000
1602#define ADV_CTRL_REG_POWER_DONE 0x8000
1603#define ADV_CTRL_REG_ANY_INTR 0xFF00
1604
1605#define ADV_CTRL_REG_CMD_RESET 0x00C6
1606#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1607#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1608#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1609#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1610
1611#define ADV_TICKLE_NOP 0x00
1612#define ADV_TICKLE_A 0x01
1613#define ADV_TICKLE_B 0x02
1614#define ADV_TICKLE_C 0x03
1615
1da177e4
LT
1616#define AdvIsIntPending(port) \
1617 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1618
1619/*
1620 * SCSI_CFG0 Register bit definitions
1621 */
27c868c2
MW
1622#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1623#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1624#define EVEN_PARITY 0x1000 /* Select Even Parity */
1625#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1626#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1627#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1628#define SCAM_EN 0x0080 /* Enable SCAM selection */
1629#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1630#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1631#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1632#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
1633
1634/*
1635 * SCSI_CFG1 Register bit definitions
1636 */
27c868c2
MW
1637#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1638#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1639#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1640#define FILTER_SEL 0x0C00 /* Filter Period Selection */
1641#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1642#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1643#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1644#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1645#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1646#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1647#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1648#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1649#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1650#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1651#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
1652
1653/*
1654 * Addendum for ASC-38C0800 Chip
1655 *
1656 * The ASC-38C1600 Chip uses the same definitions except that the
1657 * bus mode override bits [12:10] have been moved to byte register
1658 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1659 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1660 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1661 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1662 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1663 */
27c868c2
MW
1664#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1665#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1666#define HVD 0x1000 /* HVD Device Detect */
1667#define LVD 0x0800 /* LVD Device Detect */
1668#define SE 0x0400 /* SE Device Detect */
1669#define TERM_LVD 0x00C0 /* LVD Termination Bits */
1670#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1671#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1672#define TERM_SE 0x0030 /* SE Termination Bits */
1673#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1674#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1675#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1676#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1677#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1678#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1679#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1680#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
1681
1682#define CABLE_ILLEGAL_A 0x7
1683 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1684
1685#define CABLE_ILLEGAL_B 0xB
1686 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1687
1688/*
1689 * MEM_CFG Register bit definitions
1690 */
27c868c2
MW
1691#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1692#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1693#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1694#define RAM_SZ_2KB 0x00 /* 2 KB */
1695#define RAM_SZ_4KB 0x04 /* 4 KB */
1696#define RAM_SZ_8KB 0x08 /* 8 KB */
1697#define RAM_SZ_16KB 0x0C /* 16 KB */
1698#define RAM_SZ_32KB 0x10 /* 32 KB */
1699#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
1700
1701/*
1702 * DMA_CFG0 Register bit definitions
1703 *
1704 * This register is only accessible to the host.
1705 */
27c868c2
MW
1706#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1707#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1708#define FIFO_THRESH_16B 0x00 /* 16 bytes */
1709#define FIFO_THRESH_32B 0x20 /* 32 bytes */
1710#define FIFO_THRESH_48B 0x30 /* 48 bytes */
1711#define FIFO_THRESH_64B 0x40 /* 64 bytes */
1712#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1713#define FIFO_THRESH_96B 0x60 /* 96 bytes */
1714#define FIFO_THRESH_112B 0x70 /* 112 bytes */
1715#define START_CTL 0x0C /* DMA start conditions */
1716#define START_CTL_TH 0x00 /* Wait threshold level (default) */
1717#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1718#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1719#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1720#define READ_CMD 0x03 /* Memory Read Method */
1721#define READ_CMD_MR 0x00 /* Memory Read */
1722#define READ_CMD_MRL 0x02 /* Memory Read Long */
1723#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
1724
1725/*
1726 * ASC-38C0800 RAM BIST Register bit definitions
1727 */
1728#define RAM_TEST_MODE 0x80
1729#define PRE_TEST_MODE 0x40
1730#define NORMAL_MODE 0x00
1731#define RAM_TEST_DONE 0x10
1732#define RAM_TEST_STATUS 0x0F
1733#define RAM_TEST_HOST_ERROR 0x08
1734#define RAM_TEST_INTRAM_ERROR 0x04
1735#define RAM_TEST_RISC_ERROR 0x02
1736#define RAM_TEST_SCSI_ERROR 0x01
1737#define RAM_TEST_SUCCESS 0x00
1738#define PRE_TEST_VALUE 0x05
1739#define NORMAL_VALUE 0x00
1740
1741/*
1742 * ASC38C1600 Definitions
1743 *
1744 * IOPB_PCI_INT_CFG Bit Field Definitions
1745 */
1746
27c868c2 1747#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
1748
1749/*
1750 * Bit 1 can be set to change the interrupt for the Function to operate in
1751 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1752 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1753 * mode, otherwise the operating mode is undefined.
1754 */
1755#define TOTEMPOLE 0x02
1756
1757/*
1758 * Bit 0 can be used to change the Int Pin for the Function. The value is
1759 * 0 by default for both Functions with Function 0 using INT A and Function
1760 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1761 * INT A is used.
1762 *
1763 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1764 * value specified in the PCI Configuration Space.
1765 */
1766#define INTAB 0x01
1767
1da177e4
LT
1768/*
1769 * Adv Library Status Definitions
1770 */
1771#define ADV_TRUE 1
1772#define ADV_FALSE 0
1da177e4
LT
1773#define ADV_SUCCESS 1
1774#define ADV_BUSY 0
1775#define ADV_ERROR (-1)
1776
1da177e4
LT
1777/*
1778 * ADV_DVC_VAR 'warn_code' values
1779 */
27c868c2
MW
1780#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1781#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1782#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
27c868c2 1783#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 1784
27c868c2
MW
1785#define ADV_MAX_TID 15 /* max. target identifier */
1786#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
1787
1788/*
1789 * Error code values are set in ADV_DVC_VAR 'err_code'.
1790 */
27c868c2
MW
1791#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
1792#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
1793#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
1794#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
1795#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
1796#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
1797#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
1798#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
1799#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
1800#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
1801#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
1802#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
1803#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
1804#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
1805
1806/*
1807 * Fixed locations of microcode operating variables.
1808 */
27c868c2
MW
1809#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1810#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1811#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1812#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1813#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1814#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1815#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1816#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1817#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1818#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1819#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1820#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1821#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
1822#define ASC_MC_CHIP_TYPE 0x009A
1823#define ASC_MC_INTRB_CODE 0x009B
1824#define ASC_MC_WDTR_ABLE 0x009C
1825#define ASC_MC_SDTR_ABLE 0x009E
1826#define ASC_MC_TAGQNG_ABLE 0x00A0
1827#define ASC_MC_DISC_ENABLE 0x00A2
1828#define ASC_MC_IDLE_CMD_STATUS 0x00A4
1829#define ASC_MC_IDLE_CMD 0x00A6
1830#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1831#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1832#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1833#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1834#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1835#define ASC_MC_SDTR_DONE 0x00B6
1836#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1837#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1838#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 1839#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 1840#define ASC_MC_WDTR_DONE 0x0124
27c868c2 1841#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
1842#define ASC_MC_ICQ 0x0160
1843#define ASC_MC_IRQ 0x0164
1844#define ASC_MC_PPR_ABLE 0x017A
1845
1846/*
1847 * BIOS LRAM variable absolute offsets.
1848 */
1849#define BIOS_CODESEG 0x54
1850#define BIOS_CODELEN 0x56
1851#define BIOS_SIGNATURE 0x58
1852#define BIOS_VERSION 0x5A
1853
1854/*
1855 * Microcode Control Flags
1856 *
1857 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1858 * and handled by the microcode.
1859 */
27c868c2
MW
1860#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1861#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
1862
1863/*
1864 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1865 */
1866#define HSHK_CFG_WIDE_XFR 0x8000
1867#define HSHK_CFG_RATE 0x0F00
1868#define HSHK_CFG_OFFSET 0x001F
1869
27c868c2
MW
1870#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1871#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1872#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1873#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1874
1875#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1876#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
1877#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1878#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
1879#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1880
1881#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
1882#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
1883#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
1884#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
1885#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
1886/*
1887 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1888 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1889 */
27c868c2
MW
1890#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
1891#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
1892
1893/*
1894 * All fields here are accessed by the board microcode and need to be
1895 * little-endian.
1896 */
27c868c2
MW
1897typedef struct adv_carr_t {
1898 ADV_VADDR carr_va; /* Carrier Virtual Address */
1899 ADV_PADDR carr_pa; /* Carrier Physical Address */
1900 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1901 /*
1902 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
1903 *
1904 * next_vpa [3:1] Reserved Bits
1905 * next_vpa [0] Done Flag set in Response Queue.
1906 */
1907 ADV_VADDR next_vpa;
1da177e4
LT
1908} ADV_CARR_T;
1909
1910/*
1911 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1912 */
1913#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
1914
1915#define ASC_RQ_DONE 0x00000001
1916#define ASC_RQ_GOOD 0x00000002
1917#define ASC_CQ_STOPPER 0x00000000
1918
1919#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1920
1921#define ADV_CARRIER_NUM_PAGE_CROSSING \
1922 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
1923 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1924
1925#define ADV_CARRIER_BUFSIZE \
1926 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1927
1928/*
1929 * ASC_SCSI_REQ_Q 'a_flag' definitions
1930 *
1931 * The Adv Library should limit use to the lower nibble (4 bits) of
1932 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1933 */
27c868c2
MW
1934#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
1935#define ADV_SCSIQ_DONE 0x02 /* request done */
1936#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 1937
27c868c2
MW
1938#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
1939#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
1940#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
1941
1942/*
1943 * Adapter temporary configuration structure
1944 *
1945 * This structure can be discarded after initialization. Don't add
1946 * fields here needed after initialization.
1947 *
1948 * Field naming convention:
1949 *
1950 * *_enable indicates the field enables or disables a feature. The
1951 * value of the field is never reset.
1952 */
1953typedef struct adv_dvc_cfg {
27c868c2
MW
1954 ushort disc_enable; /* enable disconnection */
1955 uchar chip_version; /* chip version */
1956 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1957 ushort lib_version; /* Adv Library version number */
1958 ushort control_flag; /* Microcode Control Flag */
1959 ushort mcode_date; /* Microcode date */
1960 ushort mcode_version; /* Microcode version */
27c868c2
MW
1961 ushort serial1; /* EEPROM serial number word 1 */
1962 ushort serial2; /* EEPROM serial number word 2 */
1963 ushort serial3; /* EEPROM serial number word 3 */
1da177e4
LT
1964} ADV_DVC_CFG;
1965
1966struct adv_dvc_var;
1967struct adv_scsi_req_q;
1968
1da177e4
LT
1969/*
1970 * Adapter operation variable structure.
1971 *
1972 * One structure is required per host adapter.
1973 *
1974 * Field naming convention:
1975 *
1976 * *_able indicates both whether a feature should be enabled or disabled
1977 * and whether a device isi capable of the feature. At initialization
1978 * this field may be set, but later if a device is found to be incapable
1979 * of the feature, the field is cleared.
1980 */
1981typedef struct adv_dvc_var {
27c868c2
MW
1982 AdvPortAddr iop_base; /* I/O port address */
1983 ushort err_code; /* fatal error code */
1984 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
27c868c2
MW
1985 ushort wdtr_able; /* try WDTR for a device */
1986 ushort sdtr_able; /* try SDTR for a device */
1987 ushort ultra_able; /* try SDTR Ultra speed for a device */
1988 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
1989 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
1990 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
1991 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
1992 ushort tagqng_able; /* try tagged queuing with a device */
1993 ushort ppr_able; /* PPR message capable per TID bitmask. */
1994 uchar max_dvc_qng; /* maximum number of tagged commands per device */
1995 ushort start_motor; /* start motor command allowed */
1996 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
1997 uchar chip_no; /* should be assigned by caller */
1998 uchar max_host_qng; /* maximum number of Q'ed command allowed */
1999 uchar irq_no; /* IRQ number */
2000 ushort no_scam; /* scam_tolerant of EEPROM */
2001 struct asc_board *drv_ptr; /* driver pointer to private structure */
2002 uchar chip_scsi_id; /* chip SCSI target ID */
2003 uchar chip_type;
2004 uchar bist_err_code;
2005 ADV_CARR_T *carrier_buf;
2006 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2007 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2008 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2009 ushort carr_pending_cnt; /* Count of pending carriers. */
2010 /*
2011 * Note: The following fields will not be used after initialization. The
2012 * driver may discard the buffer after initialization is done.
2013 */
2014 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
2015} ADV_DVC_VAR;
2016
2017#define NO_OF_SG_PER_BLOCK 15
2018
2019typedef struct asc_sg_block {
27c868c2
MW
2020 uchar reserved1;
2021 uchar reserved2;
2022 uchar reserved3;
2023 uchar sg_cnt; /* Valid entries in block. */
2024 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2025 struct {
2026 ADV_PADDR sg_addr; /* SG element address. */
2027 ADV_DCNT sg_count; /* SG element count. */
2028 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
2029} ADV_SG_BLOCK;
2030
2031/*
2032 * ADV_SCSI_REQ_Q - microcode request structure
2033 *
2034 * All fields in this structure up to byte 60 are used by the microcode.
2035 * The microcode makes assumptions about the size and ordering of fields
2036 * in this structure. Do not change the structure definition here without
2037 * coordinating the change with the microcode.
2038 *
2039 * All fields accessed by microcode must be maintained in little_endian
2040 * order.
2041 */
2042typedef struct adv_scsi_req_q {
27c868c2
MW
2043 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2044 uchar target_cmd;
2045 uchar target_id; /* Device target identifier. */
2046 uchar target_lun; /* Device target logical unit number. */
2047 ADV_PADDR data_addr; /* Data buffer physical address. */
2048 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2049 ADV_PADDR sense_addr;
2050 ADV_PADDR carr_pa;
2051 uchar mflag;
2052 uchar sense_len;
2053 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2054 uchar scsi_cntl;
2055 uchar done_status; /* Completion status. */
2056 uchar scsi_status; /* SCSI status byte. */
2057 uchar host_status; /* Ucode host status. */
2058 uchar sg_working_ix;
2059 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2060 ADV_PADDR sg_real_addr; /* SG list physical address. */
2061 ADV_PADDR scsiq_rptr;
2062 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2063 ADV_VADDR scsiq_ptr;
2064 ADV_VADDR carr_va;
2065 /*
2066 * End of microcode structure - 60 bytes. The rest of the structure
2067 * is used by the Adv Library and ignored by the microcode.
2068 */
2069 ADV_VADDR srb_ptr;
2070 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2071 char *vdata_addr; /* Data buffer virtual address. */
2072 uchar a_flag;
2073 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
2074} ADV_SCSI_REQ_Q;
2075
2076/*
2077 * Microcode idle loop commands
2078 */
2079#define IDLE_CMD_COMPLETED 0
2080#define IDLE_CMD_STOP_CHIP 0x0001
2081#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2082#define IDLE_CMD_SEND_INT 0x0004
2083#define IDLE_CMD_ABORT 0x0008
2084#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
2085#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2086#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
2087#define IDLE_CMD_SCSIREQ 0x0080
2088
2089#define IDLE_CMD_STATUS_SUCCESS 0x0001
2090#define IDLE_CMD_STATUS_FAILURE 0x0002
2091
2092/*
2093 * AdvSendIdleCmd() flag definitions.
2094 */
2095#define ADV_NOWAIT 0x01
2096
2097/*
2098 * Wait loop time out values.
2099 */
27c868c2
MW
2100#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2101#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
27c868c2 2102#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 2103
27c868c2
MW
2104#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2105#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2106#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2107#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 2108
27c868c2 2109#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4 2110
27c868c2
MW
2111static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2112 uchar *, ASC_SDCNT *, int);
1da177e4
LT
2113
2114/*
2115 * Adv Library functions available to drivers.
2116 */
27c868c2
MW
2117static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2118static int AdvISR(ADV_DVC_VAR *);
27c868c2
MW
2119static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2120static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
2121static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
2122static int AdvResetChipAndSB(ADV_DVC_VAR *);
2123static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
2124
2125/*
2126 * Internal Adv Library functions.
2127 */
27c868c2 2128static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
27c868c2
MW
2129static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
2130static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
2131static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
2132static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2133static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2134static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2135static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2136static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2137static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2138static void AdvWaitEEPCmd(AdvPortAddr);
2139static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4 2140
1da177e4
LT
2141/* Read byte from a register. */
2142#define AdvReadByteRegister(iop_base, reg_off) \
2143 (ADV_MEM_READB((iop_base) + (reg_off)))
2144
2145/* Write byte to a register. */
2146#define AdvWriteByteRegister(iop_base, reg_off, byte) \
2147 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2148
2149/* Read word (2 bytes) from a register. */
2150#define AdvReadWordRegister(iop_base, reg_off) \
2151 (ADV_MEM_READW((iop_base) + (reg_off)))
2152
2153/* Write word (2 bytes) to a register. */
2154#define AdvWriteWordRegister(iop_base, reg_off, word) \
2155 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2156
2157/* Write dword (4 bytes) to a register. */
2158#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2159 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2160
2161/* Read byte from LRAM. */
2162#define AdvReadByteLram(iop_base, addr, byte) \
2163do { \
2164 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2165 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2166} while (0)
2167
2168/* Write byte to LRAM. */
2169#define AdvWriteByteLram(iop_base, addr, byte) \
2170 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2171 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2172
2173/* Read word (2 bytes) from LRAM. */
2174#define AdvReadWordLram(iop_base, addr, word) \
2175do { \
2176 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2177 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2178} while (0)
2179
2180/* Write word (2 bytes) to LRAM. */
2181#define AdvWriteWordLram(iop_base, addr, word) \
2182 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2183 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2184
2185/* Write little-endian double word (4 bytes) to LRAM */
2186/* Because of unspecified C language ordering don't use auto-increment. */
2187#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2188 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2189 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2190 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2191 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2192 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2193 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2194
2195/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2196#define AdvReadWordAutoIncLram(iop_base) \
2197 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2198
2199/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2200#define AdvWriteWordAutoIncLram(iop_base, word) \
2201 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2202
1da177e4
LT
2203/*
2204 * Define macro to check for Condor signature.
2205 *
2206 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2207 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2208 */
2209#define AdvFindSignature(iop_base) \
2210 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2211 ADV_CHIP_ID_BYTE) && \
2212 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2213 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2214
2215/*
2216 * Define macro to Return the version number of the chip at 'iop_base'.
2217 *
2218 * The second parameter 'bus_type' is currently unused.
2219 */
2220#define AdvGetChipVersion(iop_base, bus_type) \
2221 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2222
2223/*
2224 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2225 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2226 *
2227 * If the request has not yet been sent to the device it will simply be
2228 * aborted from RISC memory. If the request is disconnected it will be
2229 * aborted on reselection by sending an Abort Message to the target ID.
2230 *
2231 * Return value:
2232 * ADV_TRUE(1) - Queue was successfully aborted.
2233 * ADV_FALSE(0) - Queue was not found on the active queue list.
2234 */
2235#define AdvAbortQueue(asc_dvc, scsiq) \
2236 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2237 (ADV_DCNT) (scsiq))
2238
2239/*
2240 * Send a Bus Device Reset Message to the specified target ID.
2241 *
2242 * All outstanding commands will be purged if sending the
2243 * Bus Device Reset Message is successful.
2244 *
2245 * Return Value:
2246 * ADV_TRUE(1) - All requests on the target are purged.
2247 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2248 * are not purged.
2249 */
2250#define AdvResetDevice(asc_dvc, target_id) \
2251 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2252 (ADV_DCNT) (target_id))
2253
2254/*
2255 * SCSI Wide Type definition.
2256 */
2257#define ADV_SCSI_BIT_ID_TYPE ushort
2258
2259/*
2260 * AdvInitScsiTarget() 'cntl_flag' options.
2261 */
2262#define ADV_SCAN_LUN 0x01
2263#define ADV_CAPINFO_NOLUN 0x02
2264
2265/*
2266 * Convert target id to target id bit mask.
2267 */
2268#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2269
2270/*
2271 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2272 */
2273
27c868c2 2274#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
2275#define QD_NO_ERROR 0x01
2276#define QD_ABORTED_BY_HOST 0x02
2277#define QD_WITH_ERROR 0x04
2278
2279#define QHSTA_NO_ERROR 0x00
2280#define QHSTA_M_SEL_TIMEOUT 0x11
2281#define QHSTA_M_DATA_OVER_RUN 0x12
2282#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2283#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
2284#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2285#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2286#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2287#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2288#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2289#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2290#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 2291/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
2292#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2293#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2294#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2295#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2296#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2297#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2298#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2299#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
2300#define QHSTA_M_WTM_TIMEOUT 0x41
2301#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2302#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2303#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
2304#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2305#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2306#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4 2307
1da177e4
LT
2308/*
2309 * DvcGetPhyAddr() flag arguments
2310 */
27c868c2
MW
2311#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2312#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2313#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2314#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2315#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2316#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
2317
2318/* Return the address that is aligned at the next doubleword >= to 'addr'. */
2319#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2320#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2321#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2322
2323/*
2324 * Total contiguous memory needed for driver SG blocks.
2325 *
2326 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2327 * number of scatter-gather elements the driver supports in a
2328 * single request.
2329 */
2330
2331#define ADV_SG_LIST_MAX_BYTE_SIZE \
2332 (sizeof(ADV_SG_BLOCK) * \
2333 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2334
1da177e4
LT
2335/* Reference Scsi_Host hostdata */
2336#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2337
2338/* asc_board_t flags */
2339#define ASC_HOST_IN_RESET 0x01
27c868c2 2340#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
2341#define ASC_SELECT_QUEUE_DEPTHS 0x08
2342
2343#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2344#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
2345
27c868c2 2346#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 2347
27c868c2 2348#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
2349
2350#ifdef CONFIG_PROC_FS
2351/* /proc/scsi/advansys/[0...] related definitions */
2352#define ASC_PRTBUF_SIZE 2048
2353#define ASC_PRTLINE_SIZE 160
2354
2355#define ASC_PRT_NEXT() \
2356 if (cp) { \
2357 totlen += len; \
2358 leftlen -= len; \
2359 if (leftlen == 0) { \
2360 return totlen; \
2361 } \
2362 cp += len; \
2363 }
2364#endif /* CONFIG_PROC_FS */
2365
2366/* Asc Library return codes */
2367#define ASC_TRUE 1
2368#define ASC_FALSE 0
2369#define ASC_NOERROR 1
2370#define ASC_BUSY 0
2371#define ASC_ERROR (-1)
2372
2373/* struct scsi_cmnd function return codes */
2374#define STATUS_BYTE(byte) (byte)
2375#define MSG_BYTE(byte) ((byte) << 8)
2376#define HOST_BYTE(byte) ((byte) << 16)
2377#define DRIVER_BYTE(byte) ((byte) << 24)
2378
1da177e4 2379#ifndef ADVANSYS_STATS
27c868c2
MW
2380#define ASC_STATS(shost, counter)
2381#define ASC_STATS_ADD(shost, counter, count)
1da177e4 2382#else /* ADVANSYS_STATS */
27c868c2
MW
2383#define ASC_STATS(shost, counter) \
2384 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 2385
27c868c2
MW
2386#define ASC_STATS_ADD(shost, counter, count) \
2387 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
2388#endif /* ADVANSYS_STATS */
2389
2390#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2391
2392/* If the result wraps when calculating tenths, return 0. */
2393#define ASC_TENTHS(num, den) \
2394 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2395 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2396
2397/*
2398 * Display a message to the console.
2399 */
2400#define ASC_PRINT(s) \
2401 { \
2402 printk("advansys: "); \
2403 printk(s); \
2404 }
2405
2406#define ASC_PRINT1(s, a1) \
2407 { \
2408 printk("advansys: "); \
2409 printk((s), (a1)); \
2410 }
2411
2412#define ASC_PRINT2(s, a1, a2) \
2413 { \
2414 printk("advansys: "); \
2415 printk((s), (a1), (a2)); \
2416 }
2417
2418#define ASC_PRINT3(s, a1, a2, a3) \
2419 { \
2420 printk("advansys: "); \
2421 printk((s), (a1), (a2), (a3)); \
2422 }
2423
2424#define ASC_PRINT4(s, a1, a2, a3, a4) \
2425 { \
2426 printk("advansys: "); \
2427 printk((s), (a1), (a2), (a3), (a4)); \
2428 }
2429
1da177e4
LT
2430#ifndef ADVANSYS_DEBUG
2431
2432#define ASC_DBG(lvl, s)
2433#define ASC_DBG1(lvl, s, a1)
2434#define ASC_DBG2(lvl, s, a1, a2)
2435#define ASC_DBG3(lvl, s, a1, a2, a3)
2436#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2437#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2438#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2439#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2440#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2441#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2442#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2443#define ASC_DBG_PRT_HEX(lvl, name, start, length)
2444#define ASC_DBG_PRT_CDB(lvl, cdb, len)
2445#define ASC_DBG_PRT_SENSE(lvl, sense, len)
2446#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2447
2448#else /* ADVANSYS_DEBUG */
2449
2450/*
2451 * Debugging Message Levels:
2452 * 0: Errors Only
2453 * 1: High-Level Tracing
2454 * 2-N: Verbose Tracing
2455 */
2456
2457#define ASC_DBG(lvl, s) \
2458 { \
2459 if (asc_dbglvl >= (lvl)) { \
2460 printk(s); \
2461 } \
2462 }
2463
2464#define ASC_DBG1(lvl, s, a1) \
2465 { \
2466 if (asc_dbglvl >= (lvl)) { \
2467 printk((s), (a1)); \
2468 } \
2469 }
2470
2471#define ASC_DBG2(lvl, s, a1, a2) \
2472 { \
2473 if (asc_dbglvl >= (lvl)) { \
2474 printk((s), (a1), (a2)); \
2475 } \
2476 }
2477
2478#define ASC_DBG3(lvl, s, a1, a2, a3) \
2479 { \
2480 if (asc_dbglvl >= (lvl)) { \
2481 printk((s), (a1), (a2), (a3)); \
2482 } \
2483 }
2484
2485#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2486 { \
2487 if (asc_dbglvl >= (lvl)) { \
2488 printk((s), (a1), (a2), (a3), (a4)); \
2489 } \
2490 }
2491
2492#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2493 { \
2494 if (asc_dbglvl >= (lvl)) { \
2495 asc_prt_scsi_host(s); \
2496 } \
2497 }
2498
2499#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2500 { \
2501 if (asc_dbglvl >= (lvl)) { \
2502 asc_prt_scsi_cmnd(s); \
2503 } \
2504 }
2505
2506#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2507 { \
2508 if (asc_dbglvl >= (lvl)) { \
2509 asc_prt_asc_scsi_q(scsiqp); \
2510 } \
2511 }
2512
2513#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2514 { \
2515 if (asc_dbglvl >= (lvl)) { \
2516 asc_prt_asc_qdone_info(qdone); \
2517 } \
2518 }
2519
2520#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2521 { \
2522 if (asc_dbglvl >= (lvl)) { \
2523 asc_prt_adv_scsi_req_q(scsiqp); \
2524 } \
2525 }
2526
2527#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2528 { \
2529 if (asc_dbglvl >= (lvl)) { \
2530 asc_prt_hex((name), (start), (length)); \
2531 } \
2532 }
2533
2534#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2535 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2536
2537#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2538 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2539
2540#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2541 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2542#endif /* ADVANSYS_DEBUG */
2543
1da177e4
LT
2544#ifdef ADVANSYS_STATS
2545
2546/* Per board statistics structure */
2547struct asc_stats {
27c868c2
MW
2548 /* Driver Entrypoint Statistics */
2549 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2550 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2551 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2552 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2553 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2554 ADV_DCNT done; /* # calls to request's scsi_done function */
2555 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2556 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2557 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2558 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2559 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2560 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2561 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2562 ADV_DCNT exe_unknown; /* # unknown returns. */
2563 /* Data Transfer Statistics */
2564 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2565 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2566 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2567 ADV_DCNT sg_elem; /* # scatter-gather elements */
2568 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
2569};
2570#endif /* ADVANSYS_STATS */
2571
1da177e4
LT
2572/*
2573 * Adv Library Request Structures
2574 *
2575 * The following two structures are used to process Wide Board requests.
2576 *
2577 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2578 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2579 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2580 * Mid-Level SCSI request structure.
2581 *
2582 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2583 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2584 * up to 255 scatter-gather elements may be used per request or
2585 * ADV_SCSI_REQ_Q.
2586 *
2587 * Both structures must be 32 byte aligned.
2588 */
2589typedef struct adv_sgblk {
27c868c2
MW
2590 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2591 uchar align[32]; /* Sgblock structure padding. */
2592 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
2593} adv_sgblk_t;
2594
2595typedef struct adv_req {
27c868c2
MW
2596 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2597 uchar align[32]; /* Request structure padding. */
2598 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2599 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2600 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
2601} adv_req_t;
2602
2603/*
2604 * Structure allocated for each board.
2605 *
8dfb5379 2606 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
2607 * of the 'Scsi_Host' structure starting at the 'hostdata'
2608 * field. It is guaranteed to be allocated from DMA-able memory.
2609 */
2610typedef struct asc_board {
394dbf3f 2611 struct device *dev;
27c868c2
MW
2612 int id; /* Board Id */
2613 uint flags; /* Board flags */
2614 union {
2615 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2616 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2617 } dvc_var;
2618 union {
2619 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2620 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2621 } dvc_cfg;
2622 ushort asc_n_io_port; /* Number I/O ports. */
27c868c2
MW
2623 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2624 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
2625 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2626 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2627 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2628 union {
2629 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2630 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2631 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2632 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2633 } eep_config;
2634 ulong last_reset; /* Saved last reset time */
2635 spinlock_t lock; /* Board spinlock */
27c868c2
MW
2636 /* /proc/scsi/advansys/[0...] */
2637 char *prtbuf; /* /proc print buffer */
1da177e4 2638#ifdef ADVANSYS_STATS
27c868c2
MW
2639 struct asc_stats asc_stats; /* Board statistics */
2640#endif /* ADVANSYS_STATS */
2641 /*
2642 * The following fields are used only for Narrow Boards.
2643 */
27c868c2
MW
2644 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2645 /*
2646 * The following fields are used only for Wide Boards.
2647 */
2648 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2649 ushort ioport; /* I/O Port address. */
b2c16f58 2650 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
2651 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2652 adv_req_t *adv_reqp; /* Request structures. */
2653 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2654 ushort bios_signature; /* BIOS Signature. */
2655 ushort bios_version; /* BIOS Version. */
2656 ushort bios_codeseg; /* BIOS Code Segment. */
2657 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
2658} asc_board_t;
2659
13ac2d9c
MW
2660#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2661 dvc_var.adv_dvc_var)
2662#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2663
1da177e4 2664/* Number of boards detected in system. */
78e77d8b
MW
2665static int asc_board_count;
2666
1da177e4 2667/* Overrun buffer used by all narrow boards. */
27c868c2 2668static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
2669
2670/*
2671 * Global structures required to issue a command.
2672 */
27c868c2
MW
2673static ASC_SCSI_Q asc_scsi_q = { {0} };
2674static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4 2675
1da177e4 2676#ifdef ADVANSYS_DEBUG
27c868c2 2677static int asc_dbglvl = 3;
1da177e4
LT
2678#endif /* ADVANSYS_DEBUG */
2679
27c868c2 2680static int advansys_slave_configure(struct scsi_device *);
27c868c2
MW
2681static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
2682static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
2683static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
2684static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
1da177e4 2685#ifdef CONFIG_PROC_FS
27c868c2
MW
2686static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
2687static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
2688static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
2689static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
2690static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
2691static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
2692static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
2693static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
2694static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
2695static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
2696#endif /* CONFIG_PROC_FS */
2697
1da177e4
LT
2698/* Statistics function prototypes. */
2699#ifdef ADVANSYS_STATS
2700#ifdef CONFIG_PROC_FS
27c868c2 2701static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
1da177e4
LT
2702#endif /* CONFIG_PROC_FS */
2703#endif /* ADVANSYS_STATS */
2704
2705/* Debug function prototypes. */
2706#ifdef ADVANSYS_DEBUG
27c868c2
MW
2707static void asc_prt_scsi_host(struct Scsi_Host *);
2708static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
2709static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
2710static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
2711static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
2712static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
2713static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
2714static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
2715static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
2716static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
2717static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
2718#endif /* ADVANSYS_DEBUG */
2719
1da177e4
LT
2720#ifdef CONFIG_PROC_FS
2721/*
c304ec94 2722 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
2723 *
2724 * *buffer: I/O buffer
2725 * **start: if inout == FALSE pointer into buffer where user read should start
2726 * offset: current offset into a /proc/scsi/advansys/[0...] file
2727 * length: length of buffer
2728 * hostno: Scsi_Host host_no
2729 * inout: TRUE - user is writing; FALSE - user is reading
2730 *
2731 * Return the number of bytes read from or written to a
2732 * /proc/scsi/advansys/[0...] file.
2733 *
2734 * Note: This function uses the per board buffer 'prtbuf' which is
2735 * allocated when the board is initialized in advansys_detect(). The
2736 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
2737 * used to write to the buffer. The way asc_proc_copy() is written
2738 * if 'prtbuf' is too small it will not be overwritten. Instead the
2739 * user just won't get all the available statistics.
2740 */
70c8d897 2741static int
1da177e4 2742advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 2743 off_t offset, int length, int inout)
1da177e4 2744{
27c868c2 2745 asc_board_t *boardp;
27c868c2
MW
2746 char *cp;
2747 int cplen;
2748 int cnt;
2749 int totcnt;
2750 int leftlen;
2751 char *curbuf;
2752 off_t advoffset;
1da177e4 2753
27c868c2 2754 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 2755
27c868c2
MW
2756 /*
2757 * User write not supported.
2758 */
2759 if (inout == TRUE) {
2760 return (-ENOSYS);
2761 }
1da177e4 2762
27c868c2
MW
2763 /*
2764 * User read of /proc/scsi/advansys/[0...] file.
2765 */
1da177e4 2766
2a437959 2767 boardp = ASC_BOARDP(shost);
27c868c2
MW
2768
2769 /* Copy read data starting at the beginning of the buffer. */
2770 *start = buffer;
2771 curbuf = buffer;
2772 advoffset = 0;
2773 totcnt = 0;
2774 leftlen = length;
2775
2776 /*
2777 * Get board configuration information.
2778 *
2779 * advansys_info() returns the board string from its own static buffer.
2780 */
2a437959 2781 cp = (char *)advansys_info(shost);
27c868c2
MW
2782 strcat(cp, "\n");
2783 cplen = strlen(cp);
2784 /* Copy board information. */
2785 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2786 totcnt += cnt;
2787 leftlen -= cnt;
2788 if (leftlen == 0) {
2789 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2790 return totcnt;
2791 }
2792 advoffset += cplen;
2793 curbuf += cnt;
2794
2795 /*
2796 * Display Wide Board BIOS Information.
2797 */
2798 if (ASC_WIDE_BOARD(boardp)) {
2799 cp = boardp->prtbuf;
2a437959 2800 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2801 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
ecec1947 2802 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
27c868c2
MW
2803 cplen);
2804 totcnt += cnt;
2805 leftlen -= cnt;
2806 if (leftlen == 0) {
2807 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2808 return totcnt;
2809 }
2810 advoffset += cplen;
2811 curbuf += cnt;
2812 }
1da177e4 2813
27c868c2
MW
2814 /*
2815 * Display driver information for each device attached to the board.
2816 */
2817 cp = boardp->prtbuf;
2a437959 2818 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2819 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2820 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2821 totcnt += cnt;
2822 leftlen -= cnt;
2823 if (leftlen == 0) {
2824 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2825 return totcnt;
2826 }
2827 advoffset += cplen;
2828 curbuf += cnt;
2829
2830 /*
2831 * Display EEPROM configuration for the board.
2832 */
2833 cp = boardp->prtbuf;
2834 if (ASC_NARROW_BOARD(boardp)) {
2a437959 2835 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2836 } else {
2a437959 2837 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2838 }
b009bef6 2839 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2840 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2841 totcnt += cnt;
2842 leftlen -= cnt;
2843 if (leftlen == 0) {
2844 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2845 return totcnt;
2846 }
2847 advoffset += cplen;
2848 curbuf += cnt;
2849
2850 /*
2851 * Display driver configuration and information for the board.
2852 */
2853 cp = boardp->prtbuf;
2a437959 2854 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2855 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2856 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2857 totcnt += cnt;
2858 leftlen -= cnt;
2859 if (leftlen == 0) {
2860 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2861 return totcnt;
2862 }
2863 advoffset += cplen;
2864 curbuf += cnt;
1da177e4
LT
2865
2866#ifdef ADVANSYS_STATS
27c868c2
MW
2867 /*
2868 * Display driver statistics for the board.
2869 */
2870 cp = boardp->prtbuf;
2a437959 2871 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
b009bef6 2872 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2873 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2874 totcnt += cnt;
2875 leftlen -= cnt;
2876 if (leftlen == 0) {
2877 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2878 return totcnt;
2879 }
2880 advoffset += cplen;
2881 curbuf += cnt;
1da177e4
LT
2882#endif /* ADVANSYS_STATS */
2883
27c868c2
MW
2884 /*
2885 * Display Asc Library dynamic configuration information
2886 * for the board.
2887 */
2888 cp = boardp->prtbuf;
2889 if (ASC_NARROW_BOARD(boardp)) {
2a437959 2890 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2891 } else {
2a437959 2892 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 2893 }
b009bef6 2894 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
27c868c2
MW
2895 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
2896 totcnt += cnt;
2897 leftlen -= cnt;
2898 if (leftlen == 0) {
2899 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
2900 return totcnt;
2901 }
2902 advoffset += cplen;
2903 curbuf += cnt;
1da177e4 2904
27c868c2 2905 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 2906
27c868c2 2907 return totcnt;
1da177e4 2908}
1da177e4 2909#endif /* CONFIG_PROC_FS */
1da177e4
LT
2910
2911/*
2912 * advansys_info()
2913 *
2914 * Return suitable for printing on the console with the argument
2915 * adapter's configuration information.
2916 *
2917 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2918 * otherwise the static 'info' array will be overrun.
2919 */
27c868c2 2920static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 2921{
27c868c2
MW
2922 static char info[ASC_INFO_SIZE];
2923 asc_board_t *boardp;
2924 ASC_DVC_VAR *asc_dvc_varp;
2925 ADV_DVC_VAR *adv_dvc_varp;
2926 char *busname;
27c868c2
MW
2927 char *widename = NULL;
2928
2929 boardp = ASC_BOARDP(shost);
2930 if (ASC_NARROW_BOARD(boardp)) {
2931 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2932 ASC_DBG(1, "advansys_info: begin\n");
2933 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2934 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2935 ASC_IS_ISAPNP) {
2936 busname = "ISA PnP";
2937 } else {
2938 busname = "ISA";
2939 }
27c868c2
MW
2940 sprintf(info,
2941 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2942 ASC_VERSION, busname,
2943 (ulong)shost->io_port,
4a2d31c8
MW
2944 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2945 shost->irq, shost->dma_channel);
27c868c2
MW
2946 } else {
2947 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2948 busname = "VL";
2949 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2950 busname = "EISA";
2951 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2952 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2953 == ASC_IS_PCI_ULTRA) {
2954 busname = "PCI Ultra";
2955 } else {
2956 busname = "PCI";
2957 }
2958 } else {
2959 busname = "?";
ecec1947
MW
2960 ASC_PRINT2("advansys_info: board %d: unknown "
2961 "bus type %d\n", boardp->id,
2962 asc_dvc_varp->bus_type);
27c868c2 2963 }
27c868c2
MW
2964 sprintf(info,
2965 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
ecec1947 2966 ASC_VERSION, busname, (ulong)shost->io_port,
4a2d31c8
MW
2967 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2968 shost->irq);
27c868c2
MW
2969 }
2970 } else {
2971 /*
2972 * Wide Adapter Information
2973 *
2974 * Memory-mapped I/O is used instead of I/O space to access
2975 * the adapter, but display the I/O Port range. The Memory
2976 * I/O address is displayed through the driver /proc file.
2977 */
2978 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2979 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
27c868c2
MW
2980 widename = "Ultra-Wide";
2981 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
27c868c2
MW
2982 widename = "Ultra2-Wide";
2983 } else {
27c868c2
MW
2984 widename = "Ultra3-Wide";
2985 }
2986 sprintf(info,
2987 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2988 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4a2d31c8 2989 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
27c868c2 2990 }
b009bef6 2991 BUG_ON(strlen(info) >= ASC_INFO_SIZE);
27c868c2
MW
2992 ASC_DBG(1, "advansys_info: end\n");
2993 return info;
1da177e4
LT
2994}
2995
6ed1ef07
MW
2996static void asc_scsi_done(struct scsi_cmnd *scp)
2997{
2998 struct asc_board *boardp = ASC_BOARDP(scp->device->host);
2999
3000 if (scp->use_sg)
3001 dma_unmap_sg(boardp->dev,
3002 (struct scatterlist *)scp->request_buffer,
3003 scp->use_sg, scp->sc_data_direction);
3004 else if (scp->request_bufflen)
3005 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
3006 scp->request_bufflen, scp->sc_data_direction);
3007
3008 ASC_STATS(scp->device->host, done);
3009
3010 scp->scsi_done(scp);
3011}
3012
1da177e4
LT
3013/*
3014 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
3015 *
3016 * This function always returns 0. Command return status is saved
3017 * in the 'scp' result field.
3018 */
70c8d897 3019static int
b2a7a4ba 3020advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
1da177e4 3021{
b2a7a4ba
MW
3022 struct Scsi_Host *shost = scp->device->host;
3023 asc_board_t *boardp = ASC_BOARDP(shost);
3024 unsigned long flags;
b6622925 3025 int asc_res, result = 0;
1da177e4 3026
27c868c2 3027 ASC_STATS(shost, queuecommand);
b2a7a4ba 3028 scp->scsi_done = done;
1da177e4 3029
b2a7a4ba
MW
3030 /*
3031 * host_lock taken by mid-level prior to call, but need
3032 * to protect against own ISR
3033 */
27c868c2 3034 spin_lock_irqsave(&boardp->lock, flags);
b6622925 3035 asc_res = asc_execute_scsi_cmnd(scp);
b2a7a4ba
MW
3036 spin_unlock_irqrestore(&boardp->lock, flags);
3037
b6622925 3038 switch (asc_res) {
27c868c2
MW
3039 case ASC_NOERROR:
3040 break;
3041 case ASC_BUSY:
b6622925 3042 result = SCSI_MLQUEUE_HOST_BUSY;
27c868c2
MW
3043 break;
3044 case ASC_ERROR:
3045 default:
6ed1ef07 3046 asc_scsi_done(scp);
27c868c2
MW
3047 break;
3048 }
1da177e4 3049
b6622925 3050 return result;
1da177e4
LT
3051}
3052
3053/*
3054 * advansys_reset()
3055 *
3056 * Reset the bus associated with the command 'scp'.
3057 *
3058 * This function runs its own thread. Interrupts must be blocked but
3059 * sleeping is allowed and no locking other than for host structures is
3060 * required. Returns SUCCESS or FAILED.
3061 */
27c868c2 3062static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 3063{
27c868c2
MW
3064 struct Scsi_Host *shost;
3065 asc_board_t *boardp;
3066 ASC_DVC_VAR *asc_dvc_varp;
3067 ADV_DVC_VAR *adv_dvc_varp;
3068 ulong flags;
27c868c2
MW
3069 int status;
3070 int ret = SUCCESS;
3071
3072 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
3073
3074#ifdef ADVANSYS_STATS
27c868c2
MW
3075 if (scp->device->host != NULL) {
3076 ASC_STATS(scp->device->host, reset);
3077 }
1da177e4
LT
3078#endif /* ADVANSYS_STATS */
3079
27c868c2
MW
3080 if ((shost = scp->device->host) == NULL) {
3081 scp->result = HOST_BYTE(DID_ERROR);
3082 return FAILED;
3083 }
1da177e4 3084
27c868c2 3085 boardp = ASC_BOARDP(shost);
1da177e4 3086
27c868c2
MW
3087 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
3088 boardp->id);
3089 /*
3090 * Check for re-entrancy.
3091 */
1da177e4 3092 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
3093 if (boardp->flags & ASC_HOST_IN_RESET) {
3094 spin_unlock_irqrestore(&boardp->lock, flags);
3095 return FAILED;
3096 }
3097 boardp->flags |= ASC_HOST_IN_RESET;
3098 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3099
27c868c2
MW
3100 if (ASC_NARROW_BOARD(boardp)) {
3101 /*
3102 * Narrow Board
3103 */
3104 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 3105
27c868c2
MW
3106 /*
3107 * Reset the chip and SCSI bus.
3108 */
3109 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
3110 status = AscInitAsc1000Driver(asc_dvc_varp);
3111
3112 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
3113 if (asc_dvc_varp->err_code) {
ecec1947
MW
3114 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3115 "error: 0x%x\n", boardp->id,
3116 asc_dvc_varp->err_code);
27c868c2
MW
3117 ret = FAILED;
3118 } else if (status) {
ecec1947
MW
3119 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3120 "warning: 0x%x\n", boardp->id, status);
27c868c2 3121 } else {
ecec1947
MW
3122 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3123 "successful.\n", boardp->id);
27c868c2
MW
3124 }
3125
3126 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
3127 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 3128
27c868c2
MW
3129 } else {
3130 /*
3131 * Wide Board
3132 *
3133 * If the suggest reset bus flags are set, then reset the bus.
3134 * Otherwise only reset the device.
3135 */
3136 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 3137
27c868c2
MW
3138 /*
3139 * Reset the target's SCSI bus.
3140 */
3141 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
3142 switch (AdvResetChipAndSB(adv_dvc_varp)) {
3143 case ASC_TRUE:
ecec1947
MW
3144 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3145 "successful.\n", boardp->id);
27c868c2
MW
3146 break;
3147 case ASC_FALSE:
3148 default:
ecec1947
MW
3149 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3150 "error.\n", boardp->id);
27c868c2
MW
3151 ret = FAILED;
3152 break;
3153 }
3154 spin_lock_irqsave(&boardp->lock, flags);
3155 (void)AdvISR(adv_dvc_varp);
3156 }
3157 /* Board lock is held. */
3158
27c868c2
MW
3159 /* Save the time of the most recently completed reset. */
3160 boardp->last_reset = jiffies;
1da177e4 3161
27c868c2
MW
3162 /* Clear reset flag. */
3163 boardp->flags &= ~ASC_HOST_IN_RESET;
3164 spin_unlock_irqrestore(&boardp->lock, flags);
3165
27c868c2 3166 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 3167
27c868c2 3168 return ret;
1da177e4
LT
3169}
3170
3171/*
3172 * advansys_biosparam()
3173 *
3174 * Translate disk drive geometry if the "BIOS greater than 1 GB"
3175 * support is enabled for a drive.
3176 *
3177 * ip (information pointer) is an int array with the following definition:
3178 * ip[0]: heads
3179 * ip[1]: sectors
3180 * ip[2]: cylinders
3181 */
70c8d897 3182static int
1da177e4 3183advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 3184 sector_t capacity, int ip[])
1da177e4 3185{
27c868c2
MW
3186 asc_board_t *boardp;
3187
3188 ASC_DBG(1, "advansys_biosparam: begin\n");
3189 ASC_STATS(sdev->host, biosparam);
3190 boardp = ASC_BOARDP(sdev->host);
3191 if (ASC_NARROW_BOARD(boardp)) {
3192 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
3193 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
3194 ip[0] = 255;
3195 ip[1] = 63;
3196 } else {
3197 ip[0] = 64;
3198 ip[1] = 32;
3199 }
3200 } else {
3201 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
3202 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
3203 ip[0] = 255;
3204 ip[1] = 63;
3205 } else {
3206 ip[0] = 64;
3207 ip[1] = 32;
3208 }
3209 }
3210 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
3211 ASC_DBG(1, "advansys_biosparam: end\n");
3212 return 0;
1da177e4
LT
3213}
3214
8dfb5379 3215static struct scsi_host_template advansys_template = {
27c868c2 3216 .proc_name = "advansys",
1da177e4 3217#ifdef CONFIG_PROC_FS
27c868c2 3218 .proc_info = advansys_proc_info,
1da177e4 3219#endif
27c868c2 3220 .name = "advansys",
27c868c2
MW
3221 .info = advansys_info,
3222 .queuecommand = advansys_queuecommand,
3223 .eh_bus_reset_handler = advansys_reset,
3224 .bios_param = advansys_biosparam,
3225 .slave_configure = advansys_slave_configure,
3226 /*
3227 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
8dfb5379
MW
3228 * must be set. The flag will be cleared in advansys_board_found
3229 * for non-ISA adapters.
27c868c2
MW
3230 */
3231 .unchecked_isa_dma = 1,
3232 /*
3233 * All adapters controlled by this driver are capable of large
3234 * scatter-gather lists. According to the mid-level SCSI documentation
3235 * this obviates any performance gain provided by setting
3236 * 'use_clustering'. But empirically while CPU utilization is increased
3237 * by enabling clustering, I/O throughput increases as well.
3238 */
3239 .use_clustering = ENABLE_CLUSTERING,
1da177e4 3240};
1da177e4 3241
1da177e4
LT
3242/*
3243 * First-level interrupt handler.
3244 *
95c9f162 3245 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
1da177e4 3246 */
27c868c2 3247static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 3248{
074c8fe4 3249 unsigned long flags;
074c8fe4
MW
3250 struct Scsi_Host *shost = dev_id;
3251 asc_board_t *boardp = ASC_BOARDP(shost);
3252 irqreturn_t result = IRQ_NONE;
27c868c2 3253
074c8fe4
MW
3254 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
3255 spin_lock_irqsave(&boardp->lock, flags);
3256 if (ASC_NARROW_BOARD(boardp)) {
074c8fe4
MW
3257 if (AscIsIntPending(shost->io_port)) {
3258 result = IRQ_HANDLED;
3259 ASC_STATS(shost, interrupt);
3260 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
3261 AscISR(&boardp->dvc_var.asc_dvc_var);
3262 }
3263 } else {
074c8fe4
MW
3264 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
3265 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
3266 result = IRQ_HANDLED;
3267 ASC_STATS(shost, interrupt);
3268 }
3269 }
074c8fe4 3270 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3271
27c868c2 3272 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 3273 return result;
1da177e4
LT
3274}
3275
47d853cc
MW
3276static void
3277advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
3278{
3279 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
3280 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
3281
3282 if (sdev->lun == 0) {
3283 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
3284 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
3285 asc_dvc->init_sdtr |= tid_bit;
3286 } else {
3287 asc_dvc->init_sdtr &= ~tid_bit;
3288 }
3289
3290 if (orig_init_sdtr != asc_dvc->init_sdtr)
3291 AscAsyncFix(asc_dvc, sdev);
3292 }
3293
3294 if (sdev->tagged_supported) {
3295 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
3296 if (sdev->lun == 0) {
3297 asc_dvc->cfg->can_tagged_qng |= tid_bit;
3298 asc_dvc->use_tagged_qng |= tid_bit;
3299 }
3300 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3301 asc_dvc->max_dvc_qng[sdev->id]);
3302 }
3303 } else {
3304 if (sdev->lun == 0) {
3305 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
3306 asc_dvc->use_tagged_qng &= ~tid_bit;
3307 }
3308 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
3309 }
3310
3311 if ((sdev->lun == 0) &&
3312 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
3313 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
3314 asc_dvc->cfg->disc_enable);
3315 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
3316 asc_dvc->use_tagged_qng);
3317 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
3318 asc_dvc->cfg->can_tagged_qng);
3319
3320 asc_dvc->max_dvc_qng[sdev->id] =
3321 asc_dvc->cfg->max_tag_qng[sdev->id];
3322 AscWriteLramByte(asc_dvc->iop_base,
3323 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
3324 asc_dvc->max_dvc_qng[sdev->id]);
3325 }
3326}
3327
1da177e4 3328/*
47d853cc
MW
3329 * Wide Transfers
3330 *
3331 * If the EEPROM enabled WDTR for the device and the device supports wide
3332 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
3333 * write the new value to the microcode.
1da177e4 3334 */
47d853cc
MW
3335static void
3336advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
1da177e4 3337{
47d853cc
MW
3338 unsigned short cfg_word;
3339 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
3340 if ((cfg_word & tidmask) != 0)
3341 return;
3342
3343 cfg_word |= tidmask;
3344 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
1da177e4 3345
27c868c2 3346 /*
47d853cc
MW
3347 * Clear the microcode SDTR and WDTR negotiation done indicators for
3348 * the target to cause it to negotiate with the new setting set above.
3349 * WDTR when accepted causes the target to enter asynchronous mode, so
3350 * SDTR must be negotiated.
27c868c2 3351 */
47d853cc
MW
3352 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3353 cfg_word &= ~tidmask;
3354 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3355 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3356 cfg_word &= ~tidmask;
3357 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3358}
3359
3360/*
3361 * Synchronous Transfers
3362 *
3363 * If the EEPROM enabled SDTR for the device and the device
3364 * supports synchronous transfers, then turn on the device's
3365 * 'sdtr_able' bit. Write the new value to the microcode.
3366 */
3367static void
3368advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
3369{
3370 unsigned short cfg_word;
3371 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3372 if ((cfg_word & tidmask) != 0)
3373 return;
3374
3375 cfg_word |= tidmask;
3376 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3377
3378 /*
3379 * Clear the microcode "SDTR negotiation" done indicator for the
3380 * target to cause it to negotiate with the new setting set above.
3381 */
3382 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3383 cfg_word &= ~tidmask;
3384 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3385}
3386
3387/*
3388 * PPR (Parallel Protocol Request) Capable
3389 *
3390 * If the device supports DT mode, then it must be PPR capable.
3391 * The PPR message will be used in place of the SDTR and WDTR
3392 * messages to negotiate synchronous speed and offset, transfer
3393 * width, and protocol options.
3394 */
3395static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
3396 AdvPortAddr iop_base, unsigned short tidmask)
3397{
3398 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3399 adv_dvc->ppr_able |= tidmask;
3400 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3401}
3402
3403static void
3404advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
3405{
3406 AdvPortAddr iop_base = adv_dvc->iop_base;
3407 unsigned short tidmask = 1 << sdev->id;
3408
3409 if (sdev->lun == 0) {
3410 /*
3411 * Handle WDTR, SDTR, and Tag Queuing. If the feature
3412 * is enabled in the EEPROM and the device supports the
3413 * feature, then enable it in the microcode.
3414 */
3415
3416 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
3417 advansys_wide_enable_wdtr(iop_base, tidmask);
3418 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
3419 advansys_wide_enable_sdtr(iop_base, tidmask);
3420 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
3421 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
3422
3423 /*
3424 * Tag Queuing is disabled for the BIOS which runs in polled
3425 * mode and would see no benefit from Tag Queuing. Also by
3426 * disabling Tag Queuing in the BIOS devices with Tag Queuing
3427 * bugs will at least work with the BIOS.
3428 */
3429 if ((adv_dvc->tagqng_able & tidmask) &&
3430 sdev->tagged_supported) {
3431 unsigned short cfg_word;
3432 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
3433 cfg_word |= tidmask;
3434 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
3435 cfg_word);
3436 AdvWriteByteLram(iop_base,
3437 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
3438 adv_dvc->max_dvc_qng);
27c868c2 3439 }
47d853cc
MW
3440 }
3441
3442 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
3443 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3444 adv_dvc->max_dvc_qng);
27c868c2 3445 } else {
47d853cc 3446 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
27c868c2 3447 }
47d853cc
MW
3448}
3449
3450/*
3451 * Set the number of commands to queue per device for the
3452 * specified host adapter.
3453 */
3454static int advansys_slave_configure(struct scsi_device *sdev)
3455{
3456 asc_board_t *boardp = ASC_BOARDP(sdev->host);
3457 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
3458
3459 /*
3460 * Save a pointer to the sdev and set its initial/maximum
3461 * queue depth. Only save the pointer for a lun0 dev though.
3462 */
3463 if (sdev->lun == 0)
3464 boardp->device[sdev->id] = sdev;
3465
3466 if (ASC_NARROW_BOARD(boardp))
3467 advansys_narrow_slave_configure(sdev,
3468 &boardp->dvc_var.asc_dvc_var);
3469 else
3470 advansys_wide_slave_configure(sdev,
3471 &boardp->dvc_var.adv_dvc_var);
3472
27c868c2 3473 return 0;
1da177e4
LT
3474}
3475
1da177e4
LT
3476/*
3477 * Execute a single 'Scsi_Cmnd'.
3478 *
3479 * The function 'done' is called when the request has been completed.
3480 *
3481 * Scsi_Cmnd:
3482 *
3483 * host - board controlling device
3484 * device - device to send command
3485 * target - target of device
3486 * lun - lun of device
3487 * cmd_len - length of SCSI CDB
3488 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
3489 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
3490 *
3491 * if (use_sg == 0) {
3492 * request_buffer - buffer address for request
3493 * request_bufflen - length of request buffer
3494 * } else {
3495 * request_buffer - pointer to scatterlist structure
3496 * }
3497 *
3498 * sense_buffer - sense command buffer
3499 *
3500 * result (4 bytes of an int):
3501 * Byte Meaning
3502 * 0 SCSI Status Byte Code
3503 * 1 SCSI One Byte Message Code
3504 * 2 Host Error Code
3505 * 3 Mid-Level Error Code
3506 *
3507 * host driver fields:
3508 * SCp - Scsi_Pointer used for command processing status
3509 * scsi_done - used to save caller's done function
3510 * host_scribble - used for pointer to another struct scsi_cmnd
3511 *
349d2c44
MW
3512 * If this function returns ASC_NOERROR the request will be completed
3513 * from the interrupt handler.
1da177e4 3514 *
6ed1ef07
MW
3515 * If this function returns ASC_ERROR the host error code has been set,
3516 * and the called must call asc_scsi_done.
1da177e4 3517 *
b6622925
MW
3518 * If ASC_BUSY is returned the request will be returned to the midlayer
3519 * and re-tried later.
1da177e4 3520 */
27c868c2 3521static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 3522{
27c868c2
MW
3523 asc_board_t *boardp;
3524 ASC_DVC_VAR *asc_dvc_varp;
3525 ADV_DVC_VAR *adv_dvc_varp;
3526 ADV_SCSI_REQ_Q *adv_scsiqp;
3527 struct scsi_device *device;
3528 int ret;
3529
3530 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
3531 (ulong)scp, (ulong)scp->scsi_done);
3532
3533 boardp = ASC_BOARDP(scp->device->host);
3534 device = boardp->device[scp->device->id];
3535
3536 if (ASC_NARROW_BOARD(boardp)) {
3537 /*
3538 * Build and execute Narrow Board request.
3539 */
3540
3541 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3542
3543 /*
3544 * Build Asc Library request structure using the
3545 * global structures 'asc_scsi_req' and 'asc_sg_head'.
3546 *
3547 * If an error is returned, then the request has been
3548 * queued on the board done queue. It will be completed
3549 * by the caller.
3550 *
3551 * asc_build_req() can not return ASC_BUSY.
3552 */
3553 if (asc_build_req(boardp, scp) == ASC_ERROR) {
3554 ASC_STATS(scp->device->host, build_error);
3555 return ASC_ERROR;
3556 }
3557
27c868c2
MW
3558 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
3559 case ASC_NOERROR:
3560 ASC_STATS(scp->device->host, exe_noerror);
3561 /*
ecec1947
MW
3562 * Increment monotonically increasing per device
3563 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
3564 */
3565 boardp->reqcnt[scp->device->id]++;
ecec1947
MW
3566 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
3567 "ASC_NOERROR\n");
27c868c2
MW
3568 break;
3569 case ASC_BUSY:
27c868c2
MW
3570 ASC_STATS(scp->device->host, exe_busy);
3571 break;
3572 case ASC_ERROR:
ecec1947
MW
3573 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3574 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
3575 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3576 ASC_STATS(scp->device->host, exe_error);
3577 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3578 break;
3579 default:
ecec1947
MW
3580 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3581 "AscExeScsiQueue() unknown, err_code 0x%x\n",
3582 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3583 ASC_STATS(scp->device->host, exe_unknown);
3584 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3585 break;
3586 }
3587 } else {
3588 /*
3589 * Build and execute Wide Board request.
3590 */
3591 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3592
3593 /*
3594 * Build and get a pointer to an Adv Library request structure.
3595 *
3596 * If the request is successfully built then send it below,
3597 * otherwise return with an error.
3598 */
3599 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
3600 case ASC_NOERROR:
ecec1947
MW
3601 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
3602 "ASC_NOERROR\n");
27c868c2
MW
3603 break;
3604 case ASC_BUSY:
ecec1947
MW
3605 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
3606 "ASC_BUSY\n");
27c868c2 3607 /*
ecec1947
MW
3608 * The asc_stats fields 'adv_build_noreq' and
3609 * 'adv_build_nosg' count wide board busy conditions.
3610 * They are updated in adv_build_req and
3611 * adv_get_sglist, respectively.
27c868c2
MW
3612 */
3613 return ASC_BUSY;
3614 case ASC_ERROR:
27c868c2 3615 default:
ecec1947
MW
3616 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
3617 "ASC_ERROR\n");
27c868c2
MW
3618 ASC_STATS(scp->device->host, build_error);
3619 return ASC_ERROR;
3620 }
1da177e4 3621
27c868c2
MW
3622 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
3623 case ASC_NOERROR:
3624 ASC_STATS(scp->device->host, exe_noerror);
3625 /*
ecec1947
MW
3626 * Increment monotonically increasing per device
3627 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
3628 */
3629 boardp->reqcnt[scp->device->id]++;
ecec1947
MW
3630 ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
3631 "ASC_NOERROR\n");
27c868c2
MW
3632 break;
3633 case ASC_BUSY:
27c868c2
MW
3634 ASC_STATS(scp->device->host, exe_busy);
3635 break;
3636 case ASC_ERROR:
ecec1947
MW
3637 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3638 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
3639 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
3640 ASC_STATS(scp->device->host, exe_error);
3641 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3642 break;
3643 default:
ecec1947
MW
3644 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3645 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
3646 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
3647 ASC_STATS(scp->device->host, exe_unknown);
3648 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3649 break;
3650 }
3651 }
3652
3653 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
3654 return ret;
1da177e4
LT
3655}
3656
3657/*
3658 * Build a request structure for the Asc Library (Narrow Board).
3659 *
3660 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
3661 * used to build the request.
3662 *
6ed1ef07 3663 * If an error occurs, then return ASC_ERROR.
1da177e4 3664 */
27c868c2 3665static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 3666{
27c868c2
MW
3667 /*
3668 * Mutually exclusive access is required to 'asc_scsi_q' and
3669 * 'asc_sg_head' until after the request is started.
3670 */
3671 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
3672
3673 /*
3674 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
3675 */
3676 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
3677
3678 /*
3679 * Build the ASC_SCSI_Q request.
27c868c2 3680 */
27c868c2
MW
3681 asc_scsi_q.cdbptr = &scp->cmnd[0];
3682 asc_scsi_q.q2.cdb_len = scp->cmd_len;
3683 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
3684 asc_scsi_q.q1.target_lun = scp->device->lun;
3685 asc_scsi_q.q2.target_ix =
3686 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
3687 asc_scsi_q.q1.sense_addr =
3688 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
3689 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
3690
3691 /*
3692 * If there are any outstanding requests for the current target,
3693 * then every 255th request send an ORDERED request. This heuristic
3694 * tries to retain the benefit of request sorting while preventing
3695 * request starvation. 255 is the max number of tags or pending commands
3696 * a device may have outstanding.
3697 *
3698 * The request count is incremented below for every successfully
3699 * started request.
3700 *
3701 */
3702 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
3703 (boardp->reqcnt[scp->device->id] % 255) == 0) {
3704 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
3705 } else {
3706 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
3707 }
1da177e4 3708
27c868c2
MW
3709 /*
3710 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
3711 * buffer command.
3712 */
3713 if (scp->use_sg == 0) {
3714 /*
3715 * CDB request of single contiguous buffer.
3716 */
3717 ASC_STATS(scp->device->host, cont_cnt);
3718 scp->SCp.dma_handle = scp->request_bufflen ?
394dbf3f 3719 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
3720 scp->request_bufflen,
3721 scp->sc_data_direction) : 0;
3722 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
3723 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
3724 ASC_STATS_ADD(scp->device->host, cont_xfer,
3725 ASC_CEILING(scp->request_bufflen, 512));
3726 asc_scsi_q.q1.sg_queue_cnt = 0;
3727 asc_scsi_q.sg_head = NULL;
3728 } else {
3729 /*
3730 * CDB scatter-gather request list.
3731 */
3732 int sgcnt;
3733 int use_sg;
3734 struct scatterlist *slp;
3735
3736 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
3737 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
3738 scp->sc_data_direction);
27c868c2
MW
3739
3740 if (use_sg > scp->device->host->sg_tablesize) {
394dbf3f
MW
3741 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
3742 "sg_tablesize %d\n", boardp->id, use_sg,
3743 scp->device->host->sg_tablesize);
3744 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
3745 scp->sc_data_direction);
3746 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3747 return ASC_ERROR;
3748 }
3749
3750 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 3751
27c868c2
MW
3752 /*
3753 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
3754 * structure to point to it.
3755 */
3756 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
3757
3758 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
3759 asc_scsi_q.sg_head = &asc_sg_head;
3760 asc_scsi_q.q1.data_cnt = 0;
3761 asc_scsi_q.q1.data_addr = 0;
3762 /* This is a byte value, otherwise it would need to be swapped. */
3763 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
3764 ASC_STATS_ADD(scp->device->host, sg_elem,
3765 asc_sg_head.entry_cnt);
1da177e4 3766
27c868c2
MW
3767 /*
3768 * Convert scatter-gather list into ASC_SG_HEAD list.
3769 */
3770 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
3771 asc_sg_head.sg_list[sgcnt].addr =
3772 cpu_to_le32(sg_dma_address(slp));
3773 asc_sg_head.sg_list[sgcnt].bytes =
3774 cpu_to_le32(sg_dma_len(slp));
3775 ASC_STATS_ADD(scp->device->host, sg_xfer,
3776 ASC_CEILING(sg_dma_len(slp), 512));
3777 }
3778 }
1da177e4 3779
27c868c2
MW
3780 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
3781 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 3782
27c868c2 3783 return ASC_NOERROR;
1da177e4
LT
3784}
3785
3786/*
3787 * Build a request structure for the Adv Library (Wide Board).
3788 *
3789 * If an adv_req_t can not be allocated to issue the request,
3790 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
3791 *
3792 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
3793 * microcode for DMA addresses or math operations are byte swapped
3794 * to little-endian order.
3795 */
27c868c2 3796static int
1da177e4 3797adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 3798 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 3799{
27c868c2
MW
3800 adv_req_t *reqp;
3801 ADV_SCSI_REQ_Q *scsiqp;
3802 int i;
3803 int ret;
27c868c2
MW
3804
3805 /*
3806 * Allocate an adv_req_t structure from the board to execute
3807 * the command.
3808 */
3809 if (boardp->adv_reqp == NULL) {
3810 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
3811 ASC_STATS(scp->device->host, adv_build_noreq);
3812 return ASC_BUSY;
3813 } else {
3814 reqp = boardp->adv_reqp;
3815 boardp->adv_reqp = reqp->next_reqp;
3816 reqp->next_reqp = NULL;
3817 }
1da177e4 3818
27c868c2
MW
3819 /*
3820 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
3821 */
3822 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
3823
3824 /*
3825 * Initialize the structure.
3826 */
3827 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
3828
3829 /*
3830 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
3831 */
3832 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
3833
3834 /*
3835 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
3836 */
3837 reqp->cmndp = scp;
3838
3839 /*
3840 * Build the ADV_SCSI_REQ_Q request.
3841 */
3842
f05ec594 3843 /* Set CDB length and copy it to the request structure. */
27c868c2
MW
3844 scsiqp->cdb_len = scp->cmd_len;
3845 /* Copy first 12 CDB bytes to cdb[]. */
3846 for (i = 0; i < scp->cmd_len && i < 12; i++) {
3847 scsiqp->cdb[i] = scp->cmnd[i];
3848 }
3849 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
3850 for (; i < scp->cmd_len; i++) {
3851 scsiqp->cdb16[i - 12] = scp->cmnd[i];
3852 }
1da177e4 3853
27c868c2
MW
3854 scsiqp->target_id = scp->device->id;
3855 scsiqp->target_lun = scp->device->lun;
1da177e4 3856
27c868c2
MW
3857 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
3858 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 3859
27c868c2
MW
3860 /*
3861 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
3862 * buffer command.
3863 */
1da177e4 3864
1da177e4 3865 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
3866 scsiqp->vdata_addr = scp->request_buffer;
3867 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 3868
27c868c2
MW
3869 if (scp->use_sg == 0) {
3870 /*
3871 * CDB request of single contiguous buffer.
3872 */
3873 reqp->sgblkp = NULL;
3874 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
3875 if (scp->request_bufflen) {
3876 scsiqp->vdata_addr = scp->request_buffer;
3877 scp->SCp.dma_handle =
394dbf3f 3878 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
3879 scp->request_bufflen,
3880 scp->sc_data_direction);
3881 } else {
3882 scsiqp->vdata_addr = NULL;
3883 scp->SCp.dma_handle = 0;
3884 }
3885 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
3886 scsiqp->sg_list_ptr = NULL;
3887 scsiqp->sg_real_addr = 0;
3888 ASC_STATS(scp->device->host, cont_cnt);
3889 ASC_STATS_ADD(scp->device->host, cont_xfer,
3890 ASC_CEILING(scp->request_bufflen, 512));
3891 } else {
3892 /*
3893 * CDB scatter-gather request list.
3894 */
3895 struct scatterlist *slp;
3896 int use_sg;
3897
3898 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
3899 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
3900 scp->sc_data_direction);
27c868c2
MW
3901
3902 if (use_sg > ADV_MAX_SG_LIST) {
394dbf3f
MW
3903 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
3904 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
3905 scp->device->host->sg_tablesize);
3906 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
3907 scp->sc_data_direction);
3908 scp->result = HOST_BYTE(DID_ERROR);
27c868c2
MW
3909
3910 /*
394dbf3f
MW
3911 * Free the 'adv_req_t' structure by adding it back
3912 * to the board free list.
27c868c2
MW
3913 */
3914 reqp->next_reqp = boardp->adv_reqp;
3915 boardp->adv_reqp = reqp;
3916
3917 return ASC_ERROR;
3918 }
3919
394dbf3f
MW
3920 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
3921 if (ret != ADV_SUCCESS) {
27c868c2 3922 /*
394dbf3f
MW
3923 * Free the adv_req_t structure by adding it back to
3924 * the board free list.
27c868c2
MW
3925 */
3926 reqp->next_reqp = boardp->adv_reqp;
3927 boardp->adv_reqp = reqp;
3928
3929 return ret;
3930 }
3931
3932 ASC_STATS(scp->device->host, sg_cnt);
3933 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
3934 }
1da177e4 3935
27c868c2
MW
3936 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
3937 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 3938
27c868c2 3939 *adv_scsiqpp = scsiqp;
1da177e4 3940
27c868c2 3941 return ASC_NOERROR;
1da177e4
LT
3942}
3943
3944/*
3945 * Build scatter-gather list for Adv Library (Wide Board).
3946 *
3947 * Additional ADV_SG_BLOCK structures will need to be allocated
3948 * if the total number of scatter-gather elements exceeds
3949 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
3950 * assumed to be physically contiguous.
3951 *
3952 * Return:
3953 * ADV_SUCCESS(1) - SG List successfully created
3954 * ADV_ERROR(-1) - SG List creation failed
3955 */
27c868c2
MW
3956static int
3957adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
3958 int use_sg)
1da177e4 3959{
27c868c2
MW
3960 adv_sgblk_t *sgblkp;
3961 ADV_SCSI_REQ_Q *scsiqp;
3962 struct scatterlist *slp;
3963 int sg_elem_cnt;
3964 ADV_SG_BLOCK *sg_block, *prev_sg_block;
3965 ADV_PADDR sg_block_paddr;
3966 int i;
3967
3968 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
3969 slp = (struct scatterlist *)scp->request_buffer;
3970 sg_elem_cnt = use_sg;
3971 prev_sg_block = NULL;
3972 reqp->sgblkp = NULL;
3973
95c9f162 3974 for (;;) {
27c868c2
MW
3975 /*
3976 * Allocate a 'adv_sgblk_t' structure from the board free
3977 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
3978 * (15) scatter-gather elements.
3979 */
3980 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
3981 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
3982 ASC_STATS(scp->device->host, adv_build_nosg);
3983
3984 /*
95c9f162
MW
3985 * Allocation failed. Free 'adv_sgblk_t' structures
3986 * already allocated for the request.
27c868c2
MW
3987 */
3988 while ((sgblkp = reqp->sgblkp) != NULL) {
3989 /* Remove 'sgblkp' from the request list. */
3990 reqp->sgblkp = sgblkp->next_sgblkp;
3991
3992 /* Add 'sgblkp' to the board free list. */
3993 sgblkp->next_sgblkp = boardp->adv_sgblkp;
3994 boardp->adv_sgblkp = sgblkp;
3995 }
3996 return ASC_BUSY;
95c9f162
MW
3997 }
3998
3999 /* Complete 'adv_sgblk_t' board allocation. */
4000 boardp->adv_sgblkp = sgblkp->next_sgblkp;
4001 sgblkp->next_sgblkp = NULL;
4002
4003 /*
4004 * Get 8 byte aligned virtual and physical addresses
4005 * for the allocated ADV_SG_BLOCK structure.
4006 */
4007 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
4008 sg_block_paddr = virt_to_bus(sg_block);
4009
4010 /*
4011 * Check if this is the first 'adv_sgblk_t' for the
4012 * request.
4013 */
4014 if (reqp->sgblkp == NULL) {
4015 /* Request's first scatter-gather block. */
4016 reqp->sgblkp = sgblkp;
27c868c2
MW
4017
4018 /*
95c9f162
MW
4019 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
4020 * address pointers.
27c868c2 4021 */
95c9f162
MW
4022 scsiqp->sg_list_ptr = sg_block;
4023 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
4024 } else {
4025 /* Request's second or later scatter-gather block. */
4026 sgblkp->next_sgblkp = reqp->sgblkp;
4027 reqp->sgblkp = sgblkp;
27c868c2
MW
4028
4029 /*
95c9f162
MW
4030 * Point the previous ADV_SG_BLOCK structure to
4031 * the newly allocated ADV_SG_BLOCK structure.
27c868c2 4032 */
95c9f162 4033 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
27c868c2
MW
4034 }
4035
4036 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
4037 sg_block->sg_list[i].sg_addr =
95c9f162 4038 cpu_to_le32(sg_dma_address(slp));
27c868c2 4039 sg_block->sg_list[i].sg_count =
95c9f162 4040 cpu_to_le32(sg_dma_len(slp));
27c868c2
MW
4041 ASC_STATS_ADD(scp->device->host, sg_xfer,
4042 ASC_CEILING(sg_dma_len(slp), 512));
4043
4044 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
4045 sg_block->sg_cnt = i + 1;
4046 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
4047 return ADV_SUCCESS;
4048 }
4049 slp++;
4050 }
4051 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
4052 prev_sg_block = sg_block;
4053 }
1da177e4
LT
4054}
4055
4056/*
4057 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
4058 *
4059 * Interrupt callback function for the Narrow SCSI Asc Library.
4060 */
27c868c2 4061static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 4062{
27c868c2
MW
4063 asc_board_t *boardp;
4064 struct scsi_cmnd *scp;
4065 struct Scsi_Host *shost;
27c868c2
MW
4066
4067 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
4068 (ulong)asc_dvc_varp, (ulong)qdonep);
4069 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
4070
4071 /*
4072 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4073 * command that has been completed.
4074 */
4075 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
4076 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
4077
4078 if (scp == NULL) {
4079 ASC_PRINT("asc_isr_callback: scp is NULL\n");
4080 return;
4081 }
4082 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4083
27c868c2 4084 shost = scp->device->host;
27c868c2
MW
4085 ASC_STATS(shost, callback);
4086 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
4087
27c868c2 4088 boardp = ASC_BOARDP(shost);
b009bef6 4089 BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
1da177e4 4090
27c868c2
MW
4091 /*
4092 * 'qdonep' contains the command's ending status.
4093 */
4094 switch (qdonep->d3.done_stat) {
4095 case QD_NO_ERROR:
4096 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
4097 scp->result = 0;
1da177e4 4098
27c868c2
MW
4099 /*
4100 * Check for an underrun condition.
4101 *
4102 * If there was no error and an underrun condition, then
47d853cc 4103 * return the number of underrun bytes.
27c868c2
MW
4104 */
4105 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
4106 qdonep->remain_bytes <= scp->request_bufflen) {
4107 ASC_DBG1(1,
4108 "asc_isr_callback: underrun condition %u bytes\n",
4109 (unsigned)qdonep->remain_bytes);
4110 scp->resid = qdonep->remain_bytes;
4111 }
4112 break;
4113
4114 case QD_WITH_ERROR:
4115 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
4116 switch (qdonep->d3.host_stat) {
4117 case QHSTA_NO_ERROR:
4118 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
4119 ASC_DBG(2,
4120 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4121 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4122 sizeof(scp->sense_buffer));
4123 /*
95c9f162
MW
4124 * Note: The 'status_byte()' macro used by
4125 * target drivers defined in scsi.h shifts the
4126 * status byte returned by host drivers right
4127 * by 1 bit. This is why target drivers also
4128 * use right shifted status byte definitions.
4129 * For instance target drivers use
4130 * CHECK_CONDITION, defined to 0x1, instead of
4131 * the SCSI defined check condition value of
4132 * 0x2. Host drivers are supposed to return
4133 * the status byte as it is defined by SCSI.
27c868c2
MW
4134 */
4135 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4136 STATUS_BYTE(qdonep->d3.scsi_stat);
4137 } else {
4138 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
4139 }
4140 break;
4141
4142 default:
4143 /* QHSTA error occurred */
4144 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
4145 qdonep->d3.host_stat);
4146 scp->result = HOST_BYTE(DID_BAD_TARGET);
4147 break;
4148 }
4149 break;
4150
4151 case QD_ABORTED_BY_HOST:
4152 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
4153 scp->result =
4154 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
4155 scsi_msg) |
4156 STATUS_BYTE(qdonep->d3.scsi_stat);
4157 break;
4158
4159 default:
4160 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
4161 qdonep->d3.done_stat);
4162 scp->result =
4163 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
4164 scsi_msg) |
4165 STATUS_BYTE(qdonep->d3.scsi_stat);
4166 break;
4167 }
1da177e4 4168
27c868c2
MW
4169 /*
4170 * If the 'init_tidmask' bit isn't already set for the target and the
4171 * current request finished normally, then set the bit for the target
4172 * to indicate that a device is present.
4173 */
4174 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4175 qdonep->d3.done_stat == QD_NO_ERROR &&
4176 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
4177 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4178 }
1da177e4 4179
6ed1ef07 4180 asc_scsi_done(scp);
1da177e4 4181
27c868c2 4182 return;
1da177e4
LT
4183}
4184
4185/*
4186 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
4187 *
4188 * Callback function for the Wide SCSI Adv Library.
4189 */
27c868c2 4190static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 4191{
27c868c2
MW
4192 asc_board_t *boardp;
4193 adv_req_t *reqp;
4194 adv_sgblk_t *sgblkp;
4195 struct scsi_cmnd *scp;
4196 struct Scsi_Host *shost;
27c868c2
MW
4197 ADV_DCNT resid_cnt;
4198
4199 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
4200 (ulong)adv_dvc_varp, (ulong)scsiqp);
4201 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4202
4203 /*
4204 * Get the adv_req_t structure for the command that has been
4205 * completed. The adv_req_t structure actually contains the
4206 * completed ADV_SCSI_REQ_Q structure.
4207 */
4208 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
4209 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
4210 if (reqp == NULL) {
4211 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
4212 return;
4213 }
1da177e4 4214
27c868c2
MW
4215 /*
4216 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4217 * command that has been completed.
4218 *
4219 * Note: The adv_req_t request structure and adv_sgblk_t structure,
4220 * if any, are dropped, because a board structure pointer can not be
4221 * determined.
4222 */
4223 scp = reqp->cmndp;
4224 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
4225 if (scp == NULL) {
4226 ASC_PRINT
4227 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
4228 return;
4229 }
4230 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4231
27c868c2 4232 shost = scp->device->host;
27c868c2
MW
4233 ASC_STATS(shost, callback);
4234 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
4235
27c868c2 4236 boardp = ASC_BOARDP(shost);
b009bef6 4237 BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
1da177e4 4238
27c868c2
MW
4239 /*
4240 * 'done_status' contains the command's ending status.
4241 */
4242 switch (scsiqp->done_status) {
4243 case QD_NO_ERROR:
4244 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
4245 scp->result = 0;
1da177e4 4246
27c868c2
MW
4247 /*
4248 * Check for an underrun condition.
4249 *
4250 * If there was no error and an underrun condition, then
4251 * then return the number of underrun bytes.
4252 */
4253 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
4254 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
4255 resid_cnt <= scp->request_bufflen) {
4256 ASC_DBG1(1,
4257 "adv_isr_callback: underrun condition %lu bytes\n",
4258 (ulong)resid_cnt);
4259 scp->resid = resid_cnt;
4260 }
4261 break;
4262
4263 case QD_WITH_ERROR:
4264 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
4265 switch (scsiqp->host_status) {
4266 case QHSTA_NO_ERROR:
4267 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
4268 ASC_DBG(2,
4269 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4270 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4271 sizeof(scp->sense_buffer));
4272 /*
95c9f162
MW
4273 * Note: The 'status_byte()' macro used by
4274 * target drivers defined in scsi.h shifts the
4275 * status byte returned by host drivers right
4276 * by 1 bit. This is why target drivers also
4277 * use right shifted status byte definitions.
4278 * For instance target drivers use
4279 * CHECK_CONDITION, defined to 0x1, instead of
4280 * the SCSI defined check condition value of
4281 * 0x2. Host drivers are supposed to return
4282 * the status byte as it is defined by SCSI.
27c868c2
MW
4283 */
4284 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4285 STATUS_BYTE(scsiqp->scsi_status);
4286 } else {
4287 scp->result = STATUS_BYTE(scsiqp->scsi_status);
4288 }
4289 break;
4290
4291 default:
4292 /* Some other QHSTA error occurred. */
4293 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
4294 scsiqp->host_status);
4295 scp->result = HOST_BYTE(DID_BAD_TARGET);
4296 break;
4297 }
4298 break;
4299
4300 case QD_ABORTED_BY_HOST:
4301 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
4302 scp->result =
4303 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
4304 break;
4305
4306 default:
4307 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
4308 scsiqp->done_status);
4309 scp->result =
4310 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
4311 break;
4312 }
1da177e4 4313
27c868c2
MW
4314 /*
4315 * If the 'init_tidmask' bit isn't already set for the target and the
4316 * current request finished normally, then set the bit for the target
4317 * to indicate that a device is present.
4318 */
4319 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4320 scsiqp->done_status == QD_NO_ERROR &&
4321 scsiqp->host_status == QHSTA_NO_ERROR) {
4322 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4323 }
1da177e4 4324
6ed1ef07 4325 asc_scsi_done(scp);
27c868c2
MW
4326
4327 /*
4328 * Free all 'adv_sgblk_t' structures allocated for the request.
4329 */
4330 while ((sgblkp = reqp->sgblkp) != NULL) {
4331 /* Remove 'sgblkp' from the request list. */
4332 reqp->sgblkp = sgblkp->next_sgblkp;
4333
4334 /* Add 'sgblkp' to the board free list. */
4335 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4336 boardp->adv_sgblkp = sgblkp;
4337 }
1da177e4 4338
27c868c2
MW
4339 /*
4340 * Free the adv_req_t structure used with the command by adding
4341 * it back to the board free list.
4342 */
4343 reqp->next_reqp = boardp->adv_reqp;
4344 boardp->adv_reqp = reqp;
1da177e4 4345
27c868c2 4346 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 4347
27c868c2 4348 return;
1da177e4
LT
4349}
4350
4351/*
4352 * adv_async_callback() - Adv Library asynchronous event callback function.
4353 */
27c868c2 4354static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 4355{
27c868c2
MW
4356 switch (code) {
4357 case ADV_ASYNC_SCSI_BUS_RESET_DET:
4358 /*
4359 * The firmware detected a SCSI Bus reset.
4360 */
4361 ASC_DBG(0,
4362 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
4363 break;
4364
4365 case ADV_ASYNC_RDMA_FAILURE:
4366 /*
4367 * Handle RDMA failure by resetting the SCSI Bus and
4368 * possibly the chip if it is unresponsive. Log the error
4369 * with a unique code.
4370 */
4371 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
4372 AdvResetChipAndSB(adv_dvc_varp);
4373 break;
4374
4375 case ADV_HOST_SCSI_BUS_RESET:
4376 /*
4377 * Host generated SCSI bus reset occurred.
4378 */
4379 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
4380 break;
4381
4382 default:
4383 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
4384 break;
4385 }
1da177e4
LT
4386}
4387
1da177e4
LT
4388#ifdef CONFIG_PROC_FS
4389/*
4390 * asc_prt_board_devices()
4391 *
4392 * Print driver information for devices attached to the board.
4393 *
4394 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4395 * cf. asc_prt_line().
4396 *
4397 * Return the number of characters copied into 'cp'. No more than
4398 * 'cplen' characters will be copied to 'cp'.
4399 */
27c868c2 4400static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4401{
27c868c2
MW
4402 asc_board_t *boardp;
4403 int leftlen;
4404 int totlen;
4405 int len;
4406 int chip_scsi_id;
4407 int i;
4408
4409 boardp = ASC_BOARDP(shost);
4410 leftlen = cplen;
4411 totlen = len = 0;
4412
4413 len = asc_prt_line(cp, leftlen,
4414 "\nDevice Information for AdvanSys SCSI Host %d:\n",
4415 shost->host_no);
4416 ASC_PRT_NEXT();
4417
4418 if (ASC_NARROW_BOARD(boardp)) {
4419 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
4420 } else {
4421 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
4422 }
1da177e4 4423
27c868c2
MW
4424 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
4425 ASC_PRT_NEXT();
4426 for (i = 0; i <= ADV_MAX_TID; i++) {
4427 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
4428 len = asc_prt_line(cp, leftlen, " %X,", i);
4429 ASC_PRT_NEXT();
4430 }
4431 }
4432 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
4433 ASC_PRT_NEXT();
1da177e4 4434
27c868c2 4435 return totlen;
1da177e4
LT
4436}
4437
4438/*
4439 * Display Wide Board BIOS Information.
4440 */
27c868c2 4441static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4442{
27c868c2
MW
4443 asc_board_t *boardp;
4444 int leftlen;
4445 int totlen;
4446 int len;
4447 ushort major, minor, letter;
4448
4449 boardp = ASC_BOARDP(shost);
4450 leftlen = cplen;
4451 totlen = len = 0;
4452
4453 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
4454 ASC_PRT_NEXT();
4455
4456 /*
4457 * If the BIOS saved a valid signature, then fill in
4458 * the BIOS code segment base address.
4459 */
4460 if (boardp->bios_signature != 0x55AA) {
4461 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
4462 ASC_PRT_NEXT();
4463 len = asc_prt_line(cp, leftlen,
4464 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
4465 ASC_PRT_NEXT();
4466 len = asc_prt_line(cp, leftlen,
4467 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
4468 ASC_PRT_NEXT();
4469 } else {
4470 major = (boardp->bios_version >> 12) & 0xF;
4471 minor = (boardp->bios_version >> 8) & 0xF;
4472 letter = (boardp->bios_version & 0xFF);
1da177e4 4473
27c868c2
MW
4474 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
4475 major, minor,
4476 letter >= 26 ? '?' : letter + 'A');
4477 ASC_PRT_NEXT();
1da177e4 4478
27c868c2
MW
4479 /*
4480 * Current available ROM BIOS release is 3.1I for UW
4481 * and 3.2I for U2W. This code doesn't differentiate
4482 * UW and U2W boards.
4483 */
4484 if (major < 3 || (major <= 3 && minor < 1) ||
4485 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
4486 len = asc_prt_line(cp, leftlen,
4487 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
4488 ASC_PRT_NEXT();
4489 len = asc_prt_line(cp, leftlen,
4490 "ftp://ftp.connectcom.net/pub\n");
4491 ASC_PRT_NEXT();
4492 }
4493 }
1da177e4 4494
27c868c2 4495 return totlen;
1da177e4
LT
4496}
4497
4498/*
4499 * Add serial number to information bar if signature AAh
4500 * is found in at bit 15-9 (7 bits) of word 1.
4501 *
4502 * Serial Number consists fo 12 alpha-numeric digits.
4503 *
4504 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
4505 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
4506 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
4507 * 5 - Product revision (A-J) Word0: " "
4508 *
4509 * Signature Word1: 15-9 (7 bits)
4510 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
4511 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
4512 *
4513 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
4514 *
4515 * Note 1: Only production cards will have a serial number.
4516 *
4517 * Note 2: Signature is most significant 7 bits (0xFE).
4518 *
4519 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
4520 */
27c868c2 4521static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 4522{
27c868c2
MW
4523 ushort w, num;
4524
4525 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
4526 return ASC_FALSE;
4527 } else {
4528 /*
4529 * First word - 6 digits.
4530 */
4531 w = serialnum[0];
4532
4533 /* Product type - 1st digit. */
4534 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
4535 /* Product type is P=Prototype */
4536 *cp += 0x8;
4537 }
4538 cp++;
4539
4540 /* Manufacturing location - 2nd digit. */
4541 *cp++ = 'A' + ((w & 0x1C00) >> 10);
4542
4543 /* Product ID - 3rd, 4th digits. */
4544 num = w & 0x3FF;
4545 *cp++ = '0' + (num / 100);
4546 num %= 100;
4547 *cp++ = '0' + (num / 10);
4548
4549 /* Product revision - 5th digit. */
4550 *cp++ = 'A' + (num % 10);
4551
4552 /*
4553 * Second word
4554 */
4555 w = serialnum[1];
4556
4557 /*
4558 * Year - 6th digit.
4559 *
4560 * If bit 15 of third word is set, then the
4561 * last digit of the year is greater than 7.
4562 */
4563 if (serialnum[2] & 0x8000) {
4564 *cp++ = '8' + ((w & 0x1C0) >> 6);
4565 } else {
4566 *cp++ = '0' + ((w & 0x1C0) >> 6);
4567 }
4568
4569 /* Week of year - 7th, 8th digits. */
4570 num = w & 0x003F;
4571 *cp++ = '0' + num / 10;
4572 num %= 10;
4573 *cp++ = '0' + num;
4574
4575 /*
4576 * Third word
4577 */
4578 w = serialnum[2] & 0x7FFF;
4579
4580 /* Serial number - 9th digit. */
4581 *cp++ = 'A' + (w / 1000);
4582
4583 /* 10th, 11th, 12th digits. */
4584 num = w % 1000;
4585 *cp++ = '0' + num / 100;
4586 num %= 100;
4587 *cp++ = '0' + num / 10;
4588 num %= 10;
4589 *cp++ = '0' + num;
4590
4591 *cp = '\0'; /* Null Terminate the string. */
4592 return ASC_TRUE;
4593 }
1da177e4
LT
4594}
4595
4596/*
4597 * asc_prt_asc_board_eeprom()
4598 *
4599 * Print board EEPROM configuration.
4600 *
4601 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4602 * cf. asc_prt_line().
4603 *
4604 * Return the number of characters copied into 'cp'. No more than
4605 * 'cplen' characters will be copied to 'cp'.
4606 */
27c868c2 4607static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4608{
27c868c2
MW
4609 asc_board_t *boardp;
4610 ASC_DVC_VAR *asc_dvc_varp;
4611 int leftlen;
4612 int totlen;
4613 int len;
4614 ASCEEP_CONFIG *ep;
4615 int i;
1da177e4 4616#ifdef CONFIG_ISA
27c868c2 4617 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 4618#endif /* CONFIG_ISA */
27c868c2
MW
4619 uchar serialstr[13];
4620
4621 boardp = ASC_BOARDP(shost);
4622 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4623 ep = &boardp->eep_config.asc_eep;
4624
4625 leftlen = cplen;
4626 totlen = len = 0;
4627
4628 len = asc_prt_line(cp, leftlen,
4629 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
4630 shost->host_no);
4631 ASC_PRT_NEXT();
4632
4633 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
4634 == ASC_TRUE) {
4635 len =
4636 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
4637 serialstr);
4638 ASC_PRT_NEXT();
4639 } else {
4640 if (ep->adapter_info[5] == 0xBB) {
4641 len = asc_prt_line(cp, leftlen,
4642 " Default Settings Used for EEPROM-less Adapter.\n");
4643 ASC_PRT_NEXT();
4644 } else {
4645 len = asc_prt_line(cp, leftlen,
4646 " Serial Number Signature Not Present.\n");
4647 ASC_PRT_NEXT();
4648 }
4649 }
1da177e4 4650
27c868c2
MW
4651 len = asc_prt_line(cp, leftlen,
4652 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4653 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
4654 ep->max_tag_qng);
4655 ASC_PRT_NEXT();
4656
4657 len = asc_prt_line(cp, leftlen,
4658 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
4659 ASC_PRT_NEXT();
4660
4661 len = asc_prt_line(cp, leftlen, " Target ID: ");
4662 ASC_PRT_NEXT();
4663 for (i = 0; i <= ASC_MAX_TID; i++) {
4664 len = asc_prt_line(cp, leftlen, " %d", i);
4665 ASC_PRT_NEXT();
4666 }
4667 len = asc_prt_line(cp, leftlen, "\n");
4668 ASC_PRT_NEXT();
4669
4670 len = asc_prt_line(cp, leftlen, " Disconnects: ");
4671 ASC_PRT_NEXT();
4672 for (i = 0; i <= ASC_MAX_TID; i++) {
4673 len = asc_prt_line(cp, leftlen, " %c",
4674 (ep->
4675 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4676 'N');
4677 ASC_PRT_NEXT();
4678 }
4679 len = asc_prt_line(cp, leftlen, "\n");
4680 ASC_PRT_NEXT();
4681
4682 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
4683 ASC_PRT_NEXT();
4684 for (i = 0; i <= ASC_MAX_TID; i++) {
4685 len = asc_prt_line(cp, leftlen, " %c",
4686 (ep->
4687 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4688 'N');
4689 ASC_PRT_NEXT();
4690 }
4691 len = asc_prt_line(cp, leftlen, "\n");
4692 ASC_PRT_NEXT();
4693
4694 len = asc_prt_line(cp, leftlen, " Start Motor: ");
4695 ASC_PRT_NEXT();
4696 for (i = 0; i <= ASC_MAX_TID; i++) {
4697 len = asc_prt_line(cp, leftlen, " %c",
4698 (ep->
4699 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4700 'N');
4701 ASC_PRT_NEXT();
4702 }
4703 len = asc_prt_line(cp, leftlen, "\n");
4704 ASC_PRT_NEXT();
4705
4706 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
4707 ASC_PRT_NEXT();
4708 for (i = 0; i <= ASC_MAX_TID; i++) {
4709 len = asc_prt_line(cp, leftlen, " %c",
4710 (ep->
4711 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4712 'N');
4713 ASC_PRT_NEXT();
4714 }
4715 len = asc_prt_line(cp, leftlen, "\n");
4716 ASC_PRT_NEXT();
1da177e4
LT
4717
4718#ifdef CONFIG_ISA
27c868c2
MW
4719 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4720 len = asc_prt_line(cp, leftlen,
4721 " Host ISA DMA speed: %d MB/S\n",
4722 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
4723 ASC_PRT_NEXT();
4724 }
1da177e4
LT
4725#endif /* CONFIG_ISA */
4726
27c868c2 4727 return totlen;
1da177e4
LT
4728}
4729
4730/*
4731 * asc_prt_adv_board_eeprom()
4732 *
4733 * Print board EEPROM configuration.
4734 *
4735 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4736 * cf. asc_prt_line().
4737 *
4738 * Return the number of characters copied into 'cp'. No more than
4739 * 'cplen' characters will be copied to 'cp'.
4740 */
27c868c2 4741static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 4742{
27c868c2
MW
4743 asc_board_t *boardp;
4744 ADV_DVC_VAR *adv_dvc_varp;
4745 int leftlen;
4746 int totlen;
4747 int len;
4748 int i;
4749 char *termstr;
4750 uchar serialstr[13];
4751 ADVEEP_3550_CONFIG *ep_3550 = NULL;
4752 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
4753 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
4754 ushort word;
4755 ushort *wordp;
4756 ushort sdtr_speed = 0;
4757
4758 boardp = ASC_BOARDP(shost);
4759 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4760 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4761 ep_3550 = &boardp->eep_config.adv_3550_eep;
4762 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4763 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4764 } else {
4765 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4766 }
1da177e4 4767
27c868c2
MW
4768 leftlen = cplen;
4769 totlen = len = 0;
1da177e4 4770
27c868c2
MW
4771 len = asc_prt_line(cp, leftlen,
4772 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
4773 shost->host_no);
4774 ASC_PRT_NEXT();
1da177e4 4775
27c868c2
MW
4776 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4777 wordp = &ep_3550->serial_number_word1;
4778 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4779 wordp = &ep_38C0800->serial_number_word1;
4780 } else {
4781 wordp = &ep_38C1600->serial_number_word1;
4782 }
1da177e4 4783
27c868c2
MW
4784 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
4785 len =
4786 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
4787 serialstr);
4788 ASC_PRT_NEXT();
4789 } else {
4790 len = asc_prt_line(cp, leftlen,
4791 " Serial Number Signature Not Present.\n");
4792 ASC_PRT_NEXT();
4793 }
1da177e4 4794
27c868c2
MW
4795 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4796 len = asc_prt_line(cp, leftlen,
4797 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4798 ep_3550->adapter_scsi_id,
4799 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
4800 ASC_PRT_NEXT();
4801 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4802 len = asc_prt_line(cp, leftlen,
4803 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4804 ep_38C0800->adapter_scsi_id,
4805 ep_38C0800->max_host_qng,
4806 ep_38C0800->max_dvc_qng);
4807 ASC_PRT_NEXT();
4808 } else {
4809 len = asc_prt_line(cp, leftlen,
4810 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
4811 ep_38C1600->adapter_scsi_id,
4812 ep_38C1600->max_host_qng,
4813 ep_38C1600->max_dvc_qng);
4814 ASC_PRT_NEXT();
4815 }
4816 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4817 word = ep_3550->termination;
4818 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4819 word = ep_38C0800->termination_lvd;
4820 } else {
4821 word = ep_38C1600->termination_lvd;
4822 }
4823 switch (word) {
4824 case 1:
4825 termstr = "Low Off/High Off";
4826 break;
4827 case 2:
4828 termstr = "Low Off/High On";
4829 break;
4830 case 3:
4831 termstr = "Low On/High On";
4832 break;
4833 default:
4834 case 0:
4835 termstr = "Automatic";
4836 break;
4837 }
1da177e4 4838
27c868c2
MW
4839 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4840 len = asc_prt_line(cp, leftlen,
4841 " termination: %u (%s), bios_ctrl: 0x%x\n",
4842 ep_3550->termination, termstr,
4843 ep_3550->bios_ctrl);
4844 ASC_PRT_NEXT();
4845 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4846 len = asc_prt_line(cp, leftlen,
4847 " termination: %u (%s), bios_ctrl: 0x%x\n",
4848 ep_38C0800->termination_lvd, termstr,
4849 ep_38C0800->bios_ctrl);
4850 ASC_PRT_NEXT();
4851 } else {
4852 len = asc_prt_line(cp, leftlen,
4853 " termination: %u (%s), bios_ctrl: 0x%x\n",
4854 ep_38C1600->termination_lvd, termstr,
4855 ep_38C1600->bios_ctrl);
4856 ASC_PRT_NEXT();
4857 }
1da177e4 4858
27c868c2
MW
4859 len = asc_prt_line(cp, leftlen, " Target ID: ");
4860 ASC_PRT_NEXT();
4861 for (i = 0; i <= ADV_MAX_TID; i++) {
4862 len = asc_prt_line(cp, leftlen, " %X", i);
4863 ASC_PRT_NEXT();
4864 }
4865 len = asc_prt_line(cp, leftlen, "\n");
4866 ASC_PRT_NEXT();
1da177e4 4867
27c868c2
MW
4868 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4869 word = ep_3550->disc_enable;
4870 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4871 word = ep_38C0800->disc_enable;
4872 } else {
4873 word = ep_38C1600->disc_enable;
4874 }
4875 len = asc_prt_line(cp, leftlen, " Disconnects: ");
4876 ASC_PRT_NEXT();
4877 for (i = 0; i <= ADV_MAX_TID; i++) {
4878 len = asc_prt_line(cp, leftlen, " %c",
4879 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
4880 ASC_PRT_NEXT();
4881 }
4882 len = asc_prt_line(cp, leftlen, "\n");
4883 ASC_PRT_NEXT();
1da177e4 4884
27c868c2
MW
4885 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4886 word = ep_3550->tagqng_able;
4887 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4888 word = ep_38C0800->tagqng_able;
4889 } else {
4890 word = ep_38C1600->tagqng_able;
4891 }
4892 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
4893 ASC_PRT_NEXT();
4894 for (i = 0; i <= ADV_MAX_TID; i++) {
4895 len = asc_prt_line(cp, leftlen, " %c",
4896 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
4897 ASC_PRT_NEXT();
4898 }
4899 len = asc_prt_line(cp, leftlen, "\n");
4900 ASC_PRT_NEXT();
4901
4902 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4903 word = ep_3550->start_motor;
4904 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4905 word = ep_38C0800->start_motor;
4906 } else {
4907 word = ep_38C1600->start_motor;
4908 }
4909 len = asc_prt_line(cp, leftlen, " Start Motor: ");
4910 ASC_PRT_NEXT();
4911 for (i = 0; i <= ADV_MAX_TID; i++) {
4912 len = asc_prt_line(cp, leftlen, " %c",
4913 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
4914 ASC_PRT_NEXT();
4915 }
4916 len = asc_prt_line(cp, leftlen, "\n");
4917 ASC_PRT_NEXT();
4918
4919 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4920 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
4921 ASC_PRT_NEXT();
4922 for (i = 0; i <= ADV_MAX_TID; i++) {
4923 len = asc_prt_line(cp, leftlen, " %c",
4924 (ep_3550->
4925 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
4926 'Y' : 'N');
4927 ASC_PRT_NEXT();
4928 }
4929 len = asc_prt_line(cp, leftlen, "\n");
4930 ASC_PRT_NEXT();
4931 }
4932
4933 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4934 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
4935 ASC_PRT_NEXT();
4936 for (i = 0; i <= ADV_MAX_TID; i++) {
4937 len = asc_prt_line(cp, leftlen, " %c",
4938 (ep_3550->
4939 ultra_able & ADV_TID_TO_TIDMASK(i))
4940 ? 'Y' : 'N');
4941 ASC_PRT_NEXT();
4942 }
4943 len = asc_prt_line(cp, leftlen, "\n");
4944 ASC_PRT_NEXT();
4945 }
4946
4947 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4948 word = ep_3550->wdtr_able;
4949 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4950 word = ep_38C0800->wdtr_able;
4951 } else {
4952 word = ep_38C1600->wdtr_able;
4953 }
4954 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
4955 ASC_PRT_NEXT();
4956 for (i = 0; i <= ADV_MAX_TID; i++) {
4957 len = asc_prt_line(cp, leftlen, " %c",
4958 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
4959 ASC_PRT_NEXT();
4960 }
4961 len = asc_prt_line(cp, leftlen, "\n");
4962 ASC_PRT_NEXT();
4963
4964 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
4965 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
4966 len = asc_prt_line(cp, leftlen,
4967 " Synchronous Transfer Speed (Mhz):\n ");
4968 ASC_PRT_NEXT();
4969 for (i = 0; i <= ADV_MAX_TID; i++) {
4970 char *speed_str;
4971
4972 if (i == 0) {
4973 sdtr_speed = adv_dvc_varp->sdtr_speed1;
4974 } else if (i == 4) {
4975 sdtr_speed = adv_dvc_varp->sdtr_speed2;
4976 } else if (i == 8) {
4977 sdtr_speed = adv_dvc_varp->sdtr_speed3;
4978 } else if (i == 12) {
4979 sdtr_speed = adv_dvc_varp->sdtr_speed4;
4980 }
4981 switch (sdtr_speed & ADV_MAX_TID) {
4982 case 0:
4983 speed_str = "Off";
4984 break;
4985 case 1:
4986 speed_str = " 5";
4987 break;
4988 case 2:
4989 speed_str = " 10";
4990 break;
4991 case 3:
4992 speed_str = " 20";
4993 break;
4994 case 4:
4995 speed_str = " 40";
4996 break;
4997 case 5:
4998 speed_str = " 80";
4999 break;
5000 default:
5001 speed_str = "Unk";
5002 break;
5003 }
5004 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
5005 ASC_PRT_NEXT();
5006 if (i == 7) {
5007 len = asc_prt_line(cp, leftlen, "\n ");
5008 ASC_PRT_NEXT();
5009 }
5010 sdtr_speed >>= 4;
5011 }
5012 len = asc_prt_line(cp, leftlen, "\n");
5013 ASC_PRT_NEXT();
5014 }
5015
5016 return totlen;
5017}
5018
5019/*
5020 * asc_prt_driver_conf()
5021 *
5022 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5023 * cf. asc_prt_line().
1da177e4
LT
5024 *
5025 * Return the number of characters copied into 'cp'. No more than
5026 * 'cplen' characters will be copied to 'cp'.
5027 */
27c868c2 5028static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5029{
27c868c2
MW
5030 asc_board_t *boardp;
5031 int leftlen;
5032 int totlen;
5033 int len;
5034 int chip_scsi_id;
5035
5036 boardp = ASC_BOARDP(shost);
5037
5038 leftlen = cplen;
5039 totlen = len = 0;
5040
5041 len = asc_prt_line(cp, leftlen,
5042 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
5043 shost->host_no);
5044 ASC_PRT_NEXT();
5045
5046 len = asc_prt_line(cp, leftlen,
5047 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
5048 shost->host_busy, shost->last_reset, shost->max_id,
5049 shost->max_lun, shost->max_channel);
5050 ASC_PRT_NEXT();
5051
5052 len = asc_prt_line(cp, leftlen,
5053 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
5054 shost->unique_id, shost->can_queue, shost->this_id,
5055 shost->sg_tablesize, shost->cmd_per_lun);
5056 ASC_PRT_NEXT();
5057
5058 len = asc_prt_line(cp, leftlen,
5059 " unchecked_isa_dma %d, use_clustering %d\n",
5060 shost->unchecked_isa_dma, shost->use_clustering);
5061 ASC_PRT_NEXT();
5062
5063 len = asc_prt_line(cp, leftlen,
5064 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
5065 boardp->flags, boardp->last_reset, jiffies,
5066 boardp->asc_n_io_port);
5067 ASC_PRT_NEXT();
5068
4a2d31c8 5069 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
27c868c2
MW
5070 ASC_PRT_NEXT();
5071
5072 if (ASC_NARROW_BOARD(boardp)) {
5073 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
5074 } else {
5075 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
5076 }
1da177e4 5077
27c868c2 5078 return totlen;
1da177e4
LT
5079}
5080
5081/*
5082 * asc_prt_asc_board_info()
5083 *
5084 * Print dynamic board configuration information.
5085 *
5086 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5087 * cf. asc_prt_line().
5088 *
5089 * Return the number of characters copied into 'cp'. No more than
5090 * 'cplen' characters will be copied to 'cp'.
5091 */
27c868c2 5092static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5093{
27c868c2
MW
5094 asc_board_t *boardp;
5095 int chip_scsi_id;
5096 int leftlen;
5097 int totlen;
5098 int len;
5099 ASC_DVC_VAR *v;
5100 ASC_DVC_CFG *c;
5101 int i;
5102 int renegotiate = 0;
5103
5104 boardp = ASC_BOARDP(shost);
5105 v = &boardp->dvc_var.asc_dvc_var;
5106 c = &boardp->dvc_cfg.asc_dvc_cfg;
5107 chip_scsi_id = c->chip_scsi_id;
5108
5109 leftlen = cplen;
5110 totlen = len = 0;
5111
5112 len = asc_prt_line(cp, leftlen,
5113 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5114 shost->host_no);
5115 ASC_PRT_NEXT();
5116
5117 len = asc_prt_line(cp, leftlen,
5118 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
5119 c->chip_version, c->lib_version, c->lib_serial_no,
5120 c->mcode_date);
5121 ASC_PRT_NEXT();
5122
5123 len = asc_prt_line(cp, leftlen,
5124 " mcode_version 0x%x, err_code %u\n",
5125 c->mcode_version, v->err_code);
5126 ASC_PRT_NEXT();
5127
5128 /* Current number of commands waiting for the host. */
5129 len = asc_prt_line(cp, leftlen,
5130 " Total Command Pending: %d\n", v->cur_total_qng);
5131 ASC_PRT_NEXT();
5132
5133 len = asc_prt_line(cp, leftlen, " Command Queuing:");
5134 ASC_PRT_NEXT();
5135 for (i = 0; i <= ASC_MAX_TID; i++) {
5136 if ((chip_scsi_id == i) ||
5137 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5138 continue;
5139 }
5140 len = asc_prt_line(cp, leftlen, " %X:%c",
5141 i,
5142 (v->
5143 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
5144 'Y' : 'N');
5145 ASC_PRT_NEXT();
5146 }
5147 len = asc_prt_line(cp, leftlen, "\n");
5148 ASC_PRT_NEXT();
5149
5150 /* Current number of commands waiting for a device. */
5151 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
5152 ASC_PRT_NEXT();
5153 for (i = 0; i <= ASC_MAX_TID; i++) {
5154 if ((chip_scsi_id == i) ||
5155 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5156 continue;
5157 }
5158 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
5159 ASC_PRT_NEXT();
5160 }
5161 len = asc_prt_line(cp, leftlen, "\n");
5162 ASC_PRT_NEXT();
5163
5164 /* Current limit on number of commands that can be sent to a device. */
5165 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
5166 ASC_PRT_NEXT();
5167 for (i = 0; i <= ASC_MAX_TID; i++) {
5168 if ((chip_scsi_id == i) ||
5169 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5170 continue;
5171 }
5172 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
5173 ASC_PRT_NEXT();
5174 }
5175 len = asc_prt_line(cp, leftlen, "\n");
5176 ASC_PRT_NEXT();
5177
5178 /* Indicate whether the device has returned queue full status. */
5179 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
5180 ASC_PRT_NEXT();
5181 for (i = 0; i <= ASC_MAX_TID; i++) {
5182 if ((chip_scsi_id == i) ||
5183 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5184 continue;
5185 }
5186 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
5187 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
5188 i, boardp->queue_full_cnt[i]);
5189 } else {
5190 len = asc_prt_line(cp, leftlen, " %X:N", i);
5191 }
5192 ASC_PRT_NEXT();
5193 }
5194 len = asc_prt_line(cp, leftlen, "\n");
5195 ASC_PRT_NEXT();
5196
5197 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5198 ASC_PRT_NEXT();
5199 for (i = 0; i <= ASC_MAX_TID; i++) {
5200 if ((chip_scsi_id == i) ||
5201 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5202 continue;
5203 }
5204 len = asc_prt_line(cp, leftlen, " %X:%c",
5205 i,
5206 (v->
5207 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5208 'N');
5209 ASC_PRT_NEXT();
5210 }
5211 len = asc_prt_line(cp, leftlen, "\n");
5212 ASC_PRT_NEXT();
5213
5214 for (i = 0; i <= ASC_MAX_TID; i++) {
5215 uchar syn_period_ix;
5216
5217 if ((chip_scsi_id == i) ||
5218 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
5219 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
5220 continue;
5221 }
5222
5223 len = asc_prt_line(cp, leftlen, " %X:", i);
5224 ASC_PRT_NEXT();
5225
5226 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
5227 len = asc_prt_line(cp, leftlen, " Asynchronous");
5228 ASC_PRT_NEXT();
5229 } else {
5230 syn_period_ix =
5231 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
5232 1);
5233
5234 len = asc_prt_line(cp, leftlen,
5235 " Transfer Period Factor: %d (%d.%d Mhz),",
5236 v->sdtr_period_tbl[syn_period_ix],
5237 250 /
5238 v->sdtr_period_tbl[syn_period_ix],
5239 ASC_TENTHS(250,
5240 v->
5241 sdtr_period_tbl
5242 [syn_period_ix]));
5243 ASC_PRT_NEXT();
5244
5245 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
5246 boardp->
5247 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
5248 ASC_PRT_NEXT();
5249 }
5250
5251 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5252 len = asc_prt_line(cp, leftlen, "*\n");
5253 renegotiate = 1;
5254 } else {
5255 len = asc_prt_line(cp, leftlen, "\n");
5256 }
5257 ASC_PRT_NEXT();
5258 }
1da177e4 5259
27c868c2
MW
5260 if (renegotiate) {
5261 len = asc_prt_line(cp, leftlen,
5262 " * = Re-negotiation pending before next command.\n");
5263 ASC_PRT_NEXT();
5264 }
1da177e4 5265
27c868c2 5266 return totlen;
1da177e4
LT
5267}
5268
5269/*
5270 * asc_prt_adv_board_info()
5271 *
5272 * Print dynamic board configuration information.
5273 *
5274 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5275 * cf. asc_prt_line().
5276 *
5277 * Return the number of characters copied into 'cp'. No more than
5278 * 'cplen' characters will be copied to 'cp'.
5279 */
27c868c2 5280static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5281{
27c868c2
MW
5282 asc_board_t *boardp;
5283 int leftlen;
5284 int totlen;
5285 int len;
5286 int i;
5287 ADV_DVC_VAR *v;
5288 ADV_DVC_CFG *c;
5289 AdvPortAddr iop_base;
5290 ushort chip_scsi_id;
5291 ushort lramword;
5292 uchar lrambyte;
5293 ushort tagqng_able;
5294 ushort sdtr_able, wdtr_able;
5295 ushort wdtr_done, sdtr_done;
5296 ushort period = 0;
5297 int renegotiate = 0;
5298
5299 boardp = ASC_BOARDP(shost);
5300 v = &boardp->dvc_var.adv_dvc_var;
5301 c = &boardp->dvc_cfg.adv_dvc_cfg;
5302 iop_base = v->iop_base;
5303 chip_scsi_id = v->chip_scsi_id;
5304
5305 leftlen = cplen;
5306 totlen = len = 0;
5307
5308 len = asc_prt_line(cp, leftlen,
5309 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5310 shost->host_no);
5311 ASC_PRT_NEXT();
5312
5313 len = asc_prt_line(cp, leftlen,
5314 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
5315 v->iop_base,
5316 AdvReadWordRegister(iop_base,
5317 IOPW_SCSI_CFG1) & CABLE_DETECT,
5318 v->err_code);
5319 ASC_PRT_NEXT();
5320
5321 len = asc_prt_line(cp, leftlen,
5322 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
5323 c->chip_version, c->lib_version, c->mcode_date,
5324 c->mcode_version);
5325 ASC_PRT_NEXT();
5326
5327 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
5328 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
5329 ASC_PRT_NEXT();
5330 for (i = 0; i <= ADV_MAX_TID; i++) {
5331 if ((chip_scsi_id == i) ||
5332 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5333 continue;
5334 }
5335
5336 len = asc_prt_line(cp, leftlen, " %X:%c",
5337 i,
5338 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5339 'N');
5340 ASC_PRT_NEXT();
5341 }
5342 len = asc_prt_line(cp, leftlen, "\n");
5343 ASC_PRT_NEXT();
5344
5345 len = asc_prt_line(cp, leftlen, " Queue Limit:");
5346 ASC_PRT_NEXT();
5347 for (i = 0; i <= ADV_MAX_TID; i++) {
5348 if ((chip_scsi_id == i) ||
5349 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5350 continue;
5351 }
5352
5353 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
5354 lrambyte);
5355
5356 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
5357 ASC_PRT_NEXT();
5358 }
5359 len = asc_prt_line(cp, leftlen, "\n");
5360 ASC_PRT_NEXT();
5361
5362 len = asc_prt_line(cp, leftlen, " Command Pending:");
5363 ASC_PRT_NEXT();
5364 for (i = 0; i <= ADV_MAX_TID; i++) {
5365 if ((chip_scsi_id == i) ||
5366 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5367 continue;
5368 }
5369
5370 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
5371 lrambyte);
5372
5373 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
5374 ASC_PRT_NEXT();
5375 }
5376 len = asc_prt_line(cp, leftlen, "\n");
5377 ASC_PRT_NEXT();
5378
5379 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
5380 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
5381 ASC_PRT_NEXT();
5382 for (i = 0; i <= ADV_MAX_TID; i++) {
5383 if ((chip_scsi_id == i) ||
5384 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5385 continue;
5386 }
5387
5388 len = asc_prt_line(cp, leftlen, " %X:%c",
5389 i,
5390 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5391 'N');
5392 ASC_PRT_NEXT();
5393 }
5394 len = asc_prt_line(cp, leftlen, "\n");
5395 ASC_PRT_NEXT();
5396
5397 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
5398 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
5399 ASC_PRT_NEXT();
5400 for (i = 0; i <= ADV_MAX_TID; i++) {
5401 if ((chip_scsi_id == i) ||
5402 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5403 continue;
5404 }
5405
5406 AdvReadWordLram(iop_base,
5407 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
5408 lramword);
5409
5410 len = asc_prt_line(cp, leftlen, " %X:%d",
5411 i, (lramword & 0x8000) ? 16 : 8);
5412 ASC_PRT_NEXT();
5413
5414 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
5415 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5416 len = asc_prt_line(cp, leftlen, "*");
5417 ASC_PRT_NEXT();
5418 renegotiate = 1;
5419 }
5420 }
5421 len = asc_prt_line(cp, leftlen, "\n");
5422 ASC_PRT_NEXT();
5423
5424 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
5425 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
5426 ASC_PRT_NEXT();
5427 for (i = 0; i <= ADV_MAX_TID; i++) {
5428 if ((chip_scsi_id == i) ||
5429 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5430 continue;
5431 }
5432
5433 len = asc_prt_line(cp, leftlen, " %X:%c",
5434 i,
5435 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5436 'N');
5437 ASC_PRT_NEXT();
5438 }
5439 len = asc_prt_line(cp, leftlen, "\n");
5440 ASC_PRT_NEXT();
5441
5442 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
5443 for (i = 0; i <= ADV_MAX_TID; i++) {
5444
5445 AdvReadWordLram(iop_base,
5446 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
5447 lramword);
5448 lramword &= ~0x8000;
5449
5450 if ((chip_scsi_id == i) ||
5451 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
5452 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
5453 continue;
5454 }
5455
5456 len = asc_prt_line(cp, leftlen, " %X:", i);
5457 ASC_PRT_NEXT();
5458
5459 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
5460 len = asc_prt_line(cp, leftlen, " Asynchronous");
5461 ASC_PRT_NEXT();
5462 } else {
5463 len =
5464 asc_prt_line(cp, leftlen,
5465 " Transfer Period Factor: ");
5466 ASC_PRT_NEXT();
5467
5468 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
5469 len =
5470 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
5471 ASC_PRT_NEXT();
5472 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
5473 len =
5474 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
5475 ASC_PRT_NEXT();
5476 } else { /* 20 Mhz or below. */
5477
5478 period = (((lramword >> 8) * 25) + 50) / 4;
5479
5480 if (period == 0) { /* Should never happen. */
5481 len =
5482 asc_prt_line(cp, leftlen,
5483 "%d (? Mhz), ");
5484 ASC_PRT_NEXT();
5485 } else {
5486 len = asc_prt_line(cp, leftlen,
5487 "%d (%d.%d Mhz),",
5488 period, 250 / period,
5489 ASC_TENTHS(250,
5490 period));
5491 ASC_PRT_NEXT();
5492 }
5493 }
5494
5495 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
5496 lramword & 0x1F);
5497 ASC_PRT_NEXT();
5498 }
5499
5500 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5501 len = asc_prt_line(cp, leftlen, "*\n");
5502 renegotiate = 1;
5503 } else {
5504 len = asc_prt_line(cp, leftlen, "\n");
5505 }
5506 ASC_PRT_NEXT();
5507 }
1da177e4 5508
27c868c2
MW
5509 if (renegotiate) {
5510 len = asc_prt_line(cp, leftlen,
5511 " * = Re-negotiation pending before next command.\n");
5512 ASC_PRT_NEXT();
5513 }
1da177e4 5514
27c868c2 5515 return totlen;
1da177e4
LT
5516}
5517
5518/*
5519 * asc_proc_copy()
5520 *
5521 * Copy proc information to a read buffer taking into account the current
5522 * read offset in the file and the remaining space in the read buffer.
5523 */
27c868c2 5524static int
1da177e4 5525asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 5526 char *cp, int cplen)
1da177e4 5527{
27c868c2
MW
5528 int cnt = 0;
5529
5530 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
5531 (unsigned)offset, (unsigned)advoffset, cplen);
5532 if (offset <= advoffset) {
5533 /* Read offset below current offset, copy everything. */
5534 cnt = min(cplen, leftlen);
5535 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
5536 (ulong)curbuf, (ulong)cp, cnt);
5537 memcpy(curbuf, cp, cnt);
5538 } else if (offset < advoffset + cplen) {
5539 /* Read offset within current range, partial copy. */
5540 cnt = (advoffset + cplen) - offset;
5541 cp = (cp + cplen) - cnt;
5542 cnt = min(cnt, leftlen);
5543 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
5544 (ulong)curbuf, (ulong)cp, cnt);
5545 memcpy(curbuf, cp, cnt);
5546 }
5547 return cnt;
1da177e4
LT
5548}
5549
5550/*
5551 * asc_prt_line()
5552 *
5553 * If 'cp' is NULL print to the console, otherwise print to a buffer.
5554 *
5555 * Return 0 if printing to the console, otherwise return the number of
5556 * bytes written to the buffer.
5557 *
5558 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
5559 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
5560 */
27c868c2 5561static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 5562{
27c868c2
MW
5563 va_list args;
5564 int ret;
5565 char s[ASC_PRTLINE_SIZE];
5566
5567 va_start(args, fmt);
5568 ret = vsprintf(s, fmt, args);
b009bef6 5569 BUG_ON(ret >= ASC_PRTLINE_SIZE);
27c868c2
MW
5570 if (buf == NULL) {
5571 (void)printk(s);
5572 ret = 0;
5573 } else {
5574 ret = min(buflen, ret);
5575 memcpy(buf, s, ret);
5576 }
5577 va_end(args);
5578 return ret;
1da177e4
LT
5579}
5580#endif /* CONFIG_PROC_FS */
5581
1da177e4
LT
5582/*
5583 * void
5584 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
5585 *
5586 * Calling/Exit State:
5587 * none
5588 *
5589 * Description:
5590 * Output an ASC_SCSI_Q structure to the chip
5591 */
27c868c2 5592static void
1da177e4
LT
5593DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
5594{
27c868c2
MW
5595 int i;
5596
5597 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
5598 AscSetChipLramAddr(iop_base, s_addr);
5599 for (i = 0; i < 2 * words; i += 2) {
5600 if (i == 4 || i == 20) {
5601 continue;
5602 }
5603 outpw(iop_base + IOP_RAM_DATA,
5604 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
5605 }
1da177e4
LT
5606}
5607
5608/*
5609 * void
5610 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
5611 *
5612 * Calling/Exit State:
5613 * none
5614 *
5615 * Description:
5616 * Input an ASC_QDONE_INFO structure from the chip
5617 */
27c868c2 5618static void
1da177e4
LT
5619DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
5620{
27c868c2
MW
5621 int i;
5622 ushort word;
5623
5624 AscSetChipLramAddr(iop_base, s_addr);
5625 for (i = 0; i < 2 * words; i += 2) {
5626 if (i == 10) {
5627 continue;
5628 }
5629 word = inpw(iop_base + IOP_RAM_DATA);
5630 inbuf[i] = word & 0xff;
5631 inbuf[i + 1] = (word >> 8) & 0xff;
5632 }
5633 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
5634}
5635
1da177e4
LT
5636/*
5637 * Return the BIOS address of the adapter at the specified
5638 * I/O port and with the specified bus type.
5639 */
ecec1947
MW
5640static unsigned short __devinit
5641AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
1da177e4 5642{
ecec1947
MW
5643 unsigned short cfg_lsw;
5644 unsigned short bios_addr;
27c868c2
MW
5645
5646 /*
5647 * The PCI BIOS is re-located by the motherboard BIOS. Because
5648 * of this the driver can not determine where a PCI BIOS is
5649 * loaded and executes.
5650 */
ecec1947
MW
5651 if (bus_type & ASC_IS_PCI)
5652 return 0;
5653
1da177e4 5654#ifdef CONFIG_ISA
27c868c2
MW
5655 if ((bus_type & ASC_IS_EISA) != 0) {
5656 cfg_lsw = AscGetEisaChipCfg(iop_base);
5657 cfg_lsw &= 0x000F;
ecec1947
MW
5658 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
5659 return bios_addr;
5660 }
1da177e4
LT
5661#endif /* CONFIG_ISA */
5662
27c868c2 5663 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 5664
27c868c2
MW
5665 /*
5666 * ISA PnP uses the top bit as the 32K BIOS flag
5667 */
ecec1947 5668 if (bus_type == ASC_IS_ISAPNP)
27c868c2 5669 cfg_lsw &= 0x7FFF;
ecec1947
MW
5670 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
5671 return bios_addr;
1da177e4
LT
5672}
5673
1da177e4
LT
5674/*
5675 * DvcGetPhyAddr()
5676 *
5677 * Return the physical address of 'vaddr' and set '*lenp' to the
5678 * number of physically contiguous bytes that follow 'vaddr'.
5679 * 'flag' indicates the type of structure whose physical address
5680 * is being translated.
5681 *
5682 * Note: Because Linux currently doesn't page the kernel and all
5683 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
5684 */
5685ADV_PADDR
5686DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 5687 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 5688{
27c868c2 5689 ADV_PADDR paddr;
1da177e4 5690
27c868c2 5691 paddr = virt_to_bus(vaddr);
1da177e4 5692
27c868c2
MW
5693 ASC_DBG4(4,
5694 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
5695 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
5696 (ulong)paddr);
1da177e4 5697
27c868c2 5698 return paddr;
1da177e4
LT
5699}
5700
1da177e4
LT
5701#ifdef ADVANSYS_STATS
5702#ifdef CONFIG_PROC_FS
5703/*
5704 * asc_prt_board_stats()
5705 *
5706 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5707 * cf. asc_prt_line().
5708 *
5709 * Return the number of characters copied into 'cp'. No more than
5710 * 'cplen' characters will be copied to 'cp'.
5711 */
27c868c2 5712static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5713{
27c868c2
MW
5714 int leftlen;
5715 int totlen;
5716 int len;
5717 struct asc_stats *s;
5718 asc_board_t *boardp;
1da177e4 5719
27c868c2
MW
5720 leftlen = cplen;
5721 totlen = len = 0;
5722
5723 boardp = ASC_BOARDP(shost);
5724 s = &boardp->asc_stats;
5725
5726 len = asc_prt_line(cp, leftlen,
5727 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
5728 shost->host_no);
5729 ASC_PRT_NEXT();
5730
5731 len = asc_prt_line(cp, leftlen,
5732 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
5733 s->queuecommand, s->reset, s->biosparam,
5734 s->interrupt);
5735 ASC_PRT_NEXT();
5736
5737 len = asc_prt_line(cp, leftlen,
5738 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
5739 s->callback, s->done, s->build_error,
5740 s->adv_build_noreq, s->adv_build_nosg);
5741 ASC_PRT_NEXT();
5742
5743 len = asc_prt_line(cp, leftlen,
5744 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
5745 s->exe_noerror, s->exe_busy, s->exe_error,
5746 s->exe_unknown);
5747 ASC_PRT_NEXT();
5748
5749 /*
5750 * Display data transfer statistics.
5751 */
5752 if (s->cont_cnt > 0) {
5753 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
5754 ASC_PRT_NEXT();
5755
5756 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
5757 s->cont_xfer / 2,
5758 ASC_TENTHS(s->cont_xfer, 2));
5759 ASC_PRT_NEXT();
5760
5761 /* Contiguous transfer average size */
5762 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
5763 (s->cont_xfer / 2) / s->cont_cnt,
5764 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
5765 ASC_PRT_NEXT();
5766 }
1da177e4 5767
27c868c2 5768 if (s->sg_cnt > 0) {
1da177e4 5769
27c868c2
MW
5770 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
5771 s->sg_cnt, s->sg_elem);
5772 ASC_PRT_NEXT();
1da177e4 5773
27c868c2
MW
5774 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
5775 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
5776 ASC_PRT_NEXT();
1da177e4 5777
27c868c2
MW
5778 /* Scatter gather transfer statistics */
5779 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
5780 s->sg_elem / s->sg_cnt,
5781 ASC_TENTHS(s->sg_elem, s->sg_cnt));
5782 ASC_PRT_NEXT();
1da177e4 5783
27c868c2
MW
5784 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
5785 (s->sg_xfer / 2) / s->sg_elem,
5786 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
5787 ASC_PRT_NEXT();
1da177e4 5788
27c868c2
MW
5789 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
5790 (s->sg_xfer / 2) / s->sg_cnt,
5791 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
5792 ASC_PRT_NEXT();
5793 }
1da177e4 5794
27c868c2
MW
5795 /*
5796 * Display request queuing statistics.
5797 */
5798 len = asc_prt_line(cp, leftlen,
5799 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
5800 HZ);
5801 ASC_PRT_NEXT();
1da177e4 5802
27c868c2 5803 return totlen;
1da177e4 5804}
1da177e4
LT
5805#endif /* CONFIG_PROC_FS */
5806#endif /* ADVANSYS_STATS */
5807
5808#ifdef ADVANSYS_DEBUG
5809/*
5810 * asc_prt_scsi_host()
5811 */
27c868c2 5812static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 5813{
27c868c2
MW
5814 asc_board_t *boardp;
5815
5816 boardp = ASC_BOARDP(s);
5817
5818 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
5819 printk(" host_busy %u, host_no %d, last_reset %d,\n",
5820 s->host_busy, s->host_no, (unsigned)s->last_reset);
5821
4a2d31c8
MW
5822 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
5823 (ulong)s->base, (ulong)s->io_port, s->irq);
27c868c2
MW
5824
5825 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
5826 s->dma_channel, s->this_id, s->can_queue);
5827
5828 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
5829 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
5830
5831 if (ASC_NARROW_BOARD(boardp)) {
5832 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
5833 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
5834 } else {
5835 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
5836 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
5837 }
1da177e4
LT
5838}
5839
5840/*
5841 * asc_prt_scsi_cmnd()
5842 */
27c868c2 5843static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 5844{
27c868c2 5845 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 5846
27c868c2
MW
5847 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
5848 (ulong)s->device->host, (ulong)s->device, s->device->id,
5849 s->device->lun, s->device->channel);
1da177e4 5850
27c868c2 5851 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 5852
27c868c2
MW
5853 printk("sc_data_direction %u, resid %d\n",
5854 s->sc_data_direction, s->resid);
1da177e4 5855
27c868c2 5856 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 5857
27c868c2
MW
5858 printk(" serial_number 0x%x, retries %d, allowed %d\n",
5859 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 5860
27c868c2 5861 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 5862
ecec1947
MW
5863 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
5864 s->scsi_done, s->done, s->host_scribble, s->result);
1da177e4 5865
27c868c2 5866 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
5867}
5868
5869/*
5870 * asc_prt_asc_dvc_var()
5871 */
27c868c2 5872static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 5873{
27c868c2
MW
5874 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
5875
ecec1947
MW
5876 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
5877 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
27c868c2 5878
895d6b4c
MW
5879 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
5880 (unsigned)h->init_sdtr);
27c868c2 5881
ecec1947
MW
5882 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
5883 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
5884 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
5885 (unsigned)h->chip_no);
27c868c2 5886
ecec1947
MW
5887 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
5888 "%u,\n", (unsigned)h->queue_full_or_busy,
5889 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
27c868c2 5890
ecec1947
MW
5891 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
5892 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
5893 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
5894 (unsigned)h->in_critical_cnt);
27c868c2 5895
ecec1947
MW
5896 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
5897 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
5898 (unsigned)h->init_state, (unsigned)h->no_scam,
5899 (unsigned)h->pci_fix_asyn_xfer);
27c868c2
MW
5900
5901 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
5902}
5903
5904/*
5905 * asc_prt_asc_dvc_cfg()
5906 */
27c868c2 5907static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 5908{
27c868c2
MW
5909 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
5910
5911 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
5912 h->can_tagged_qng, h->cmd_qng_enabled);
5913 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
5914 h->disc_enable, h->sdtr_enable);
5915
5916 printk
5917 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
5918 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
5919 h->chip_version);
5920
5921 printk
5922 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
5923 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
5924 h->mcode_date);
5925
5926 printk(" mcode_version %d, overrun_buf 0x%lx\n",
5927 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
5928}
5929
5930/*
5931 * asc_prt_asc_scsi_q()
5932 */
27c868c2 5933static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 5934{
27c868c2
MW
5935 ASC_SG_HEAD *sgp;
5936 int i;
5937
5938 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
5939
5940 printk
5941 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
5942 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
5943 q->q2.tag_code);
5944
5945 printk
5946 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
5947 (ulong)le32_to_cpu(q->q1.data_addr),
5948 (ulong)le32_to_cpu(q->q1.data_cnt),
5949 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
5950
5951 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
5952 (ulong)q->cdbptr, q->q2.cdb_len,
5953 (ulong)q->sg_head, q->q1.sg_queue_cnt);
5954
5955 if (q->sg_head) {
5956 sgp = q->sg_head;
5957 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
5958 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
5959 sgp->queue_cnt);
5960 for (i = 0; i < sgp->entry_cnt; i++) {
5961 printk(" [%u]: addr 0x%lx, bytes %lu\n",
5962 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
5963 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
5964 }
1da177e4 5965
27c868c2 5966 }
1da177e4
LT
5967}
5968
5969/*
5970 * asc_prt_asc_qdone_info()
5971 */
27c868c2 5972static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 5973{
27c868c2
MW
5974 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
5975 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
5976 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
5977 q->d2.tag_code);
5978 printk
5979 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
5980 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
5981}
5982
5983/*
5984 * asc_prt_adv_dvc_var()
5985 *
5986 * Display an ADV_DVC_VAR structure.
5987 */
27c868c2 5988static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 5989{
27c868c2
MW
5990 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
5991
5992 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
5993 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
5994
5995 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
5996 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
5997 (unsigned)h->wdtr_able);
5998
5999 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
6000 (unsigned)h->start_motor,
6001 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
6002
6003 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
6004 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
6005 (ulong)h->carr_freelist);
6006
6007 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
6008 (ulong)h->icq_sp, (ulong)h->irq_sp);
6009
6010 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
6011 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
6012
6013 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
6014 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
6015}
6016
6017/*
6018 * asc_prt_adv_dvc_cfg()
6019 *
6020 * Display an ADV_DVC_CFG structure.
6021 */
27c868c2 6022static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 6023{
27c868c2 6024 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 6025
27c868c2
MW
6026 printk(" disc_enable 0x%x, termination 0x%x\n",
6027 h->disc_enable, h->termination);
1da177e4 6028
27c868c2
MW
6029 printk(" chip_version 0x%x, mcode_date 0x%x\n",
6030 h->chip_version, h->mcode_date);
1da177e4 6031
27c868c2
MW
6032 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
6033 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 6034
13ac2d9c 6035 printk(" control_flag 0x%x\n", h->control_flag);
1da177e4
LT
6036}
6037
6038/*
6039 * asc_prt_adv_scsi_req_q()
6040 *
6041 * Display an ADV_SCSI_REQ_Q structure.
6042 */
27c868c2 6043static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 6044{
27c868c2
MW
6045 int sg_blk_cnt;
6046 struct asc_sg_block *sg_ptr;
6047
6048 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
6049
6050 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
6051 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
6052
6053 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
6054 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
6055
6056 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6057 (ulong)le32_to_cpu(q->data_cnt),
6058 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
6059
6060 printk
6061 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
6062 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
6063
6064 printk(" sg_working_ix 0x%x, target_cmd %u\n",
6065 q->sg_working_ix, q->target_cmd);
6066
6067 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
6068 (ulong)le32_to_cpu(q->scsiq_rptr),
6069 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
6070
6071 /* Display the request's ADV_SG_BLOCK structures. */
6072 if (q->sg_list_ptr != NULL) {
6073 sg_blk_cnt = 0;
6074 while (1) {
6075 /*
6076 * 'sg_ptr' is a physical address. Convert it to a virtual
6077 * address by indexing 'sg_blk_cnt' into the virtual address
6078 * array 'sg_list_ptr'.
6079 *
6080 * XXX - Assumes all SG physical blocks are virtually contiguous.
6081 */
6082 sg_ptr =
6083 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
6084 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
6085 if (sg_ptr->sg_ptr == 0) {
6086 break;
6087 }
6088 sg_blk_cnt++;
6089 }
6090 }
1da177e4
LT
6091}
6092
6093/*
6094 * asc_prt_adv_sgblock()
6095 *
6096 * Display an ADV_SG_BLOCK structure.
6097 */
27c868c2 6098static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 6099{
27c868c2
MW
6100 int i;
6101
6102 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
6103 (ulong)b, sgblockno);
6104 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
6105 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
b009bef6
MW
6106 BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
6107 if (b->sg_ptr != 0)
6108 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
27c868c2
MW
6109 for (i = 0; i < b->sg_cnt; i++) {
6110 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
6111 i, (ulong)b->sg_list[i].sg_addr,
6112 (ulong)b->sg_list[i].sg_count);
6113 }
1da177e4
LT
6114}
6115
6116/*
6117 * asc_prt_hex()
6118 *
6119 * Print hexadecimal output in 4 byte groupings 32 bytes
6120 * or 8 double-words per line.
6121 */
27c868c2 6122static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 6123{
27c868c2
MW
6124 int i;
6125 int j;
6126 int k;
6127 int m;
6128
6129 printk("%s: (%d bytes)\n", f, l);
6130
6131 for (i = 0; i < l; i += 32) {
6132
6133 /* Display a maximum of 8 double-words per line. */
6134 if ((k = (l - i) / 4) >= 8) {
6135 k = 8;
6136 m = 0;
6137 } else {
6138 m = (l - i) % 4;
6139 }
6140
6141 for (j = 0; j < k; j++) {
6142 printk(" %2.2X%2.2X%2.2X%2.2X",
6143 (unsigned)s[i + (j * 4)],
6144 (unsigned)s[i + (j * 4) + 1],
6145 (unsigned)s[i + (j * 4) + 2],
6146 (unsigned)s[i + (j * 4) + 3]);
6147 }
6148
6149 switch (m) {
6150 case 0:
6151 default:
6152 break;
6153 case 1:
6154 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
6155 break;
6156 case 2:
6157 printk(" %2.2X%2.2X",
6158 (unsigned)s[i + (j * 4)],
6159 (unsigned)s[i + (j * 4) + 1]);
6160 break;
6161 case 3:
6162 printk(" %2.2X%2.2X%2.2X",
6163 (unsigned)s[i + (j * 4) + 1],
6164 (unsigned)s[i + (j * 4) + 2],
6165 (unsigned)s[i + (j * 4) + 3]);
6166 break;
6167 }
6168
6169 printk("\n");
6170 }
1da177e4
LT
6171}
6172#endif /* ADVANSYS_DEBUG */
6173
78e77d8b 6174static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 6175{
27c868c2 6176 PortAddr eisa_cfg_iop;
1da177e4 6177
27c868c2
MW
6178 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
6179 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
6180 return (inpw(eisa_cfg_iop));
1da177e4
LT
6181}
6182
78e77d8b 6183static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 6184{
27c868c2 6185 ushort cfg_lsw;
1da177e4 6186
27c868c2
MW
6187 if (AscGetChipScsiID(iop_base) == new_host_id) {
6188 return (new_host_id);
6189 }
6190 cfg_lsw = AscGetChipCfgLsw(iop_base);
6191 cfg_lsw &= 0xF8FF;
6192 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
6193 AscSetChipCfgLsw(iop_base, cfg_lsw);
6194 return (AscGetChipScsiID(iop_base));
1da177e4
LT
6195}
6196
ecec1947 6197static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 6198{
ecec1947 6199 unsigned char sc;
1da177e4 6200
27c868c2
MW
6201 AscSetBank(iop_base, 1);
6202 sc = inp(iop_base + IOP_REG_SC);
6203 AscSetBank(iop_base, 0);
ecec1947 6204 return sc;
1da177e4
LT
6205}
6206
ecec1947
MW
6207static unsigned char __devinit
6208AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
1da177e4 6209{
ecec1947 6210 if (bus_type & ASC_IS_EISA) {
27c868c2 6211 PortAddr eisa_iop;
ecec1947 6212 unsigned char revision;
27c868c2
MW
6213 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
6214 (PortAddr) ASC_EISA_REV_IOP_MASK;
6215 revision = inp(eisa_iop);
ecec1947 6216 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
27c868c2 6217 }
ecec1947 6218 return AscGetChipVerNo(iop_base);
1da177e4
LT
6219}
6220
27c868c2
MW
6221static ASC_DCNT
6222AscLoadMicroCode(PortAddr iop_base,
6223 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 6224{
27c868c2
MW
6225 ASC_DCNT chksum;
6226 ushort mcode_word_size;
6227 ushort mcode_chksum;
6228
6229 /* Write the microcode buffer starting at LRAM address 0. */
6230 mcode_word_size = (ushort)(mcode_size >> 1);
6231 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
6232 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
6233
6234 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
6235 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
6236 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
6237 (ushort)ASC_CODE_SEC_BEG,
6238 (ushort)((mcode_size -
6239 s_addr - (ushort)
6240 ASC_CODE_SEC_BEG) /
6241 2));
6242 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
6243 (ulong)mcode_chksum);
6244 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
6245 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
6246 return (chksum);
1da177e4
LT
6247}
6248
27c868c2 6249static int AscFindSignature(PortAddr iop_base)
1da177e4 6250{
27c868c2
MW
6251 ushort sig_word;
6252
6253 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
6254 iop_base, AscGetChipSignatureByte(iop_base));
6255 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
6256 ASC_DBG2(1,
6257 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
6258 iop_base, AscGetChipSignatureWord(iop_base));
6259 sig_word = AscGetChipSignatureWord(iop_base);
6260 if ((sig_word == (ushort)ASC_1000_ID0W) ||
6261 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
6262 return (1);
6263 }
6264 }
6265 return (0);
1da177e4
LT
6266}
6267
78e77d8b 6268static void __devinit AscToggleIRQAct(PortAddr iop_base)
1da177e4 6269{
27c868c2
MW
6270 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
6271 AscSetChipStatus(iop_base, 0);
6272 return;
1da177e4
LT
6273}
6274
78e77d8b 6275static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 6276{
27c868c2
MW
6277 ushort cfg_lsw;
6278 uchar chip_irq;
6279
6280 if ((bus_type & ASC_IS_EISA) != 0) {
6281 cfg_lsw = AscGetEisaChipCfg(iop_base);
6282 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
6283 if ((chip_irq == 13) || (chip_irq > 15)) {
6284 return (0);
6285 }
6286 return (chip_irq);
6287 }
6288 if ((bus_type & ASC_IS_VL) != 0) {
6289 cfg_lsw = AscGetChipCfgLsw(iop_base);
6290 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
6291 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
6292 return (0);
6293 }
6294 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
6295 }
6296 cfg_lsw = AscGetChipCfgLsw(iop_base);
6297 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
6298 if (chip_irq == 3)
6299 chip_irq += (uchar)2;
6300 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
6301}
6302
78e77d8b 6303static uchar __devinit
27c868c2 6304AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 6305{
27c868c2
MW
6306 ushort cfg_lsw;
6307
6308 if ((bus_type & ASC_IS_VL) != 0) {
6309 if (irq_no != 0) {
6310 if ((irq_no < ASC_MIN_IRQ_NO)
6311 || (irq_no > ASC_MAX_IRQ_NO)) {
6312 irq_no = 0;
6313 } else {
6314 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
6315 }
6316 }
6317 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
6318 cfg_lsw |= (ushort)0x0010;
6319 AscSetChipCfgLsw(iop_base, cfg_lsw);
6320 AscToggleIRQAct(iop_base);
6321 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
6322 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
6323 AscSetChipCfgLsw(iop_base, cfg_lsw);
6324 AscToggleIRQAct(iop_base);
6325 return (AscGetChipIRQ(iop_base, bus_type));
6326 }
6327 if ((bus_type & (ASC_IS_ISA)) != 0) {
6328 if (irq_no == 15)
6329 irq_no -= (uchar)2;
6330 irq_no -= (uchar)ASC_MIN_IRQ_NO;
6331 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
6332 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
6333 AscSetChipCfgLsw(iop_base, cfg_lsw);
6334 return (AscGetChipIRQ(iop_base, bus_type));
6335 }
6336 return (0);
1da177e4
LT
6337}
6338
6339#ifdef CONFIG_ISA
78e77d8b 6340static void __devinit AscEnableIsaDma(uchar dma_channel)
1da177e4 6341{
27c868c2
MW
6342 if (dma_channel < 4) {
6343 outp(0x000B, (ushort)(0xC0 | dma_channel));
6344 outp(0x000A, dma_channel);
6345 } else if (dma_channel < 8) {
6346 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
6347 outp(0x00D4, (ushort)(dma_channel - 4));
6348 }
6349 return;
1da177e4
LT
6350}
6351#endif /* CONFIG_ISA */
6352
27c868c2 6353static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 6354{
27c868c2
MW
6355 EXT_MSG ext_msg;
6356 EXT_MSG out_msg;
6357 ushort halt_q_addr;
6358 int sdtr_accept;
6359 ushort int_halt_code;
6360 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6361 ASC_SCSI_BIT_ID_TYPE target_id;
6362 PortAddr iop_base;
6363 uchar tag_code;
6364 uchar q_status;
6365 uchar halt_qp;
6366 uchar sdtr_data;
6367 uchar target_ix;
6368 uchar q_cntl, tid_no;
6369 uchar cur_dvc_qng;
6370 uchar asyn_sdtr;
6371 uchar scsi_status;
6372 asc_board_t *boardp;
6373
b009bef6 6374 BUG_ON(!asc_dvc->drv_ptr);
27c868c2
MW
6375 boardp = asc_dvc->drv_ptr;
6376
6377 iop_base = asc_dvc->iop_base;
6378 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
6379
6380 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
6381 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
6382 target_ix = AscReadLramByte(iop_base,
6383 (ushort)(halt_q_addr +
6384 (ushort)ASC_SCSIQ_B_TARGET_IX));
95c9f162 6385 q_cntl = AscReadLramByte(iop_base,
27c868c2
MW
6386 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6387 tid_no = ASC_TIX_TO_TID(target_ix);
6388 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
6389 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6390 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
6391 } else {
6392 asyn_sdtr = 0;
6393 }
6394 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
6395 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6396 AscSetChipSDTR(iop_base, 0, tid_no);
6397 boardp->sdtr_data[tid_no] = 0;
6398 }
6399 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6400 return (0);
6401 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
6402 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
6403 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6404 boardp->sdtr_data[tid_no] = asyn_sdtr;
6405 }
6406 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6407 return (0);
6408 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
27c868c2
MW
6409 AscMemWordCopyPtrFromLram(iop_base,
6410 ASCV_MSGIN_BEG,
6411 (uchar *)&ext_msg,
6412 sizeof(EXT_MSG) >> 1);
6413
47d853cc
MW
6414 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6415 ext_msg.msg_req == EXTENDED_SDTR &&
27c868c2
MW
6416 ext_msg.msg_len == MS_SDTR_LEN) {
6417 sdtr_accept = TRUE;
6418 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
6419
6420 sdtr_accept = FALSE;
6421 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
6422 }
6423 if ((ext_msg.xfer_period <
6424 asc_dvc->sdtr_period_tbl[asc_dvc->
6425 host_init_sdtr_index])
6426 || (ext_msg.xfer_period >
6427 asc_dvc->sdtr_period_tbl[asc_dvc->
6428 max_sdtr_index])) {
6429 sdtr_accept = FALSE;
6430 ext_msg.xfer_period =
6431 asc_dvc->sdtr_period_tbl[asc_dvc->
6432 host_init_sdtr_index];
6433 }
6434 if (sdtr_accept) {
6435 sdtr_data =
6436 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
6437 ext_msg.req_ack_offset);
6438 if ((sdtr_data == 0xFF)) {
6439
6440 q_cntl |= QC_MSG_OUT;
6441 asc_dvc->init_sdtr &= ~target_id;
6442 asc_dvc->sdtr_done &= ~target_id;
6443 AscSetChipSDTR(iop_base, asyn_sdtr,
6444 tid_no);
6445 boardp->sdtr_data[tid_no] = asyn_sdtr;
6446 }
6447 }
6448 if (ext_msg.req_ack_offset == 0) {
6449
6450 q_cntl &= ~QC_MSG_OUT;
6451 asc_dvc->init_sdtr &= ~target_id;
6452 asc_dvc->sdtr_done &= ~target_id;
6453 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6454 } else {
6455 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
6456
6457 q_cntl &= ~QC_MSG_OUT;
6458 asc_dvc->sdtr_done |= target_id;
6459 asc_dvc->init_sdtr |= target_id;
6460 asc_dvc->pci_fix_asyn_xfer &=
6461 ~target_id;
6462 sdtr_data =
6463 AscCalSDTRData(asc_dvc,
6464 ext_msg.xfer_period,
6465 ext_msg.
6466 req_ack_offset);
6467 AscSetChipSDTR(iop_base, sdtr_data,
6468 tid_no);
6469 boardp->sdtr_data[tid_no] = sdtr_data;
6470 } else {
6471
6472 q_cntl |= QC_MSG_OUT;
6473 AscMsgOutSDTR(asc_dvc,
6474 ext_msg.xfer_period,
6475 ext_msg.req_ack_offset);
6476 asc_dvc->pci_fix_asyn_xfer &=
6477 ~target_id;
6478 sdtr_data =
6479 AscCalSDTRData(asc_dvc,
6480 ext_msg.xfer_period,
6481 ext_msg.
6482 req_ack_offset);
6483 AscSetChipSDTR(iop_base, sdtr_data,
6484 tid_no);
6485 boardp->sdtr_data[tid_no] = sdtr_data;
6486 asc_dvc->sdtr_done |= target_id;
6487 asc_dvc->init_sdtr |= target_id;
6488 }
6489 }
6490
6491 AscWriteLramByte(iop_base,
6492 (ushort)(halt_q_addr +
6493 (ushort)ASC_SCSIQ_B_CNTL),
6494 q_cntl);
6495 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6496 return (0);
47d853cc
MW
6497 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
6498 ext_msg.msg_req == EXTENDED_WDTR &&
27c868c2
MW
6499 ext_msg.msg_len == MS_WDTR_LEN) {
6500
6501 ext_msg.wdtr_width = 0;
6502 AscMemWordCopyPtrToLram(iop_base,
6503 ASCV_MSGOUT_BEG,
6504 (uchar *)&ext_msg,
6505 sizeof(EXT_MSG) >> 1);
6506 q_cntl |= QC_MSG_OUT;
6507 AscWriteLramByte(iop_base,
6508 (ushort)(halt_q_addr +
6509 (ushort)ASC_SCSIQ_B_CNTL),
6510 q_cntl);
6511 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6512 return (0);
6513 } else {
6514
6515 ext_msg.msg_type = MESSAGE_REJECT;
6516 AscMemWordCopyPtrToLram(iop_base,
6517 ASCV_MSGOUT_BEG,
6518 (uchar *)&ext_msg,
6519 sizeof(EXT_MSG) >> 1);
6520 q_cntl |= QC_MSG_OUT;
6521 AscWriteLramByte(iop_base,
6522 (ushort)(halt_q_addr +
6523 (ushort)ASC_SCSIQ_B_CNTL),
6524 q_cntl);
6525 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6526 return (0);
6527 }
6528 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
6529
6530 q_cntl |= QC_REQ_SENSE;
6531
6532 if ((asc_dvc->init_sdtr & target_id) != 0) {
6533
6534 asc_dvc->sdtr_done &= ~target_id;
6535
6536 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
6537 q_cntl |= QC_MSG_OUT;
6538 AscMsgOutSDTR(asc_dvc,
6539 asc_dvc->
6540 sdtr_period_tbl[(sdtr_data >> 4) &
6541 (uchar)(asc_dvc->
6542 max_sdtr_index -
6543 1)],
6544 (uchar)(sdtr_data & (uchar)
6545 ASC_SYN_MAX_OFFSET));
6546 }
6547
6548 AscWriteLramByte(iop_base,
6549 (ushort)(halt_q_addr +
6550 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6551
6552 tag_code = AscReadLramByte(iop_base,
6553 (ushort)(halt_q_addr + (ushort)
6554 ASC_SCSIQ_B_TAG_CODE));
6555 tag_code &= 0xDC;
6556 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
6557 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
6558 ) {
6559
6560 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
6561 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
6562
6563 }
6564 AscWriteLramByte(iop_base,
6565 (ushort)(halt_q_addr +
6566 (ushort)ASC_SCSIQ_B_TAG_CODE),
6567 tag_code);
6568
6569 q_status = AscReadLramByte(iop_base,
6570 (ushort)(halt_q_addr + (ushort)
6571 ASC_SCSIQ_B_STATUS));
6572 q_status |= (QS_READY | QS_BUSY);
6573 AscWriteLramByte(iop_base,
6574 (ushort)(halt_q_addr +
6575 (ushort)ASC_SCSIQ_B_STATUS),
6576 q_status);
6577
6578 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
6579 scsi_busy &= ~target_id;
6580 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6581
6582 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6583 return (0);
6584 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
6585
6586 AscMemWordCopyPtrFromLram(iop_base,
6587 ASCV_MSGOUT_BEG,
6588 (uchar *)&out_msg,
6589 sizeof(EXT_MSG) >> 1);
6590
47d853cc 6591 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
27c868c2 6592 (out_msg.msg_len == MS_SDTR_LEN) &&
47d853cc 6593 (out_msg.msg_req == EXTENDED_SDTR)) {
27c868c2
MW
6594
6595 asc_dvc->init_sdtr &= ~target_id;
6596 asc_dvc->sdtr_done &= ~target_id;
6597 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
6598 boardp->sdtr_data[tid_no] = asyn_sdtr;
6599 }
6600 q_cntl &= ~QC_MSG_OUT;
6601 AscWriteLramByte(iop_base,
6602 (ushort)(halt_q_addr +
6603 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
6604 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6605 return (0);
6606 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
6607
6608 scsi_status = AscReadLramByte(iop_base,
6609 (ushort)((ushort)halt_q_addr +
6610 (ushort)
6611 ASC_SCSIQ_SCSI_STATUS));
6612 cur_dvc_qng =
6613 AscReadLramByte(iop_base,
6614 (ushort)((ushort)ASC_QADR_BEG +
6615 (ushort)target_ix));
6616 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
6617
6618 scsi_busy = AscReadLramByte(iop_base,
6619 (ushort)ASCV_SCSIBUSY_B);
6620 scsi_busy |= target_id;
6621 AscWriteLramByte(iop_base,
6622 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
6623 asc_dvc->queue_full_or_busy |= target_id;
6624
6625 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
6626 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
6627 cur_dvc_qng -= 1;
6628 asc_dvc->max_dvc_qng[tid_no] =
6629 cur_dvc_qng;
6630
6631 AscWriteLramByte(iop_base,
6632 (ushort)((ushort)
6633 ASCV_MAX_DVC_QNG_BEG
6634 + (ushort)
6635 tid_no),
6636 cur_dvc_qng);
6637
6638 /*
95c9f162
MW
6639 * Set the device queue depth to the
6640 * number of active requests when the
6641 * QUEUE FULL condition was encountered.
27c868c2
MW
6642 */
6643 boardp->queue_full |= target_id;
6644 boardp->queue_full_cnt[tid_no] =
6645 cur_dvc_qng;
6646 }
6647 }
6648 }
6649 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6650 return (0);
6651 }
1da177e4 6652#if CC_VERY_LONG_SG_LIST
27c868c2
MW
6653 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
6654 uchar q_no;
6655 ushort q_addr;
6656 uchar sg_wk_q_no;
6657 uchar first_sg_wk_q_no;
6658 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
6659 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
6660 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
6661 ushort sg_list_dwords;
6662 ushort sg_entry_cnt;
6663 uchar next_qp;
6664 int i;
6665
6666 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
95c9f162
MW
6667 if (q_no == ASC_QLINK_END)
6668 return 0;
27c868c2
MW
6669
6670 q_addr = ASC_QNO_TO_QADDR(q_no);
6671
6672 /*
6673 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
6674 * structure pointer using a macro provided by the driver.
6675 * The ASC_SCSI_REQ pointer provides a pointer to the
6676 * host ASC_SG_HEAD structure.
6677 */
6678 /* Read request's SRB pointer. */
6679 scsiq = (ASC_SCSI_Q *)
6680 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
6681 (ushort)
6682 (q_addr +
6683 ASC_SCSIQ_D_SRBPTR))));
6684
6685 /*
6686 * Get request's first and working SG queue.
6687 */
6688 sg_wk_q_no = AscReadLramByte(iop_base,
6689 (ushort)(q_addr +
6690 ASC_SCSIQ_B_SG_WK_QP));
6691
6692 first_sg_wk_q_no = AscReadLramByte(iop_base,
6693 (ushort)(q_addr +
6694 ASC_SCSIQ_B_FIRST_SG_WK_QP));
6695
6696 /*
6697 * Reset request's working SG queue back to the
6698 * first SG queue.
6699 */
6700 AscWriteLramByte(iop_base,
6701 (ushort)(q_addr +
6702 (ushort)ASC_SCSIQ_B_SG_WK_QP),
6703 first_sg_wk_q_no);
6704
6705 sg_head = scsiq->sg_head;
6706
6707 /*
6708 * Set sg_entry_cnt to the number of SG elements
6709 * that will be completed on this interrupt.
6710 *
6711 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
6712 * SG elements. The data_cnt and data_addr fields which
6713 * add 1 to the SG element capacity are not used when
6714 * restarting SG handling after a halt.
6715 */
6716 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
6717 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
6718
6719 /*
95c9f162
MW
6720 * Keep track of remaining number of SG elements that
6721 * will need to be handled on the next interrupt.
27c868c2
MW
6722 */
6723 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
6724 } else {
6725 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
6726 scsiq->remain_sg_entry_cnt = 0;
6727 }
6728
6729 /*
6730 * Copy SG elements into the list of allocated SG queues.
6731 *
6732 * Last index completed is saved in scsiq->next_sg_index.
6733 */
6734 next_qp = first_sg_wk_q_no;
6735 q_addr = ASC_QNO_TO_QADDR(next_qp);
6736 scsi_sg_q.sg_head_qp = q_no;
6737 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
6738 for (i = 0; i < sg_head->queue_cnt; i++) {
6739 scsi_sg_q.seq_no = i + 1;
6740 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
6741 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
6742 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
6743 /*
6744 * After very first SG queue RISC FW uses next
6745 * SG queue first element then checks sg_list_cnt
6746 * against zero and then decrements, so set
6747 * sg_list_cnt 1 less than number of SG elements
6748 * in each SG queue.
6749 */
6750 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
6751 scsi_sg_q.sg_cur_list_cnt =
6752 ASC_SG_LIST_PER_Q - 1;
6753 } else {
6754 /*
6755 * This is the last SG queue in the list of
6756 * allocated SG queues. If there are more
6757 * SG elements than will fit in the allocated
6758 * queues, then set the QCSG_SG_XFER_MORE flag.
6759 */
6760 if (scsiq->remain_sg_entry_cnt != 0) {
6761 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
6762 } else {
6763 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
6764 }
6765 /* equals sg_entry_cnt * 2 */
6766 sg_list_dwords = sg_entry_cnt << 1;
6767 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
6768 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
6769 sg_entry_cnt = 0;
6770 }
6771
6772 scsi_sg_q.q_no = next_qp;
6773 AscMemWordCopyPtrToLram(iop_base,
6774 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
6775 (uchar *)&scsi_sg_q,
6776 sizeof(ASC_SG_LIST_Q) >> 1);
6777
6778 AscMemDWordCopyPtrToLram(iop_base,
6779 q_addr + ASC_SGQ_LIST_BEG,
6780 (uchar *)&sg_head->
6781 sg_list[scsiq->next_sg_index],
6782 sg_list_dwords);
6783
6784 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
6785
6786 /*
6787 * If the just completed SG queue contained the
6788 * last SG element, then no more SG queues need
6789 * to be written.
6790 */
6791 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
6792 break;
6793 }
6794
6795 next_qp = AscReadLramByte(iop_base,
6796 (ushort)(q_addr +
6797 ASC_SCSIQ_B_FWD));
6798 q_addr = ASC_QNO_TO_QADDR(next_qp);
6799 }
6800
6801 /*
6802 * Clear the halt condition so the RISC will be restarted
6803 * after the return.
6804 */
6805 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6806 return (0);
6807 }
1da177e4 6808#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 6809 return (0);
1da177e4
LT
6810}
6811
27c868c2
MW
6812static uchar
6813_AscCopyLramScsiDoneQ(PortAddr iop_base,
6814 ushort q_addr,
6815 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 6816{
27c868c2
MW
6817 ushort _val;
6818 uchar sg_queue_cnt;
6819
6820 DvcGetQinfo(iop_base,
6821 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
6822 (uchar *)scsiq,
6823 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
6824
6825 _val = AscReadLramWord(iop_base,
6826 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
6827 scsiq->q_status = (uchar)_val;
6828 scsiq->q_no = (uchar)(_val >> 8);
6829 _val = AscReadLramWord(iop_base,
6830 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
6831 scsiq->cntl = (uchar)_val;
6832 sg_queue_cnt = (uchar)(_val >> 8);
6833 _val = AscReadLramWord(iop_base,
6834 (ushort)(q_addr +
6835 (ushort)ASC_SCSIQ_B_SENSE_LEN));
6836 scsiq->sense_len = (uchar)_val;
6837 scsiq->extra_bytes = (uchar)(_val >> 8);
6838
6839 /*
6840 * Read high word of remain bytes from alternate location.
6841 */
6842 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
6843 (ushort)(q_addr +
6844 (ushort)
6845 ASC_SCSIQ_W_ALT_DC1)))
6846 << 16);
6847 /*
6848 * Read low word of remain bytes from original location.
6849 */
6850 scsiq->remain_bytes += AscReadLramWord(iop_base,
6851 (ushort)(q_addr + (ushort)
6852 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
6853
6854 scsiq->remain_bytes &= max_dma_count;
6855 return (sg_queue_cnt);
1da177e4
LT
6856}
6857
27c868c2 6858static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 6859{
27c868c2
MW
6860 uchar next_qp;
6861 uchar n_q_used;
6862 uchar sg_list_qp;
6863 uchar sg_queue_cnt;
6864 uchar q_cnt;
6865 uchar done_q_tail;
6866 uchar tid_no;
6867 ASC_SCSI_BIT_ID_TYPE scsi_busy;
6868 ASC_SCSI_BIT_ID_TYPE target_id;
6869 PortAddr iop_base;
6870 ushort q_addr;
6871 ushort sg_q_addr;
6872 uchar cur_target_qng;
6873 ASC_QDONE_INFO scsiq_buf;
6874 ASC_QDONE_INFO *scsiq;
6875 int false_overrun;
27c868c2
MW
6876
6877 iop_base = asc_dvc->iop_base;
27c868c2
MW
6878 n_q_used = 1;
6879 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
6880 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
6881 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
6882 next_qp = AscReadLramByte(iop_base,
6883 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
6884 if (next_qp != ASC_QLINK_END) {
6885 AscPutVarDoneQTail(iop_base, next_qp);
6886 q_addr = ASC_QNO_TO_QADDR(next_qp);
6887 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
6888 asc_dvc->max_dma_count);
6889 AscWriteLramByte(iop_base,
6890 (ushort)(q_addr +
6891 (ushort)ASC_SCSIQ_B_STATUS),
6892 (uchar)(scsiq->
6893 q_status & (uchar)~(QS_READY |
6894 QS_ABORTED)));
6895 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
6896 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
6897 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
6898 sg_q_addr = q_addr;
6899 sg_list_qp = next_qp;
6900 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
6901 sg_list_qp = AscReadLramByte(iop_base,
6902 (ushort)(sg_q_addr
6903 + (ushort)
6904 ASC_SCSIQ_B_FWD));
6905 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
6906 if (sg_list_qp == ASC_QLINK_END) {
6907 AscSetLibErrorCode(asc_dvc,
6908 ASCQ_ERR_SG_Q_LINKS);
6909 scsiq->d3.done_stat = QD_WITH_ERROR;
6910 scsiq->d3.host_stat =
6911 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
6912 goto FATAL_ERR_QDONE;
6913 }
6914 AscWriteLramByte(iop_base,
6915 (ushort)(sg_q_addr + (ushort)
6916 ASC_SCSIQ_B_STATUS),
6917 QS_FREE);
6918 }
6919 n_q_used = sg_queue_cnt + 1;
6920 AscPutVarDoneQTail(iop_base, sg_list_qp);
6921 }
6922 if (asc_dvc->queue_full_or_busy & target_id) {
6923 cur_target_qng = AscReadLramByte(iop_base,
6924 (ushort)((ushort)
6925 ASC_QADR_BEG
6926 + (ushort)
6927 scsiq->d2.
6928 target_ix));
6929 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
6930 scsi_busy = AscReadLramByte(iop_base, (ushort)
6931 ASCV_SCSIBUSY_B);
6932 scsi_busy &= ~target_id;
6933 AscWriteLramByte(iop_base,
6934 (ushort)ASCV_SCSIBUSY_B,
6935 scsi_busy);
6936 asc_dvc->queue_full_or_busy &= ~target_id;
6937 }
6938 }
6939 if (asc_dvc->cur_total_qng >= n_q_used) {
6940 asc_dvc->cur_total_qng -= n_q_used;
6941 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
6942 asc_dvc->cur_dvc_qng[tid_no]--;
6943 }
6944 } else {
6945 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
6946 scsiq->d3.done_stat = QD_WITH_ERROR;
6947 goto FATAL_ERR_QDONE;
6948 }
6949 if ((scsiq->d2.srb_ptr == 0UL) ||
6950 ((scsiq->q_status & QS_ABORTED) != 0)) {
6951 return (0x11);
6952 } else if (scsiq->q_status == QS_DONE) {
6953 false_overrun = FALSE;
6954 if (scsiq->extra_bytes != 0) {
6955 scsiq->remain_bytes +=
6956 (ADV_DCNT)scsiq->extra_bytes;
6957 }
6958 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
6959 if (scsiq->d3.host_stat ==
6960 QHSTA_M_DATA_OVER_RUN) {
6961 if ((scsiq->
6962 cntl & (QC_DATA_IN | QC_DATA_OUT))
6963 == 0) {
6964 scsiq->d3.done_stat =
6965 QD_NO_ERROR;
6966 scsiq->d3.host_stat =
6967 QHSTA_NO_ERROR;
6968 } else if (false_overrun) {
6969 scsiq->d3.done_stat =
6970 QD_NO_ERROR;
6971 scsiq->d3.host_stat =
6972 QHSTA_NO_ERROR;
6973 }
6974 } else if (scsiq->d3.host_stat ==
6975 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
6976 AscStopChip(iop_base);
6977 AscSetChipControl(iop_base,
6978 (uchar)(CC_SCSI_RESET
6979 | CC_HALT));
b009bef6 6980 udelay(60);
27c868c2
MW
6981 AscSetChipControl(iop_base, CC_HALT);
6982 AscSetChipStatus(iop_base,
6983 CIW_CLR_SCSI_RESET_INT);
6984 AscSetChipStatus(iop_base, 0);
6985 AscSetChipControl(iop_base, 0);
6986 }
6987 }
6988 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 6989 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
6990 } else {
6991 if ((AscReadLramByte(iop_base,
6992 (ushort)(q_addr + (ushort)
6993 ASC_SCSIQ_CDB_BEG))
6994 == START_STOP)) {
6995 asc_dvc->unit_not_ready &= ~target_id;
6996 if (scsiq->d3.done_stat != QD_NO_ERROR) {
6997 asc_dvc->start_motor &=
6998 ~target_id;
6999 }
7000 }
7001 }
7002 return (1);
7003 } else {
7004 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
7005 FATAL_ERR_QDONE:
7006 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 7007 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
7008 }
7009 return (0x80);
7010 }
7011 }
7012 return (0);
1da177e4
LT
7013}
7014
27c868c2 7015static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 7016{
27c868c2
MW
7017 ASC_CS_TYPE chipstat;
7018 PortAddr iop_base;
7019 ushort saved_ram_addr;
7020 uchar ctrl_reg;
7021 uchar saved_ctrl_reg;
7022 int int_pending;
7023 int status;
7024 uchar host_flag;
7025
7026 iop_base = asc_dvc->iop_base;
7027 int_pending = FALSE;
7028
7029 if (AscIsIntPending(iop_base) == 0) {
7030 return int_pending;
7031 }
1da177e4 7032
895d6b4c 7033 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
27c868c2
MW
7034 return (ERR);
7035 }
7036 if (asc_dvc->in_critical_cnt != 0) {
7037 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
7038 return (ERR);
7039 }
7040 if (asc_dvc->is_in_int) {
7041 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
7042 return (ERR);
7043 }
7044 asc_dvc->is_in_int = TRUE;
7045 ctrl_reg = AscGetChipControl(iop_base);
7046 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
7047 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
7048 chipstat = AscGetChipStatus(iop_base);
7049 if (chipstat & CSW_SCSI_RESET_LATCH) {
7050 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
7051 int i = 10;
7052 int_pending = TRUE;
7053 asc_dvc->sdtr_done = 0;
7054 saved_ctrl_reg &= (uchar)(~CC_HALT);
7055 while ((AscGetChipStatus(iop_base) &
7056 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
b009bef6 7057 mdelay(100);
27c868c2
MW
7058 }
7059 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
7060 AscSetChipControl(iop_base, CC_HALT);
7061 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
7062 AscSetChipStatus(iop_base, 0);
7063 chipstat = AscGetChipStatus(iop_base);
7064 }
7065 }
7066 saved_ram_addr = AscGetChipLramAddr(iop_base);
7067 host_flag = AscReadLramByte(iop_base,
7068 ASCV_HOST_FLAG_B) &
7069 (uchar)(~ASC_HOST_FLAG_IN_ISR);
7070 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
7071 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
7072 if ((chipstat & CSW_INT_PENDING)
7073 || (int_pending)
7074 ) {
7075 AscAckInterrupt(iop_base);
7076 int_pending = TRUE;
7077 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
7078 if (AscIsrChipHalted(asc_dvc) == ERR) {
7079 goto ISR_REPORT_QDONE_FATAL_ERROR;
7080 } else {
7081 saved_ctrl_reg &= (uchar)(~CC_HALT);
7082 }
7083 } else {
7084 ISR_REPORT_QDONE_FATAL_ERROR:
7085 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
7086 while (((status =
7087 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
7088 }
7089 } else {
7090 do {
7091 if ((status =
7092 AscIsrQDone(asc_dvc)) == 1) {
7093 break;
7094 }
7095 } while (status == 0x11);
7096 }
7097 if ((status & 0x80) != 0)
7098 int_pending = ERR;
7099 }
7100 }
7101 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
7102 AscSetChipLramAddr(iop_base, saved_ram_addr);
7103 AscSetChipControl(iop_base, saved_ctrl_reg);
7104 asc_dvc->is_in_int = FALSE;
7105 return (int_pending);
1da177e4
LT
7106}
7107
7108/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
7109static uchar _asc_mcode_buf[] = {
7110 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d 7111 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
27c868c2 7112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d
MW
7114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
7116 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7117 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7118 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
629d688d
MW
7119 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
7120 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
7121 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
27c868c2 7122 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
629d688d
MW
7123 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
7124 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
7125 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
27c868c2 7126 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
629d688d
MW
7127 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
7128 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
7129 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
27c868c2 7130 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
629d688d
MW
7131 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
7132 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
7133 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
27c868c2 7134 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
629d688d
MW
7135 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
7136 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
7137 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
27c868c2 7138 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
629d688d
MW
7139 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
7140 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
7141 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
27c868c2 7142 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
629d688d
MW
7143 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
7144 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
7145 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
27c868c2 7146 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
629d688d
MW
7147 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
7148 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
7149 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
27c868c2 7150 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
629d688d
MW
7151 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
7152 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
7153 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
27c868c2 7154 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
629d688d
MW
7155 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
7156 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
7157 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
27c868c2 7158 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
629d688d
MW
7159 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
7160 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
7161 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
27c868c2 7162 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
629d688d
MW
7163 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
7164 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
7165 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
27c868c2 7166 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
629d688d
MW
7167 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
7168 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
7169 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
27c868c2 7170 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
629d688d
MW
7171 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
7172 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
7173 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
27c868c2 7174 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
629d688d
MW
7175 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
7176 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
7177 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
27c868c2 7178 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
629d688d
MW
7179 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
7180 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
7181 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
27c868c2 7182 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
629d688d
MW
7183 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
7184 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
7185 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
27c868c2 7186 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
629d688d
MW
7187 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
7188 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
7189 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
27c868c2 7190 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
629d688d
MW
7191 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
7192 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
7193 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
27c868c2 7194 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
629d688d
MW
7195 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
7196 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
7197 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
27c868c2 7198 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
629d688d
MW
7199 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
7200 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
7201 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
27c868c2 7202 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
629d688d
MW
7203 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
7204 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
7205 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
27c868c2 7206 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
629d688d
MW
7207 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
7208 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
7209 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
27c868c2 7210 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
629d688d
MW
7211 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
7212 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
7213 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
27c868c2 7214 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
629d688d
MW
7215 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
7216 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
7217 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
27c868c2 7218 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
629d688d
MW
7219 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
7220 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
7221 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
27c868c2 7222 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
7223 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
7224 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
7225 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
27c868c2 7226 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
629d688d
MW
7227 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
7228 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
7229 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
27c868c2 7230 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
629d688d
MW
7231 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
7232 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
7233 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
27c868c2 7234 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
629d688d
MW
7235 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
7236 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
7237 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
27c868c2 7238 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
629d688d
MW
7239 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
7240 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
7241 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
27c868c2 7242 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
629d688d
MW
7243 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
7244 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
7245 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
27c868c2 7246 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
629d688d
MW
7247 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
7248 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
7249 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
27c868c2 7250 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
629d688d
MW
7251 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
7252 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
7253 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
27c868c2 7254 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
629d688d
MW
7255 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
7256 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
7257 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
27c868c2 7258 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
629d688d
MW
7259 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
7260 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
7261 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
27c868c2 7262 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
629d688d
MW
7263 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
7264 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
7265 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
27c868c2 7266 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
629d688d
MW
7267 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
7268 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
7269 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
27c868c2 7270 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
629d688d
MW
7271 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
7272 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
7273 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
27c868c2 7274 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
629d688d
MW
7275 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
7276 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
7277 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
27c868c2 7278 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
7279 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
7280 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
7281 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
27c868c2 7282 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
629d688d
MW
7283 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
7284 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
7285 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
27c868c2 7286 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
629d688d
MW
7287 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
7288 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
7289 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
27c868c2 7290 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
629d688d
MW
7291 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
7292 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
7293 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
27c868c2 7294 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
629d688d
MW
7295 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
7296 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
7297 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
27c868c2 7298 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
629d688d
MW
7299 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
7300 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
7301 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
7302};
7303
27c868c2
MW
7304static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
7305static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
7306
7307#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
7308static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
7309 INQUIRY,
7310 REQUEST_SENSE,
7311 READ_CAPACITY,
7312 READ_TOC,
7313 MODE_SELECT,
7314 MODE_SENSE,
7315 MODE_SELECT_10,
7316 MODE_SENSE_10,
7317 0xFF,
7318 0xFF,
7319 0xFF,
7320 0xFF,
7321 0xFF,
7322 0xFF,
7323 0xFF,
7324 0xFF
1da177e4
LT
7325};
7326
27c868c2 7327static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 7328{
27c868c2 7329 PortAddr iop_base;
27c868c2
MW
7330 int sta;
7331 int n_q_required;
7332 int disable_syn_offset_one_fix;
7333 int i;
7334 ASC_PADDR addr;
27c868c2
MW
7335 ushort sg_entry_cnt = 0;
7336 ushort sg_entry_cnt_minus_one = 0;
7337 uchar target_ix;
7338 uchar tid_no;
7339 uchar sdtr_data;
7340 uchar extra_bytes;
7341 uchar scsi_cmd;
7342 uchar disable_cmd;
7343 ASC_SG_HEAD *sg_head;
7344 ASC_DCNT data_cnt;
7345
7346 iop_base = asc_dvc->iop_base;
7347 sg_head = scsiq->sg_head;
27c868c2
MW
7348 if (asc_dvc->err_code != 0)
7349 return (ERR);
27c868c2
MW
7350 scsiq->q1.q_no = 0;
7351 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
7352 scsiq->q1.extra_bytes = 0;
7353 }
7354 sta = 0;
7355 target_ix = scsiq->q2.target_ix;
7356 tid_no = ASC_TIX_TO_TID(target_ix);
7357 n_q_required = 1;
7358 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
7359 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
7360 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
7361 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7362 AscMsgOutSDTR(asc_dvc,
7363 asc_dvc->
7364 sdtr_period_tbl[(sdtr_data >> 4) &
7365 (uchar)(asc_dvc->
7366 max_sdtr_index -
7367 1)],
7368 (uchar)(sdtr_data & (uchar)
7369 ASC_SYN_MAX_OFFSET));
7370 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
7371 }
7372 }
27c868c2 7373 if (asc_dvc->in_critical_cnt != 0) {
27c868c2
MW
7374 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
7375 return (ERR);
7376 }
7377 asc_dvc->in_critical_cnt++;
7378 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
7379 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
7380 asc_dvc->in_critical_cnt--;
27c868c2
MW
7381 return (ERR);
7382 }
1da177e4 7383#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
7384 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
7385 asc_dvc->in_critical_cnt--;
27c868c2
MW
7386 return (ERR);
7387 }
1da177e4 7388#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
7389 if (sg_entry_cnt == 1) {
7390 scsiq->q1.data_addr =
7391 (ADV_PADDR)sg_head->sg_list[0].addr;
7392 scsiq->q1.data_cnt =
7393 (ADV_DCNT)sg_head->sg_list[0].bytes;
7394 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
7395 }
7396 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
7397 }
7398 scsi_cmd = scsiq->cdbptr[0];
7399 disable_syn_offset_one_fix = FALSE;
7400 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
7401 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
7402 if (scsiq->q1.cntl & QC_SG_HEAD) {
7403 data_cnt = 0;
7404 for (i = 0; i < sg_entry_cnt; i++) {
7405 data_cnt +=
7406 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
7407 bytes);
7408 }
7409 } else {
7410 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
7411 }
7412 if (data_cnt != 0UL) {
7413 if (data_cnt < 512UL) {
7414 disable_syn_offset_one_fix = TRUE;
7415 } else {
7416 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
7417 i++) {
7418 disable_cmd =
7419 _syn_offset_one_disable_cmd[i];
7420 if (disable_cmd == 0xFF) {
7421 break;
7422 }
7423 if (scsi_cmd == disable_cmd) {
7424 disable_syn_offset_one_fix =
7425 TRUE;
7426 break;
7427 }
7428 }
7429 }
7430 }
7431 }
7432 if (disable_syn_offset_one_fix) {
7433 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
7434 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
7435 ASC_TAG_FLAG_DISABLE_DISCONNECT);
7436 } else {
7437 scsiq->q2.tag_code &= 0x27;
7438 }
7439 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
7440 if (asc_dvc->bug_fix_cntl) {
7441 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
7442 if ((scsi_cmd == READ_6) ||
7443 (scsi_cmd == READ_10)) {
7444 addr =
7445 (ADV_PADDR)le32_to_cpu(sg_head->
7446 sg_list
7447 [sg_entry_cnt_minus_one].
7448 addr) +
7449 (ADV_DCNT)le32_to_cpu(sg_head->
7450 sg_list
7451 [sg_entry_cnt_minus_one].
7452 bytes);
7453 extra_bytes =
7454 (uchar)((ushort)addr & 0x0003);
7455 if ((extra_bytes != 0)
7456 &&
7457 ((scsiq->q2.
7458 tag_code &
7459 ASC_TAG_FLAG_EXTRA_BYTES)
7460 == 0)) {
7461 scsiq->q2.tag_code |=
7462 ASC_TAG_FLAG_EXTRA_BYTES;
7463 scsiq->q1.extra_bytes =
7464 extra_bytes;
7465 data_cnt =
7466 le32_to_cpu(sg_head->
7467 sg_list
7468 [sg_entry_cnt_minus_one].
7469 bytes);
7470 data_cnt -=
7471 (ASC_DCNT) extra_bytes;
7472 sg_head->
7473 sg_list
7474 [sg_entry_cnt_minus_one].
7475 bytes =
7476 cpu_to_le32(data_cnt);
7477 }
7478 }
7479 }
7480 }
7481 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 7482#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7483 /*
7484 * Set the sg_entry_cnt to the maximum possible. The rest of
7485 * the SG elements will be copied when the RISC completes the
7486 * SG elements that fit and halts.
7487 */
7488 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
7489 sg_entry_cnt = ASC_MAX_SG_LIST;
7490 }
1da177e4 7491#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7492 n_q_required = AscSgListToQueue(sg_entry_cnt);
7493 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
7494 (uint) n_q_required)
7495 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
7496 if ((sta =
7497 AscSendScsiQueue(asc_dvc, scsiq,
7498 n_q_required)) == 1) {
7499 asc_dvc->in_critical_cnt--;
27c868c2
MW
7500 return (sta);
7501 }
7502 }
7503 } else {
7504 if (asc_dvc->bug_fix_cntl) {
7505 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
7506 if ((scsi_cmd == READ_6) ||
7507 (scsi_cmd == READ_10)) {
7508 addr =
7509 le32_to_cpu(scsiq->q1.data_addr) +
7510 le32_to_cpu(scsiq->q1.data_cnt);
7511 extra_bytes =
7512 (uchar)((ushort)addr & 0x0003);
7513 if ((extra_bytes != 0)
7514 &&
7515 ((scsiq->q2.
7516 tag_code &
7517 ASC_TAG_FLAG_EXTRA_BYTES)
7518 == 0)) {
7519 data_cnt =
7520 le32_to_cpu(scsiq->q1.
7521 data_cnt);
7522 if (((ushort)data_cnt & 0x01FF)
7523 == 0) {
7524 scsiq->q2.tag_code |=
7525 ASC_TAG_FLAG_EXTRA_BYTES;
7526 data_cnt -= (ASC_DCNT)
7527 extra_bytes;
7528 scsiq->q1.data_cnt =
7529 cpu_to_le32
7530 (data_cnt);
7531 scsiq->q1.extra_bytes =
7532 extra_bytes;
7533 }
7534 }
7535 }
7536 }
7537 }
7538 n_q_required = 1;
7539 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
7540 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
7541 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
7542 n_q_required)) == 1) {
7543 asc_dvc->in_critical_cnt--;
27c868c2
MW
7544 return (sta);
7545 }
7546 }
7547 }
7548 asc_dvc->in_critical_cnt--;
27c868c2 7549 return (sta);
1da177e4
LT
7550}
7551
27c868c2
MW
7552static int
7553AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 7554{
27c868c2
MW
7555 PortAddr iop_base;
7556 uchar free_q_head;
7557 uchar next_qp;
7558 uchar tid_no;
7559 uchar target_ix;
7560 int sta;
7561
7562 iop_base = asc_dvc->iop_base;
7563 target_ix = scsiq->q2.target_ix;
7564 tid_no = ASC_TIX_TO_TID(target_ix);
7565 sta = 0;
7566 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
7567 if (n_q_required > 1) {
95c9f162
MW
7568 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
7569 (uchar)n_q_required);
7570 if (next_qp != ASC_QLINK_END) {
27c868c2
MW
7571 asc_dvc->last_q_shortage = 0;
7572 scsiq->sg_head->queue_cnt = n_q_required - 1;
7573 scsiq->q1.q_no = free_q_head;
95c9f162
MW
7574 sta = AscPutReadySgListQueue(asc_dvc, scsiq,
7575 free_q_head);
27c868c2
MW
7576 }
7577 } else if (n_q_required == 1) {
95c9f162
MW
7578 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
7579 if (next_qp != ASC_QLINK_END) {
27c868c2 7580 scsiq->q1.q_no = free_q_head;
95c9f162 7581 sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
27c868c2
MW
7582 }
7583 }
95c9f162
MW
7584 if (sta == 1) {
7585 AscPutVarFreeQHead(iop_base, next_qp);
7586 asc_dvc->cur_total_qng += (uchar)(n_q_required);
7587 asc_dvc->cur_dvc_qng[tid_no]++;
7588 }
7589 return sta;
1da177e4
LT
7590}
7591
27c868c2 7592static int AscSgListToQueue(int sg_list)
1da177e4 7593{
27c868c2 7594 int n_sg_list_qs;
1da177e4 7595
27c868c2
MW
7596 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
7597 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
7598 n_sg_list_qs++;
7599 return (n_sg_list_qs + 1);
1da177e4
LT
7600}
7601
27c868c2
MW
7602static uint
7603AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 7604{
27c868c2
MW
7605 uint cur_used_qs;
7606 uint cur_free_qs;
7607 ASC_SCSI_BIT_ID_TYPE target_id;
7608 uchar tid_no;
7609
7610 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
7611 tid_no = ASC_TIX_TO_TID(target_ix);
7612 if ((asc_dvc->unit_not_ready & target_id) ||
7613 (asc_dvc->queue_full_or_busy & target_id)) {
7614 return (0);
7615 }
7616 if (n_qs == 1) {
7617 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7618 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
7619 } else {
7620 cur_used_qs = (uint) asc_dvc->cur_total_qng +
7621 (uint) ASC_MIN_FREE_Q;
7622 }
7623 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
7624 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
7625 if (asc_dvc->cur_dvc_qng[tid_no] >=
7626 asc_dvc->max_dvc_qng[tid_no]) {
7627 return (0);
7628 }
7629 return (cur_free_qs);
7630 }
7631 if (n_qs > 1) {
7632 if ((n_qs > asc_dvc->last_q_shortage)
7633 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
7634 asc_dvc->last_q_shortage = n_qs;
7635 }
7636 }
7637 return (0);
1da177e4
LT
7638}
7639
27c868c2 7640static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 7641{
27c868c2
MW
7642 ushort q_addr;
7643 uchar tid_no;
7644 uchar sdtr_data;
7645 uchar syn_period_ix;
7646 uchar syn_offset;
7647 PortAddr iop_base;
7648
7649 iop_base = asc_dvc->iop_base;
7650 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
7651 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
7652 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
7653 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7654 syn_period_ix =
7655 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
7656 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
7657 AscMsgOutSDTR(asc_dvc,
7658 asc_dvc->sdtr_period_tbl[syn_period_ix],
7659 syn_offset);
7660 scsiq->q1.cntl |= QC_MSG_OUT;
7661 }
7662 q_addr = ASC_QNO_TO_QADDR(q_no);
7663 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
7664 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
7665 }
7666 scsiq->q1.status = QS_FREE;
7667 AscMemWordCopyPtrToLram(iop_base,
7668 q_addr + ASC_SCSIQ_CDB_BEG,
7669 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
7670
7671 DvcPutScsiQ(iop_base,
7672 q_addr + ASC_SCSIQ_CPY_BEG,
7673 (uchar *)&scsiq->q1.cntl,
7674 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
7675 AscWriteLramWord(iop_base,
7676 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
7677 (ushort)(((ushort)scsiq->q1.
7678 q_no << 8) | (ushort)QS_READY));
7679 return (1);
1da177e4
LT
7680}
7681
27c868c2
MW
7682static int
7683AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 7684{
27c868c2
MW
7685 int sta;
7686 int i;
7687 ASC_SG_HEAD *sg_head;
7688 ASC_SG_LIST_Q scsi_sg_q;
7689 ASC_DCNT saved_data_addr;
7690 ASC_DCNT saved_data_cnt;
7691 PortAddr iop_base;
7692 ushort sg_list_dwords;
7693 ushort sg_index;
7694 ushort sg_entry_cnt;
7695 ushort q_addr;
7696 uchar next_qp;
7697
7698 iop_base = asc_dvc->iop_base;
7699 sg_head = scsiq->sg_head;
7700 saved_data_addr = scsiq->q1.data_addr;
7701 saved_data_cnt = scsiq->q1.data_cnt;
7702 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
7703 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 7704#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7705 /*
7706 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
7707 * then not all SG elements will fit in the allocated queues.
7708 * The rest of the SG elements will be copied when the RISC
7709 * completes the SG elements that fit and halts.
7710 */
7711 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
7712 /*
7713 * Set sg_entry_cnt to be the number of SG elements that
7714 * will fit in the allocated SG queues. It is minus 1, because
7715 * the first SG element is handled above. ASC_MAX_SG_LIST is
7716 * already inflated by 1 to account for this. For example it
7717 * may be 50 which is 1 + 7 queues * 7 SG elements.
7718 */
7719 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
7720
7721 /*
7722 * Keep track of remaining number of SG elements that will
7723 * need to be handled from a_isr.c.
7724 */
7725 scsiq->remain_sg_entry_cnt =
7726 sg_head->entry_cnt - ASC_MAX_SG_LIST;
7727 } else {
1da177e4 7728#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7729 /*
7730 * Set sg_entry_cnt to be the number of SG elements that
7731 * will fit in the allocated SG queues. It is minus 1, because
7732 * the first SG element is handled above.
7733 */
7734 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 7735#if CC_VERY_LONG_SG_LIST
27c868c2 7736 }
1da177e4 7737#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7738 if (sg_entry_cnt != 0) {
7739 scsiq->q1.cntl |= QC_SG_HEAD;
7740 q_addr = ASC_QNO_TO_QADDR(q_no);
7741 sg_index = 1;
7742 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
7743 scsi_sg_q.sg_head_qp = q_no;
7744 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
7745 for (i = 0; i < sg_head->queue_cnt; i++) {
7746 scsi_sg_q.seq_no = i + 1;
7747 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
7748 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
7749 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
7750 if (i == 0) {
7751 scsi_sg_q.sg_list_cnt =
7752 ASC_SG_LIST_PER_Q;
7753 scsi_sg_q.sg_cur_list_cnt =
7754 ASC_SG_LIST_PER_Q;
7755 } else {
7756 scsi_sg_q.sg_list_cnt =
7757 ASC_SG_LIST_PER_Q - 1;
7758 scsi_sg_q.sg_cur_list_cnt =
7759 ASC_SG_LIST_PER_Q - 1;
7760 }
7761 } else {
1da177e4 7762#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7763 /*
7764 * This is the last SG queue in the list of
7765 * allocated SG queues. If there are more
7766 * SG elements than will fit in the allocated
7767 * queues, then set the QCSG_SG_XFER_MORE flag.
7768 */
7769 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
7770 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
7771 } else {
1da177e4 7772#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 7773 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 7774#if CC_VERY_LONG_SG_LIST
27c868c2 7775 }
1da177e4 7776#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
7777 sg_list_dwords = sg_entry_cnt << 1;
7778 if (i == 0) {
7779 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
7780 scsi_sg_q.sg_cur_list_cnt =
7781 sg_entry_cnt;
7782 } else {
7783 scsi_sg_q.sg_list_cnt =
7784 sg_entry_cnt - 1;
7785 scsi_sg_q.sg_cur_list_cnt =
7786 sg_entry_cnt - 1;
7787 }
7788 sg_entry_cnt = 0;
7789 }
7790 next_qp = AscReadLramByte(iop_base,
7791 (ushort)(q_addr +
7792 ASC_SCSIQ_B_FWD));
7793 scsi_sg_q.q_no = next_qp;
7794 q_addr = ASC_QNO_TO_QADDR(next_qp);
7795 AscMemWordCopyPtrToLram(iop_base,
7796 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
7797 (uchar *)&scsi_sg_q,
7798 sizeof(ASC_SG_LIST_Q) >> 1);
7799 AscMemDWordCopyPtrToLram(iop_base,
7800 q_addr + ASC_SGQ_LIST_BEG,
7801 (uchar *)&sg_head->
7802 sg_list[sg_index],
7803 sg_list_dwords);
7804 sg_index += ASC_SG_LIST_PER_Q;
7805 scsiq->next_sg_index = sg_index;
7806 }
7807 } else {
7808 scsiq->q1.cntl &= ~QC_SG_HEAD;
7809 }
7810 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
7811 scsiq->q1.data_addr = saved_data_addr;
7812 scsiq->q1.data_cnt = saved_data_cnt;
7813 return (sta);
1da177e4
LT
7814}
7815
27c868c2
MW
7816static int
7817AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 7818{
27c868c2 7819 int sta = FALSE;
1da177e4 7820
27c868c2
MW
7821 if (AscHostReqRiscHalt(iop_base)) {
7822 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
7823 AscStartChip(iop_base);
7824 return (sta);
7825 }
7826 return (sta);
1da177e4
LT
7827}
7828
27c868c2 7829static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 7830{
27c868c2
MW
7831 ASC_SCSI_BIT_ID_TYPE org_id;
7832 int i;
7833 int sta = TRUE;
7834
7835 AscSetBank(iop_base, 1);
7836 org_id = AscReadChipDvcID(iop_base);
7837 for (i = 0; i <= ASC_MAX_TID; i++) {
7838 if (org_id == (0x01 << i))
7839 break;
7840 }
7841 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
7842 AscWriteChipDvcID(iop_base, id);
7843 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
7844 AscSetBank(iop_base, 0);
7845 AscSetChipSyn(iop_base, sdtr_data);
7846 if (AscGetChipSyn(iop_base) != sdtr_data) {
7847 sta = FALSE;
7848 }
7849 } else {
7850 sta = FALSE;
7851 }
7852 AscSetBank(iop_base, 1);
7853 AscWriteChipDvcID(iop_base, org_id);
7854 AscSetBank(iop_base, 0);
7855 return (sta);
7856}
1da177e4 7857
27c868c2 7858static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 7859{
27c868c2
MW
7860 uchar i;
7861 ushort s_addr;
7862 PortAddr iop_base;
7863 ushort warn_code;
7864
7865 iop_base = asc_dvc->iop_base;
7866 warn_code = 0;
7867 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
7868 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
7869 64) >> 1)
7870 );
7871 i = ASC_MIN_ACTIVE_QNO;
7872 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
7873 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
7874 (uchar)(i + 1));
7875 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
7876 (uchar)(asc_dvc->max_total_qng));
7877 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
7878 (uchar)i);
7879 i++;
7880 s_addr += ASC_QBLK_SIZE;
7881 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
7882 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
7883 (uchar)(i + 1));
7884 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
7885 (uchar)(i - 1));
7886 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
7887 (uchar)i);
7888 }
7889 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
7890 (uchar)ASC_QLINK_END);
7891 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
7892 (uchar)(asc_dvc->max_total_qng - 1));
7893 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
7894 (uchar)asc_dvc->max_total_qng);
7895 i++;
7896 s_addr += ASC_QBLK_SIZE;
7897 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
7898 i++, s_addr += ASC_QBLK_SIZE) {
7899 AscWriteLramByte(iop_base,
7900 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
7901 AscWriteLramByte(iop_base,
7902 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
7903 AscWriteLramByte(iop_base,
7904 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
7905 }
7906 return (warn_code);
1da177e4
LT
7907}
7908
95c9f162 7909static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 7910{
27c868c2
MW
7911 PortAddr iop_base;
7912 int i;
7913 ushort lram_addr;
7914
7915 iop_base = asc_dvc->iop_base;
7916 AscPutRiscVarFreeQHead(iop_base, 1);
7917 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
7918 AscPutVarFreeQHead(iop_base, 1);
7919 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
7920 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
7921 (uchar)((int)asc_dvc->max_total_qng + 1));
7922 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
7923 (uchar)((int)asc_dvc->max_total_qng + 2));
7924 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
7925 asc_dvc->max_total_qng);
7926 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
7927 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7928 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
7929 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
7930 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
7931 AscPutQDoneInProgress(iop_base, 0);
7932 lram_addr = ASC_QADR_BEG;
7933 for (i = 0; i < 32; i++, lram_addr += 2) {
7934 AscWriteLramWord(iop_base, lram_addr, 0);
7935 }
1da177e4
LT
7936}
7937
27c868c2 7938static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 7939{
27c868c2
MW
7940 if (asc_dvc->err_code == 0) {
7941 asc_dvc->err_code = err_code;
7942 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
7943 err_code);
7944 }
7945 return (err_code);
1da177e4
LT
7946}
7947
27c868c2
MW
7948static uchar
7949AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 7950{
27c868c2
MW
7951 EXT_MSG sdtr_buf;
7952 uchar sdtr_period_index;
7953 PortAddr iop_base;
7954
7955 iop_base = asc_dvc->iop_base;
47d853cc 7956 sdtr_buf.msg_type = EXTENDED_MESSAGE;
27c868c2 7957 sdtr_buf.msg_len = MS_SDTR_LEN;
47d853cc 7958 sdtr_buf.msg_req = EXTENDED_SDTR;
27c868c2
MW
7959 sdtr_buf.xfer_period = sdtr_period;
7960 sdtr_offset &= ASC_SYN_MAX_OFFSET;
7961 sdtr_buf.req_ack_offset = sdtr_offset;
7962 if ((sdtr_period_index =
7963 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
7964 asc_dvc->max_sdtr_index) {
7965 AscMemWordCopyPtrToLram(iop_base,
7966 ASCV_MSGOUT_BEG,
7967 (uchar *)&sdtr_buf,
7968 sizeof(EXT_MSG) >> 1);
7969 return ((sdtr_period_index << 4) | sdtr_offset);
7970 } else {
7971
7972 sdtr_buf.req_ack_offset = 0;
7973 AscMemWordCopyPtrToLram(iop_base,
7974 ASCV_MSGOUT_BEG,
7975 (uchar *)&sdtr_buf,
7976 sizeof(EXT_MSG) >> 1);
7977 return (0);
7978 }
1da177e4
LT
7979}
7980
27c868c2
MW
7981static uchar
7982AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 7983{
27c868c2
MW
7984 uchar byte;
7985 uchar sdtr_period_ix;
7986
7987 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
7988 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
7989 ) {
7990 return (0xFF);
7991 }
7992 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
7993 return (byte);
1da177e4
LT
7994}
7995
27c868c2 7996static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 7997{
27c868c2
MW
7998 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
7999 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8000 return;
1da177e4
LT
8001}
8002
27c868c2 8003static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 8004{
27c868c2
MW
8005 uchar *period_table;
8006 int max_index;
8007 int min_index;
8008 int i;
8009
8010 period_table = asc_dvc->sdtr_period_tbl;
8011 max_index = (int)asc_dvc->max_sdtr_index;
8012 min_index = (int)asc_dvc->host_init_sdtr_index;
8013 if ((syn_time <= period_table[max_index])) {
8014 for (i = min_index; i < (max_index - 1); i++) {
8015 if (syn_time <= period_table[i]) {
8016 return ((uchar)i);
8017 }
8018 }
8019 return ((uchar)max_index);
8020 } else {
8021 return ((uchar)(max_index + 1));
8022 }
1da177e4
LT
8023}
8024
27c868c2 8025static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 8026{
27c868c2
MW
8027 ushort q_addr;
8028 uchar next_qp;
8029 uchar q_status;
8030
8031 q_addr = ASC_QNO_TO_QADDR(free_q_head);
8032 q_status = (uchar)AscReadLramByte(iop_base,
8033 (ushort)(q_addr +
8034 ASC_SCSIQ_B_STATUS));
8035 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
8036 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
8037 return (next_qp);
8038 }
8039 return (ASC_QLINK_END);
1da177e4
LT
8040}
8041
27c868c2
MW
8042static uchar
8043AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 8044{
27c868c2 8045 uchar i;
1da177e4 8046
27c868c2
MW
8047 for (i = 0; i < n_free_q; i++) {
8048 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
8049 == ASC_QLINK_END) {
8050 return (ASC_QLINK_END);
8051 }
8052 }
8053 return (free_q_head);
1da177e4
LT
8054}
8055
27c868c2 8056static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 8057{
27c868c2
MW
8058 int count = 0;
8059 int sta = 0;
8060 uchar saved_stop_code;
8061
8062 if (AscIsChipHalted(iop_base))
8063 return (1);
8064 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
8065 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8066 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
8067 do {
8068 if (AscIsChipHalted(iop_base)) {
8069 sta = 1;
8070 break;
8071 }
b009bef6 8072 mdelay(100);
27c868c2
MW
8073 } while (count++ < 20);
8074 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
8075 return (sta);
1da177e4
LT
8076}
8077
27c868c2 8078static int AscStopQueueExe(PortAddr iop_base)
1da177e4 8079{
27c868c2
MW
8080 int count = 0;
8081
8082 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
8083 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8084 ASC_STOP_REQ_RISC_STOP);
8085 do {
8086 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
8087 ASC_STOP_ACK_RISC_STOP) {
8088 return (1);
8089 }
b009bef6 8090 mdelay(100);
27c868c2
MW
8091 } while (count++ < 20);
8092 }
8093 return (0);
1da177e4
LT
8094}
8095
27c868c2 8096static int AscStartChip(PortAddr iop_base)
1da177e4 8097{
27c868c2
MW
8098 AscSetChipControl(iop_base, 0);
8099 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8100 return (0);
8101 }
8102 return (1);
1da177e4
LT
8103}
8104
27c868c2 8105static int AscStopChip(PortAddr iop_base)
1da177e4 8106{
27c868c2
MW
8107 uchar cc_val;
8108
8109 cc_val =
8110 AscGetChipControl(iop_base) &
8111 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
8112 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
8113 AscSetChipIH(iop_base, INS_HALT);
8114 AscSetChipIH(iop_base, INS_RFLAG_WTM);
8115 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
8116 return (0);
8117 }
8118 return (1);
1da177e4
LT
8119}
8120
27c868c2 8121static int AscIsChipHalted(PortAddr iop_base)
1da177e4 8122{
27c868c2
MW
8123 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8124 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
8125 return (1);
8126 }
8127 }
8128 return (0);
1da177e4
LT
8129}
8130
27c868c2 8131static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 8132{
27c868c2
MW
8133 AscSetBank(iop_base, 1);
8134 AscWriteChipIH(iop_base, ins_code);
8135 AscSetBank(iop_base, 0);
8136 return;
1da177e4
LT
8137}
8138
27c868c2 8139static void AscAckInterrupt(PortAddr iop_base)
1da177e4 8140{
27c868c2
MW
8141 uchar host_flag;
8142 uchar risc_flag;
8143 ushort loop;
8144
8145 loop = 0;
8146 do {
8147 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8148 if (loop++ > 0x7FFF) {
8149 break;
8150 }
8151 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8152 host_flag =
8153 AscReadLramByte(iop_base,
8154 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8155 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8156 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8157 AscSetChipStatus(iop_base, CIW_INT_ACK);
8158 loop = 0;
8159 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8160 AscSetChipStatus(iop_base, CIW_INT_ACK);
8161 if (loop++ > 3) {
8162 break;
8163 }
8164 }
8165 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8166 return;
1da177e4
LT
8167}
8168
27c868c2 8169static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 8170{
27c868c2 8171 ushort cfg;
1da177e4 8172
27c868c2
MW
8173 cfg = AscGetChipCfgLsw(iop_base);
8174 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
8175 return;
1da177e4
LT
8176}
8177
27c868c2 8178static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 8179{
27c868c2 8180 ushort cfg;
1da177e4 8181
27c868c2
MW
8182 cfg = AscGetChipCfgLsw(iop_base);
8183 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
8184 return;
1da177e4
LT
8185}
8186
27c868c2 8187static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 8188{
27c868c2
MW
8189 uchar val;
8190
8191 val = AscGetChipControl(iop_base) &
8192 (~
8193 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
8194 CC_CHIP_RESET));
8195 if (bank == 1) {
8196 val |= CC_BANK_ONE;
8197 } else if (bank == 2) {
8198 val |= CC_DIAG | CC_BANK_ONE;
8199 } else {
8200 val &= ~CC_BANK_ONE;
8201 }
8202 AscSetChipControl(iop_base, val);
8203 return;
1da177e4
LT
8204}
8205
27c868c2 8206static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 8207{
27c868c2
MW
8208 PortAddr iop_base;
8209 int i = 10;
1da177e4 8210
27c868c2
MW
8211 iop_base = asc_dvc->iop_base;
8212 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
8213 && (i-- > 0)) {
b009bef6 8214 mdelay(100);
27c868c2
MW
8215 }
8216 AscStopChip(iop_base);
8217 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
b009bef6 8218 udelay(60);
27c868c2
MW
8219 AscSetChipIH(iop_base, INS_RFLAG_WTM);
8220 AscSetChipIH(iop_base, INS_HALT);
8221 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
8222 AscSetChipControl(iop_base, CC_HALT);
b009bef6 8223 mdelay(200);
27c868c2
MW
8224 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8225 AscSetChipStatus(iop_base, 0);
8226 return (AscIsChipHalted(iop_base));
1da177e4
LT
8227}
8228
78e77d8b 8229static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
1da177e4 8230{
27c868c2 8231 if (bus_type & ASC_IS_ISA)
95c9f162 8232 return ASC_MAX_ISA_DMA_COUNT;
27c868c2 8233 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
95c9f162
MW
8234 return ASC_MAX_VL_DMA_COUNT;
8235 return ASC_MAX_PCI_DMA_COUNT;
1da177e4
LT
8236}
8237
8238#ifdef CONFIG_ISA
78e77d8b 8239static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 8240{
27c868c2
MW
8241 ushort channel;
8242
8243 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
8244 if (channel == 0x03)
8245 return (0);
8246 else if (channel == 0x00)
8247 return (7);
8248 return (channel + 4);
1da177e4
LT
8249}
8250
78e77d8b 8251static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 8252{
27c868c2
MW
8253 ushort cfg_lsw;
8254 uchar value;
8255
8256 if ((dma_channel >= 5) && (dma_channel <= 7)) {
8257 if (dma_channel == 7)
8258 value = 0x00;
8259 else
8260 value = dma_channel - 4;
8261 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
8262 cfg_lsw |= value;
8263 AscSetChipCfgLsw(iop_base, cfg_lsw);
8264 return (AscGetIsaDmaChannel(iop_base));
8265 }
8266 return (0);
1da177e4
LT
8267}
8268
78e77d8b 8269static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 8270{
27c868c2
MW
8271 speed_value &= 0x07;
8272 AscSetBank(iop_base, 1);
8273 AscWriteChipDmaSpeed(iop_base, speed_value);
8274 AscSetBank(iop_base, 0);
8275 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
8276}
8277
78e77d8b 8278static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 8279{
27c868c2 8280 uchar speed_value;
1da177e4 8281
27c868c2
MW
8282 AscSetBank(iop_base, 1);
8283 speed_value = AscReadChipDmaSpeed(iop_base);
8284 speed_value &= 0x07;
8285 AscSetBank(iop_base, 0);
8286 return (speed_value);
1da177e4
LT
8287}
8288#endif /* CONFIG_ISA */
8289
c2dce2fa 8290static int __devinit AscInitGetConfig(asc_board_t *boardp)
1da177e4 8291{
c2dce2fa 8292 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9649af39 8293 unsigned short warn_code = 0;
27c868c2 8294
27c868c2 8295 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9649af39 8296 if (asc_dvc->err_code != 0)
c2dce2fa 8297 return asc_dvc->err_code;
27c868c2 8298
9649af39 8299 if (AscFindSignature(asc_dvc->iop_base)) {
27c868c2
MW
8300 warn_code |= AscInitAscDvcVar(asc_dvc);
8301 warn_code |= AscInitFromEEP(asc_dvc);
8302 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
ecec1947 8303 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
27c868c2 8304 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
27c868c2
MW
8305 } else {
8306 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
8307 }
c2dce2fa
MW
8308
8309 switch (warn_code) {
8310 case 0: /* No error */
8311 break;
8312 case ASC_WARN_IO_PORT_ROTATE:
8313 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
8314 "modified\n", boardp->id);
8315 break;
8316 case ASC_WARN_AUTO_CONFIG:
8317 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
8318 "switch enabled\n", boardp->id);
8319 break;
8320 case ASC_WARN_EEPROM_CHKSUM:
8321 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
8322 "error\n", boardp->id);
8323 break;
8324 case ASC_WARN_IRQ_MODIFIED:
8325 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
8326 boardp->id);
8327 break;
8328 case ASC_WARN_CMD_QNG_CONFLICT:
8329 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
8330 "w/o disconnects\n", boardp->id);
8331 break;
8332 default:
8333 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
8334 "0x%x\n", boardp->id, warn_code);
8335 break;
8336 }
8337
8338 if (asc_dvc->err_code != 0) {
8339 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
8340 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
8341 asc_dvc->err_code);
8342 }
8343
8344 return asc_dvc->err_code;
1da177e4
LT
8345}
8346
c2dce2fa 8347static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 8348{
c2dce2fa 8349 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
394dbf3f
MW
8350 PortAddr iop_base = asc_dvc->iop_base;
8351 unsigned short cfg_msw;
8352 unsigned short warn_code = 0;
27c868c2
MW
8353
8354 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
8355 if (asc_dvc->err_code != 0)
c2dce2fa 8356 return asc_dvc->err_code;
394dbf3f 8357 if (!AscFindSignature(asc_dvc->iop_base)) {
27c868c2 8358 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
c2dce2fa 8359 return asc_dvc->err_code;
27c868c2 8360 }
1da177e4 8361
27c868c2
MW
8362 cfg_msw = AscGetChipCfgMsw(iop_base);
8363 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 8364 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
8365 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
8366 AscSetChipCfgMsw(iop_base, cfg_msw);
8367 }
8368 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
8369 asc_dvc->cfg->cmd_qng_enabled) {
8370 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
8371 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
8372 }
8373 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
8374 warn_code |= ASC_WARN_AUTO_CONFIG;
8375 }
8376 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
8377 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
8378 != asc_dvc->irq_no) {
8379 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
8380 }
8381 }
9649af39 8382#ifdef CONFIG_PCI
27c868c2
MW
8383 if (asc_dvc->bus_type & ASC_IS_PCI) {
8384 cfg_msw &= 0xFFC0;
8385 AscSetChipCfgMsw(iop_base, cfg_msw);
8386 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
8387 } else {
9649af39
MW
8388 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
8389 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
27c868c2
MW
8390 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
8391 asc_dvc->bug_fix_cntl |=
8392 ASC_BUG_FIX_ASYN_USE_SYN;
8393 }
8394 }
9649af39
MW
8395 } else
8396#endif /* CONFIG_PCI */
8397 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
27c868c2
MW
8398 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
8399 == ASC_CHIP_VER_ASYN_BUG) {
8400 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
8401 }
8402 }
8403 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
8404 asc_dvc->cfg->chip_scsi_id) {
8405 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
8406 }
1da177e4 8407#ifdef CONFIG_ISA
27c868c2
MW
8408 if (asc_dvc->bus_type & ASC_IS_ISA) {
8409 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
8410 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
8411 }
1da177e4 8412#endif /* CONFIG_ISA */
394dbf3f
MW
8413
8414 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
c2dce2fa
MW
8415
8416 switch (warn_code) {
8417 case 0: /* No error. */
8418 break;
8419 case ASC_WARN_IO_PORT_ROTATE:
8420 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
8421 "modified\n", boardp->id);
8422 break;
8423 case ASC_WARN_AUTO_CONFIG:
8424 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
8425 "switch enabled\n", boardp->id);
8426 break;
8427 case ASC_WARN_EEPROM_CHKSUM:
8428 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
8429 "error\n", boardp->id);
8430 break;
8431 case ASC_WARN_IRQ_MODIFIED:
8432 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
8433 boardp->id);
8434 break;
8435 case ASC_WARN_CMD_QNG_CONFLICT:
8436 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
8437 "disconnects\n",
8438 boardp->id);
8439 break;
8440 default:
8441 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
8442 "0x%x\n", boardp->id, warn_code);
8443 break;
8444 }
8445
8446 if (asc_dvc->err_code != 0) {
8447 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
8448 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
8449 asc_dvc->err_code);
8450 }
8451
8452 return asc_dvc->err_code;
1da177e4
LT
8453}
8454
27c868c2 8455static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 8456{
27c868c2
MW
8457 ushort warn_code;
8458 PortAddr iop_base;
8459
8460 iop_base = asc_dvc->iop_base;
8461 warn_code = 0;
8462 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
8463 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
8464 AscResetChipAndScsiBus(asc_dvc);
b009bef6 8465 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
27c868c2
MW
8466 }
8467 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
8468 if (asc_dvc->err_code != 0)
8469 return (UW_ERR);
8470 if (!AscFindSignature(asc_dvc->iop_base)) {
8471 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
8472 return (warn_code);
8473 }
8474 AscDisableInterrupt(iop_base);
8475 warn_code |= AscInitLram(asc_dvc);
8476 if (asc_dvc->err_code != 0)
8477 return (UW_ERR);
8478 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
8479 (ulong)_asc_mcode_chksum);
8480 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
8481 _asc_mcode_size) != _asc_mcode_chksum) {
8482 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
8483 return (warn_code);
8484 }
8485 warn_code |= AscInitMicroCodeVar(asc_dvc);
8486 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
8487 AscEnableInterrupt(iop_base);
8488 return (warn_code);
1da177e4
LT
8489}
8490
78e77d8b 8491static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8492{
27c868c2
MW
8493 int i;
8494 PortAddr iop_base;
8495 ushort warn_code;
8496 uchar chip_version;
8497
8498 iop_base = asc_dvc->iop_base;
8499 warn_code = 0;
8500 asc_dvc->err_code = 0;
8501 if ((asc_dvc->bus_type &
8502 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
8503 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
8504 }
8505 AscSetChipControl(iop_base, CC_HALT);
8506 AscSetChipStatus(iop_base, 0);
8507 asc_dvc->bug_fix_cntl = 0;
8508 asc_dvc->pci_fix_asyn_xfer = 0;
8509 asc_dvc->pci_fix_asyn_xfer_always = 0;
8510 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
8511 asc_dvc->sdtr_done = 0;
8512 asc_dvc->cur_total_qng = 0;
8513 asc_dvc->is_in_int = 0;
8514 asc_dvc->in_critical_cnt = 0;
8515 asc_dvc->last_q_shortage = 0;
8516 asc_dvc->use_tagged_qng = 0;
8517 asc_dvc->no_scam = 0;
8518 asc_dvc->unit_not_ready = 0;
8519 asc_dvc->queue_full_or_busy = 0;
8520 asc_dvc->redo_scam = 0;
8521 asc_dvc->res2 = 0;
8522 asc_dvc->host_init_sdtr_index = 0;
8523 asc_dvc->cfg->can_tagged_qng = 0;
8524 asc_dvc->cfg->cmd_qng_enabled = 0;
8525 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
8526 asc_dvc->init_sdtr = 0;
8527 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
8528 asc_dvc->scsi_reset_wait = 3;
8529 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
8530 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
8531 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
8532 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
8533 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
8534 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
8535 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
8536 ASC_LIB_VERSION_MINOR;
8537 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
8538 asc_dvc->cfg->chip_version = chip_version;
8539 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
8540 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
8541 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
8542 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
8543 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
8544 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
8545 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
8546 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
8547 asc_dvc->max_sdtr_index = 7;
8548 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
8549 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
8550 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
8551 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
8552 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
8553 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
8554 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
8555 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
8556 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
8557 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
8558 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
8559 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
8560 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
8561 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
8562 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
8563 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
8564 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
8565 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
8566 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
8567 asc_dvc->max_sdtr_index = 15;
8568 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
8569 AscSetExtraControl(iop_base,
8570 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8571 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
8572 AscSetExtraControl(iop_base,
8573 (SEC_ACTIVE_NEGATE |
8574 SEC_ENABLE_FILTER));
8575 }
8576 }
8577 if (asc_dvc->bus_type == ASC_IS_PCI) {
8578 AscSetExtraControl(iop_base,
8579 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
8580 }
1da177e4 8581
27c868c2 8582 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
1da177e4 8583#ifdef CONFIG_ISA
27c868c2 8584 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
59fcf844
MW
8585 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
8586 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
8587 asc_dvc->bus_type = ASC_IS_ISAPNP;
8588 }
27c868c2
MW
8589 asc_dvc->cfg->isa_dma_channel =
8590 (uchar)AscGetIsaDmaChannel(iop_base);
8591 }
1da177e4 8592#endif /* CONFIG_ISA */
27c868c2
MW
8593 for (i = 0; i <= ASC_MAX_TID; i++) {
8594 asc_dvc->cur_dvc_qng[i] = 0;
8595 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
8596 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
8597 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
8598 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
8599 }
8600 return (warn_code);
1da177e4
LT
8601}
8602
78e77d8b 8603static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 8604{
27c868c2
MW
8605 ASCEEP_CONFIG eep_config_buf;
8606 ASCEEP_CONFIG *eep_config;
8607 PortAddr iop_base;
8608 ushort chksum;
8609 ushort warn_code;
8610 ushort cfg_msw, cfg_lsw;
8611 int i;
8612 int write_eep = 0;
8613
8614 iop_base = asc_dvc->iop_base;
8615 warn_code = 0;
8616 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
8617 AscStopQueueExe(iop_base);
8618 if ((AscStopChip(iop_base) == FALSE) ||
8619 (AscGetChipScsiCtrl(iop_base) != 0)) {
8620 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
8621 AscResetChipAndScsiBus(asc_dvc);
b009bef6 8622 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
27c868c2
MW
8623 }
8624 if (AscIsChipHalted(iop_base) == FALSE) {
8625 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
8626 return (warn_code);
8627 }
8628 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
8629 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
8630 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
8631 return (warn_code);
8632 }
8633 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
8634 cfg_msw = AscGetChipCfgMsw(iop_base);
8635 cfg_lsw = AscGetChipCfgLsw(iop_base);
8636 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 8637 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
8638 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
8639 AscSetChipCfgMsw(iop_base, cfg_msw);
8640 }
8641 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
8642 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
8643 if (chksum == 0) {
8644 chksum = 0xaa55;
8645 }
8646 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
8647 warn_code |= ASC_WARN_AUTO_CONFIG;
8648 if (asc_dvc->cfg->chip_version == 3) {
8649 if (eep_config->cfg_lsw != cfg_lsw) {
8650 warn_code |= ASC_WARN_EEPROM_RECOVER;
8651 eep_config->cfg_lsw =
8652 AscGetChipCfgLsw(iop_base);
8653 }
8654 if (eep_config->cfg_msw != cfg_msw) {
8655 warn_code |= ASC_WARN_EEPROM_RECOVER;
8656 eep_config->cfg_msw =
8657 AscGetChipCfgMsw(iop_base);
8658 }
8659 }
8660 }
8661 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
8662 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
8663 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
8664 eep_config->chksum);
8665 if (chksum != eep_config->chksum) {
8666 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
8667 ASC_CHIP_VER_PCI_ULTRA_3050) {
8668 ASC_DBG(1,
8669 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
8670 eep_config->init_sdtr = 0xFF;
8671 eep_config->disc_enable = 0xFF;
8672 eep_config->start_motor = 0xFF;
8673 eep_config->use_cmd_qng = 0;
8674 eep_config->max_total_qng = 0xF0;
8675 eep_config->max_tag_qng = 0x20;
8676 eep_config->cntl = 0xBFFF;
8677 ASC_EEP_SET_CHIP_ID(eep_config, 7);
8678 eep_config->no_scam = 0;
8679 eep_config->adapter_info[0] = 0;
8680 eep_config->adapter_info[1] = 0;
8681 eep_config->adapter_info[2] = 0;
8682 eep_config->adapter_info[3] = 0;
8683 eep_config->adapter_info[4] = 0;
8684 /* Indicate EEPROM-less board. */
8685 eep_config->adapter_info[5] = 0xBB;
8686 } else {
8687 ASC_PRINT
8688 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
8689 write_eep = 1;
8690 warn_code |= ASC_WARN_EEPROM_CHKSUM;
8691 }
8692 }
8693 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
8694 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
8695 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
8696 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
8697 asc_dvc->start_motor = eep_config->start_motor;
8698 asc_dvc->dvc_cntl = eep_config->cntl;
8699 asc_dvc->no_scam = eep_config->no_scam;
8700 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
8701 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
8702 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
8703 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
8704 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
8705 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
8706 if (!AscTestExternalLram(asc_dvc)) {
8707 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
8708 ASC_IS_PCI_ULTRA)) {
8709 eep_config->max_total_qng =
8710 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
8711 eep_config->max_tag_qng =
8712 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
8713 } else {
8714 eep_config->cfg_msw |= 0x0800;
8715 cfg_msw |= 0x0800;
8716 AscSetChipCfgMsw(iop_base, cfg_msw);
8717 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
8718 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
8719 }
8720 } else {
8721 }
8722 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
8723 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
8724 }
8725 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
8726 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
8727 }
8728 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
8729 eep_config->max_tag_qng = eep_config->max_total_qng;
8730 }
8731 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
8732 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
8733 }
8734 asc_dvc->max_total_qng = eep_config->max_total_qng;
8735 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
8736 eep_config->use_cmd_qng) {
8737 eep_config->disc_enable = eep_config->use_cmd_qng;
8738 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
8739 }
8740 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
8741 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
8742 }
8743 ASC_EEP_SET_CHIP_ID(eep_config,
8744 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
8745 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
8746 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
8747 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
8748 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
8749 }
1da177e4 8750
27c868c2
MW
8751 for (i = 0; i <= ASC_MAX_TID; i++) {
8752 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
8753 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
8754 asc_dvc->cfg->sdtr_period_offset[i] =
8755 (uchar)(ASC_DEF_SDTR_OFFSET |
8756 (asc_dvc->host_init_sdtr_index << 4));
8757 }
8758 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
8759 if (write_eep) {
8760 if ((i =
8761 AscSetEEPConfig(iop_base, eep_config,
8762 asc_dvc->bus_type)) != 0) {
8763 ASC_PRINT1
8764 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
8765 i);
8766 } else {
8767 ASC_PRINT
8768 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
8769 }
8770 }
8771 return (warn_code);
1da177e4
LT
8772}
8773
27c868c2 8774static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8775{
27c868c2
MW
8776 int i;
8777 ushort warn_code;
8778 PortAddr iop_base;
8779 ASC_PADDR phy_addr;
8780 ASC_DCNT phy_size;
8781
8782 iop_base = asc_dvc->iop_base;
8783 warn_code = 0;
8784 for (i = 0; i <= ASC_MAX_TID; i++) {
8785 AscPutMCodeInitSDTRAtID(iop_base, i,
8786 asc_dvc->cfg->sdtr_period_offset[i]
8787 );
8788 }
1da177e4 8789
27c868c2
MW
8790 AscInitQLinkVar(asc_dvc);
8791 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
8792 asc_dvc->cfg->disc_enable);
8793 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
8794 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
8795
8796 /* Align overrun buffer on an 8 byte boundary. */
8797 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
8798 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
8799 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
8800 (uchar *)&phy_addr, 1);
8801 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
8802 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
8803 (uchar *)&phy_size, 1);
8804
8805 asc_dvc->cfg->mcode_date =
8806 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
8807 asc_dvc->cfg->mcode_version =
8808 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
8809
8810 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
8811 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
8812 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
8813 return (warn_code);
8814 }
8815 if (AscStartChip(iop_base) != 1) {
8816 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
8817 return (warn_code);
8818 }
1da177e4 8819
27c868c2 8820 return (warn_code);
1da177e4
LT
8821}
8822
78e77d8b 8823static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 8824{
27c868c2
MW
8825 PortAddr iop_base;
8826 ushort q_addr;
8827 ushort saved_word;
8828 int sta;
8829
8830 iop_base = asc_dvc->iop_base;
8831 sta = 0;
8832 q_addr = ASC_QNO_TO_QADDR(241);
8833 saved_word = AscReadLramWord(iop_base, q_addr);
8834 AscSetChipLramAddr(iop_base, q_addr);
8835 AscSetChipLramData(iop_base, 0x55AA);
b009bef6 8836 mdelay(10);
27c868c2
MW
8837 AscSetChipLramAddr(iop_base, q_addr);
8838 if (AscGetChipLramData(iop_base) == 0x55AA) {
8839 sta = 1;
8840 AscWriteLramWord(iop_base, q_addr, saved_word);
8841 }
8842 return (sta);
1da177e4
LT
8843}
8844
78e77d8b 8845static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 8846{
27c868c2
MW
8847 uchar read_back;
8848 int retry;
8849
8850 retry = 0;
8851 while (TRUE) {
8852 AscSetChipEEPCmd(iop_base, cmd_reg);
b009bef6 8853 mdelay(1);
27c868c2
MW
8854 read_back = AscGetChipEEPCmd(iop_base);
8855 if (read_back == cmd_reg) {
8856 return (1);
8857 }
8858 if (retry++ > ASC_EEP_MAX_RETRY) {
8859 return (0);
8860 }
8861 }
1da177e4
LT
8862}
8863
78e77d8b 8864static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 8865{
27c868c2
MW
8866 ushort read_back;
8867 int retry;
8868
8869 retry = 0;
8870 while (TRUE) {
8871 AscSetChipEEPData(iop_base, data_reg);
b009bef6 8872 mdelay(1);
27c868c2
MW
8873 read_back = AscGetChipEEPData(iop_base);
8874 if (read_back == data_reg) {
8875 return (1);
8876 }
8877 if (retry++ > ASC_EEP_MAX_RETRY) {
8878 return (0);
8879 }
8880 }
1da177e4
LT
8881}
8882
78e77d8b 8883static void __devinit AscWaitEEPRead(void)
1da177e4 8884{
b009bef6 8885 mdelay(1);
27c868c2 8886 return;
1da177e4
LT
8887}
8888
78e77d8b 8889static void __devinit AscWaitEEPWrite(void)
1da177e4 8890{
b009bef6 8891 mdelay(20);
27c868c2 8892 return;
1da177e4
LT
8893}
8894
78e77d8b 8895static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 8896{
27c868c2
MW
8897 ushort read_wval;
8898 uchar cmd_reg;
8899
8900 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8901 AscWaitEEPRead();
8902 cmd_reg = addr | ASC_EEP_CMD_READ;
8903 AscWriteEEPCmdReg(iop_base, cmd_reg);
8904 AscWaitEEPRead();
8905 read_wval = AscGetChipEEPData(iop_base);
8906 AscWaitEEPRead();
8907 return (read_wval);
1da177e4
LT
8908}
8909
78e77d8b 8910static ushort __devinit
27c868c2 8911AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 8912{
27c868c2
MW
8913 ushort read_wval;
8914
8915 read_wval = AscReadEEPWord(iop_base, addr);
8916 if (read_wval != word_val) {
8917 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
8918 AscWaitEEPRead();
8919 AscWriteEEPDataReg(iop_base, word_val);
8920 AscWaitEEPRead();
8921 AscWriteEEPCmdReg(iop_base,
8922 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
8923 AscWaitEEPWrite();
8924 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
8925 AscWaitEEPRead();
8926 return (AscReadEEPWord(iop_base, addr));
8927 }
8928 return (read_wval);
1da177e4
LT
8929}
8930
78e77d8b 8931static ushort __devinit
27c868c2 8932AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 8933{
27c868c2
MW
8934 ushort wval;
8935 ushort sum;
8936 ushort *wbuf;
8937 int cfg_beg;
8938 int cfg_end;
8939 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8940 int s_addr;
8941
8942 wbuf = (ushort *)cfg_buf;
8943 sum = 0;
8944 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
8945 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8946 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8947 sum += *wbuf;
8948 }
8949 if (bus_type & ASC_IS_VL) {
8950 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
8951 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
8952 } else {
8953 cfg_beg = ASC_EEP_DVC_CFG_BEG;
8954 cfg_end = ASC_EEP_MAX_DVC_ADDR;
8955 }
8956 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
8957 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
8958 if (s_addr <= uchar_end_in_config) {
8959 /*
8960 * Swap all char fields - must unswap bytes already swapped
8961 * by AscReadEEPWord().
8962 */
8963 *wbuf = le16_to_cpu(wval);
8964 } else {
8965 /* Don't swap word field at the end - cntl field. */
8966 *wbuf = wval;
8967 }
8968 sum += wval; /* Checksum treats all EEPROM data as words. */
8969 }
8970 /*
8971 * Read the checksum word which will be compared against 'sum'
8972 * by the caller. Word field already swapped.
8973 */
8974 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
8975 return (sum);
1da177e4
LT
8976}
8977
78e77d8b 8978static int __devinit
27c868c2 8979AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 8980{
27c868c2
MW
8981 int n_error;
8982 ushort *wbuf;
8983 ushort word;
8984 ushort sum;
8985 int s_addr;
8986 int cfg_beg;
8987 int cfg_end;
8988 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
8989
8990 wbuf = (ushort *)cfg_buf;
8991 n_error = 0;
8992 sum = 0;
8993 /* Write two config words; AscWriteEEPWord() will swap bytes. */
8994 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
8995 sum += *wbuf;
8996 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
8997 n_error++;
8998 }
8999 }
9000 if (bus_type & ASC_IS_VL) {
9001 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9002 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9003 } else {
9004 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9005 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9006 }
9007 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9008 if (s_addr <= uchar_end_in_config) {
9009 /*
9010 * This is a char field. Swap char fields before they are
9011 * swapped again by AscWriteEEPWord().
9012 */
9013 word = cpu_to_le16(*wbuf);
9014 if (word !=
9015 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
9016 n_error++;
9017 }
9018 } else {
9019 /* Don't swap word field at the end - cntl field. */
9020 if (*wbuf !=
9021 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9022 n_error++;
9023 }
9024 }
9025 sum += *wbuf; /* Checksum calculated from word values. */
9026 }
9027 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
9028 *wbuf = sum;
9029 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
9030 n_error++;
9031 }
1da177e4 9032
27c868c2
MW
9033 /* Read EEPROM back again. */
9034 wbuf = (ushort *)cfg_buf;
9035 /*
9036 * Read two config words; Byte-swapping done by AscReadEEPWord().
9037 */
9038 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9039 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
9040 n_error++;
9041 }
9042 }
9043 if (bus_type & ASC_IS_VL) {
9044 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9045 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9046 } else {
9047 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9048 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9049 }
9050 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9051 if (s_addr <= uchar_end_in_config) {
9052 /*
9053 * Swap all char fields. Must unswap bytes already swapped
9054 * by AscReadEEPWord().
9055 */
9056 word =
9057 le16_to_cpu(AscReadEEPWord
9058 (iop_base, (uchar)s_addr));
9059 } else {
9060 /* Don't swap word field at the end - cntl field. */
9061 word = AscReadEEPWord(iop_base, (uchar)s_addr);
9062 }
9063 if (*wbuf != word) {
9064 n_error++;
9065 }
9066 }
9067 /* Read checksum; Byte swapping not needed. */
9068 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
9069 n_error++;
9070 }
9071 return (n_error);
1da177e4
LT
9072}
9073
78e77d8b 9074static int __devinit
27c868c2 9075AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9076{
27c868c2
MW
9077 int retry;
9078 int n_error;
9079
9080 retry = 0;
9081 while (TRUE) {
9082 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
9083 bus_type)) == 0) {
9084 break;
9085 }
9086 if (++retry > ASC_EEP_MAX_RETRY) {
9087 break;
9088 }
9089 }
9090 return (n_error);
1da177e4
LT
9091}
9092
47d853cc 9093static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
1da177e4 9094{
47d853cc
MW
9095 char type = sdev->type;
9096 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
27c868c2 9097
95c9f162
MW
9098 if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9099 return;
9100 if (asc_dvc->init_sdtr & tid_bits)
9101 return;
9102
9103 if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9104 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9105
9106 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9107 if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9108 (type == TYPE_ROM) || (type == TYPE_TAPE))
9109 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
27c868c2 9110
95c9f162
MW
9111 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9112 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
47d853cc 9113 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
1da177e4
LT
9114}
9115
27c868c2 9116static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 9117{
27c868c2
MW
9118 uchar byte_data;
9119 ushort word_data;
9120
9121 if (isodd_word(addr)) {
9122 AscSetChipLramAddr(iop_base, addr - 1);
9123 word_data = AscGetChipLramData(iop_base);
9124 byte_data = (uchar)((word_data >> 8) & 0xFF);
9125 } else {
9126 AscSetChipLramAddr(iop_base, addr);
9127 word_data = AscGetChipLramData(iop_base);
9128 byte_data = (uchar)(word_data & 0xFF);
9129 }
9130 return (byte_data);
1da177e4 9131}
27c868c2
MW
9132
9133static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 9134{
27c868c2 9135 ushort word_data;
1da177e4 9136
27c868c2
MW
9137 AscSetChipLramAddr(iop_base, addr);
9138 word_data = AscGetChipLramData(iop_base);
9139 return (word_data);
1da177e4
LT
9140}
9141
9142#if CC_VERY_LONG_SG_LIST
27c868c2 9143static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 9144{
27c868c2
MW
9145 ushort val_low, val_high;
9146 ASC_DCNT dword_data;
9147
9148 AscSetChipLramAddr(iop_base, addr);
9149 val_low = AscGetChipLramData(iop_base);
9150 val_high = AscGetChipLramData(iop_base);
9151 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
9152 return (dword_data);
1da177e4
LT
9153}
9154#endif /* CC_VERY_LONG_SG_LIST */
9155
27c868c2 9156static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 9157{
27c868c2
MW
9158 AscSetChipLramAddr(iop_base, addr);
9159 AscSetChipLramData(iop_base, word_val);
9160 return;
1da177e4
LT
9161}
9162
27c868c2 9163static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 9164{
27c868c2
MW
9165 ushort word_data;
9166
9167 if (isodd_word(addr)) {
9168 addr--;
9169 word_data = AscReadLramWord(iop_base, addr);
9170 word_data &= 0x00FF;
9171 word_data |= (((ushort)byte_val << 8) & 0xFF00);
9172 } else {
9173 word_data = AscReadLramWord(iop_base, addr);
9174 word_data &= 0xFF00;
9175 word_data |= ((ushort)byte_val & 0x00FF);
9176 }
9177 AscWriteLramWord(iop_base, addr, word_data);
9178 return;
1da177e4
LT
9179}
9180
9181/*
9182 * Copy 2 bytes to LRAM.
9183 *
9184 * The source data is assumed to be in little-endian order in memory
9185 * and is maintained in little-endian order when written to LRAM.
9186 */
27c868c2
MW
9187static void
9188AscMemWordCopyPtrToLram(PortAddr iop_base,
9189 ushort s_addr, uchar *s_buffer, int words)
1da177e4 9190{
27c868c2
MW
9191 int i;
9192
9193 AscSetChipLramAddr(iop_base, s_addr);
9194 for (i = 0; i < 2 * words; i += 2) {
9195 /*
9196 * On a little-endian system the second argument below
9197 * produces a little-endian ushort which is written to
9198 * LRAM in little-endian order. On a big-endian system
9199 * the second argument produces a big-endian ushort which
9200 * is "transparently" byte-swapped by outpw() and written
9201 * in little-endian order to LRAM.
9202 */
9203 outpw(iop_base + IOP_RAM_DATA,
9204 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
9205 }
9206 return;
1da177e4
LT
9207}
9208
9209/*
9210 * Copy 4 bytes to LRAM.
9211 *
9212 * The source data is assumed to be in little-endian order in memory
9213 * and is maintained in little-endian order when writen to LRAM.
9214 */
27c868c2
MW
9215static void
9216AscMemDWordCopyPtrToLram(PortAddr iop_base,
9217 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 9218{
27c868c2
MW
9219 int i;
9220
9221 AscSetChipLramAddr(iop_base, s_addr);
9222 for (i = 0; i < 4 * dwords; i += 4) {
9223 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
9224 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
9225 }
9226 return;
1da177e4
LT
9227}
9228
9229/*
9230 * Copy 2 bytes from LRAM.
9231 *
9232 * The source data is assumed to be in little-endian order in LRAM
9233 * and is maintained in little-endian order when written to memory.
9234 */
27c868c2
MW
9235static void
9236AscMemWordCopyPtrFromLram(PortAddr iop_base,
9237 ushort s_addr, uchar *d_buffer, int words)
1da177e4 9238{
27c868c2
MW
9239 int i;
9240 ushort word;
9241
9242 AscSetChipLramAddr(iop_base, s_addr);
9243 for (i = 0; i < 2 * words; i += 2) {
9244 word = inpw(iop_base + IOP_RAM_DATA);
9245 d_buffer[i] = word & 0xff;
9246 d_buffer[i + 1] = (word >> 8) & 0xff;
9247 }
9248 return;
1da177e4
LT
9249}
9250
27c868c2 9251static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 9252{
27c868c2
MW
9253 ASC_DCNT sum;
9254 int i;
1da177e4 9255
27c868c2
MW
9256 sum = 0L;
9257 for (i = 0; i < words; i++, s_addr += 2) {
9258 sum += AscReadLramWord(iop_base, s_addr);
9259 }
9260 return (sum);
1da177e4
LT
9261}
9262
27c868c2
MW
9263static void
9264AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 9265{
27c868c2 9266 int i;
1da177e4 9267
27c868c2
MW
9268 AscSetChipLramAddr(iop_base, s_addr);
9269 for (i = 0; i < words; i++) {
9270 AscSetChipLramData(iop_base, set_wval);
9271 }
9272 return;
1da177e4
LT
9273}
9274
1da177e4 9275/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9276static unsigned char _adv_asc3550_buf[] = {
9277 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
629d688d
MW
9278 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
9279 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
9280 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
27c868c2 9281 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
629d688d
MW
9282 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
9283 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
9284 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
27c868c2 9285 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
629d688d
MW
9286 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
9287 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
9288 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
27c868c2 9289 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
629d688d
MW
9290 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
9291 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
9292 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
27c868c2 9293 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
629d688d
MW
9294 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
9295 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
9296 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
27c868c2 9297 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
629d688d
MW
9298 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
9299 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
9300 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
27c868c2 9301 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
629d688d
MW
9302 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
9303 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
9304 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
27c868c2 9305 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
629d688d
MW
9306 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
9307 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
9308 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
27c868c2 9309 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
629d688d
MW
9310 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
9311 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
9312 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
27c868c2 9313 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
629d688d
MW
9314 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
9315 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
9316 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
27c868c2 9317 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
629d688d
MW
9318 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
9319 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
9320 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
27c868c2 9321 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
9322 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
9323 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
9324 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
27c868c2 9325 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
9326 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
9327 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
9328 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
27c868c2 9329 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
629d688d
MW
9330 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
9331 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
9332 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
27c868c2 9333 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
629d688d
MW
9334 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
9335 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
9336 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
27c868c2 9337 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
629d688d
MW
9338 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
9339 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
9340 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
27c868c2 9341 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
9342 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
9343 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
9344 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
27c868c2 9345 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
629d688d
MW
9346 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
9347 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
9348 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
27c868c2 9349 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
629d688d
MW
9350 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
9351 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
9352 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
27c868c2 9353 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
629d688d
MW
9354 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
9355 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
9356 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
27c868c2 9357 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
629d688d
MW
9358 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
9359 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
9360 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
27c868c2 9361 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
629d688d
MW
9362 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
9363 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
9364 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
27c868c2 9365 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
629d688d
MW
9366 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
9367 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
9368 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
27c868c2 9369 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
629d688d
MW
9370 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
9371 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
9372 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
27c868c2 9373 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
629d688d
MW
9374 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
9375 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
9376 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
27c868c2 9377 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
629d688d
MW
9378 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
9379 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
9380 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
27c868c2 9381 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
629d688d
MW
9382 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
9383 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
9384 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
27c868c2 9385 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
629d688d
MW
9386 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
9387 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
9388 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
27c868c2 9389 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
629d688d
MW
9390 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
9391 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
9392 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
27c868c2 9393 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
629d688d
MW
9394 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
9395 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
9396 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
27c868c2 9397 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
629d688d
MW
9398 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
9399 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
9400 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
27c868c2 9401 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
629d688d
MW
9402 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
9403 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
9404 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
27c868c2 9405 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
629d688d
MW
9406 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
9407 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
9408 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
27c868c2 9409 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
629d688d
MW
9410 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
9411 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
9412 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
27c868c2 9413 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
629d688d
MW
9414 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
9415 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
9416 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
27c868c2 9417 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
629d688d
MW
9418 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
9419 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
9420 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
27c868c2 9421 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
629d688d
MW
9422 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
9423 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
9424 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
27c868c2 9425 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
629d688d
MW
9426 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
9427 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
9428 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
27c868c2 9429 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
629d688d
MW
9430 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
9431 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
9432 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
27c868c2 9433 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
629d688d
MW
9434 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
9435 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
9436 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
27c868c2 9437 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
629d688d
MW
9438 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
9439 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
9440 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
27c868c2 9441 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
629d688d
MW
9442 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
9443 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
9444 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
27c868c2 9445 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
629d688d
MW
9446 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
9447 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
9448 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
27c868c2 9449 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
629d688d
MW
9450 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
9451 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
9452 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
27c868c2 9453 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
629d688d
MW
9454 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
9455 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
9456 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
27c868c2 9457 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
629d688d
MW
9458 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
9459 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
9460 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
27c868c2 9461 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
629d688d
MW
9462 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
9463 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
9464 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
27c868c2 9465 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
629d688d
MW
9466 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
9467 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
9468 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
27c868c2 9469 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
629d688d
MW
9470 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
9471 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
9472 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
27c868c2 9473 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
629d688d
MW
9474 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
9475 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
9476 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
27c868c2 9477 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
629d688d
MW
9478 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
9479 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
9480 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
27c868c2 9481 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
629d688d
MW
9482 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
9483 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
9484 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
27c868c2 9485 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
629d688d
MW
9486 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
9487 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
9488 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
27c868c2 9489 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
629d688d
MW
9490 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
9491 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
9492 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
27c868c2 9493 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
629d688d
MW
9494 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
9495 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
9496 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
27c868c2 9497 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
629d688d
MW
9498 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
9499 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
9500 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
27c868c2 9501 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
629d688d
MW
9502 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
9503 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
9504 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
27c868c2 9505 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
629d688d
MW
9506 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
9507 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
9508 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
27c868c2 9509 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
629d688d
MW
9510 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
9511 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
9512 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
27c868c2 9513 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
629d688d
MW
9514 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
9515 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
9516 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
27c868c2 9517 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
629d688d
MW
9518 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
9519 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
9520 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
27c868c2 9521 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
629d688d
MW
9522 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
9523 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
9524 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
27c868c2 9525 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
629d688d
MW
9526 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
9527 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
9528 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
27c868c2 9529 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
629d688d
MW
9530 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
9531 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
9532 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
27c868c2 9533 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
629d688d
MW
9534 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
9535 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
9536 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
27c868c2 9537 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
629d688d
MW
9538 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
9539 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
9540 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
27c868c2 9541 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
629d688d
MW
9542 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
9543 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
9544 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
27c868c2 9545 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
629d688d
MW
9546 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
9547 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
9548 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
27c868c2 9549 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
629d688d
MW
9550 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
9551 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
9552 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
27c868c2 9553 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
629d688d
MW
9554 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
9555 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
9556 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
27c868c2 9557 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
629d688d
MW
9558 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
9559 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
9560 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
27c868c2 9561 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
629d688d
MW
9562 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
9563 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
9564 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
27c868c2 9565 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
629d688d
MW
9566 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
9567 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
9568 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
27c868c2 9569 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
629d688d
MW
9570 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
9571 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
9572 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
27c868c2 9573 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
629d688d
MW
9574 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
9575 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
9576 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
27c868c2 9577 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
629d688d
MW
9578 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
9579 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
9580 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
27c868c2 9581 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
629d688d
MW
9582 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
9583 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
9584 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
27c868c2 9585 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
629d688d
MW
9586 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
9587 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
9588 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
27c868c2 9589 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
629d688d
MW
9590 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
9591 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
9592 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
27c868c2 9593 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
629d688d
MW
9594 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
9595 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
9596 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
27c868c2 9597 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
629d688d
MW
9598 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
9599 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
9600 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
27c868c2 9601 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
629d688d
MW
9602 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
9603 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
9604 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
27c868c2 9605 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
629d688d
MW
9606 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
9607 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
9608 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
27c868c2 9609 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
629d688d
MW
9610 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
9611 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
9612 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
27c868c2 9613 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
629d688d
MW
9614 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
9615 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
9616 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
27c868c2 9617 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
629d688d
MW
9618 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
9619 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
9620 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
27c868c2 9621 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
629d688d
MW
9622 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
9623 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
9624 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
27c868c2 9625 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
629d688d
MW
9626 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
9627 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
9628 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
27c868c2 9629 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
629d688d
MW
9630 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
9631 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
9632 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
27c868c2 9633 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
629d688d
MW
9634 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
9635 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
9636 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
27c868c2 9637 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
629d688d
MW
9638 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
9639 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
9640 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
27c868c2 9641 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
629d688d
MW
9642 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
9643 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
9644 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
27c868c2 9645 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
629d688d
MW
9646 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
9647 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
9648 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
27c868c2 9649 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
629d688d
MW
9650 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
9651 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
9652 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
27c868c2 9653 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
629d688d
MW
9654 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
9655 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
9656 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
27c868c2 9657 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
629d688d
MW
9658 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
9659 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
9660 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
27c868c2 9661 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
629d688d
MW
9662 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
9663 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
9664 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
27c868c2 9665 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
629d688d
MW
9666 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
9667 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
9668 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
27c868c2 9669 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
629d688d
MW
9670 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
9671 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
9672 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
27c868c2 9673 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
629d688d
MW
9674 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
9675 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
9676 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
27c868c2 9677 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
629d688d
MW
9678 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
9679 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
9680 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
27c868c2 9681 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
629d688d
MW
9682 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
9683 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
9684 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
27c868c2 9685 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
629d688d
MW
9686 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
9687 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
9688 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
27c868c2 9689 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
629d688d
MW
9690 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
9691 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
9692 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
27c868c2 9693 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
629d688d
MW
9694 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
9695 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
1da177e4
LT
9696};
9697
27c868c2
MW
9698static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
9699static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
9700
9701/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
9702static unsigned char _adv_asc38C0800_buf[] = {
9703 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
629d688d
MW
9704 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
9705 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
9706 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
27c868c2 9707 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
629d688d
MW
9708 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
9709 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
9710 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
27c868c2 9711 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
629d688d
MW
9712 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
9713 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
9714 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
27c868c2 9715 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
629d688d
MW
9716 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
9717 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
9718 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
27c868c2 9719 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
629d688d
MW
9720 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
9721 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
9722 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
27c868c2 9723 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
629d688d
MW
9724 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
9725 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
9726 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
27c868c2 9727 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
629d688d
MW
9728 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
9729 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
9730 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
27c868c2 9731 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
629d688d
MW
9732 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
9733 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
9734 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
27c868c2 9735 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
629d688d
MW
9736 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
9737 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
9738 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
27c868c2 9739 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
629d688d
MW
9740 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
9741 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
9742 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
27c868c2 9743 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
629d688d
MW
9744 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
9745 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
9746 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
27c868c2 9747 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
9748 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
9749 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
9750 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
27c868c2 9751 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
9752 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
9753 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
9754 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
27c868c2 9755 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
629d688d
MW
9756 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
9757 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
9758 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
27c868c2 9759 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
629d688d
MW
9760 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
9761 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
9762 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
27c868c2 9763 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
629d688d
MW
9764 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
9765 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
9766 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
27c868c2 9767 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
9768 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
9769 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
9770 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
27c868c2 9771 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
629d688d
MW
9772 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
9773 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
9774 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
27c868c2 9775 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
629d688d
MW
9776 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
9777 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
9778 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
27c868c2 9779 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
629d688d
MW
9780 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
9781 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
9782 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
27c868c2 9783 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
629d688d
MW
9784 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
9785 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
9786 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
27c868c2 9787 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
629d688d
MW
9788 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
9789 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
9790 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
27c868c2 9791 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
629d688d
MW
9792 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
9793 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
9794 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
27c868c2 9795 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
629d688d
MW
9796 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
9797 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
9798 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
27c868c2 9799 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
629d688d
MW
9800 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
9801 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
9802 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
27c868c2 9803 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
629d688d
MW
9804 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
9805 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
9806 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
27c868c2 9807 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
629d688d
MW
9808 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
9809 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
9810 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
27c868c2 9811 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
629d688d
MW
9812 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
9813 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
9814 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
27c868c2 9815 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
629d688d
MW
9816 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
9817 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
9818 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
27c868c2 9819 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
629d688d
MW
9820 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
9821 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
9822 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
27c868c2 9823 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
629d688d
MW
9824 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
9825 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
9826 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
27c868c2 9827 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
629d688d
MW
9828 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
9829 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
9830 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
27c868c2 9831 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
629d688d
MW
9832 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
9833 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
9834 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
27c868c2 9835 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
629d688d
MW
9836 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
9837 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
9838 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
27c868c2 9839 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
629d688d
MW
9840 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
9841 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
9842 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
27c868c2 9843 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
629d688d
MW
9844 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
9845 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
9846 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
27c868c2 9847 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
629d688d
MW
9848 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
9849 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
9850 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
27c868c2 9851 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
629d688d
MW
9852 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
9853 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
9854 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
27c868c2 9855 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
629d688d
MW
9856 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
9857 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
9858 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
27c868c2 9859 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
629d688d
MW
9860 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
9861 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
9862 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
27c868c2 9863 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
629d688d
MW
9864 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
9865 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
9866 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
27c868c2 9867 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
629d688d
MW
9868 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
9869 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
9870 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
27c868c2 9871 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
629d688d
MW
9872 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
9873 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
9874 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
27c868c2 9875 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
629d688d
MW
9876 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
9877 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
9878 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
27c868c2 9879 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
629d688d
MW
9880 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
9881 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
9882 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
27c868c2 9883 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
629d688d
MW
9884 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
9885 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
9886 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
27c868c2 9887 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
629d688d
MW
9888 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
9889 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
9890 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
27c868c2 9891 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
629d688d
MW
9892 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
9893 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
9894 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
27c868c2 9895 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
629d688d
MW
9896 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
9897 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
9898 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
27c868c2 9899 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
629d688d
MW
9900 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
9901 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
9902 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
27c868c2 9903 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
629d688d
MW
9904 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
9905 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
9906 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
27c868c2 9907 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
629d688d
MW
9908 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
9909 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
9910 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
27c868c2 9911 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
629d688d
MW
9912 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
9913 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
9914 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
27c868c2 9915 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
629d688d
MW
9916 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
9917 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
9918 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
27c868c2 9919 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
629d688d
MW
9920 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
9921 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
9922 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
27c868c2 9923 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
629d688d
MW
9924 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
9925 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
9926 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
27c868c2 9927 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
629d688d
MW
9928 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
9929 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
9930 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
27c868c2 9931 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
629d688d
MW
9932 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
9933 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
9934 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
27c868c2 9935 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
629d688d
MW
9936 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
9937 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
9938 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
27c868c2 9939 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
629d688d
MW
9940 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
9941 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
9942 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
27c868c2 9943 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
629d688d
MW
9944 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
9945 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
9946 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
27c868c2 9947 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
629d688d
MW
9948 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
9949 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
9950 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
27c868c2 9951 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
629d688d
MW
9952 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
9953 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
9954 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
27c868c2 9955 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
629d688d
MW
9956 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
9957 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
9958 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
27c868c2 9959 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
629d688d
MW
9960 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
9961 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
9962 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
27c868c2 9963 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
629d688d
MW
9964 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
9965 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
9966 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
27c868c2 9967 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
629d688d
MW
9968 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
9969 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
9970 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
27c868c2 9971 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
629d688d
MW
9972 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
9973 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
9974 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
27c868c2 9975 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
629d688d
MW
9976 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
9977 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
9978 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
27c868c2 9979 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
629d688d
MW
9980 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
9981 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
9982 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
27c868c2 9983 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
629d688d
MW
9984 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
9985 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
9986 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
27c868c2 9987 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
629d688d
MW
9988 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
9989 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
9990 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
27c868c2 9991 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
629d688d
MW
9992 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
9993 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
9994 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
27c868c2 9995 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
629d688d
MW
9996 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
9997 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
9998 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
27c868c2 9999 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
629d688d
MW
10000 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
10001 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
10002 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
27c868c2 10003 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
629d688d
MW
10004 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
10005 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
10006 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
27c868c2 10007 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
629d688d
MW
10008 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
10009 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
10010 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
27c868c2 10011 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
629d688d
MW
10012 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
10013 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
10014 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
27c868c2 10015 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
629d688d
MW
10016 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
10017 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
10018 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
27c868c2 10019 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
629d688d
MW
10020 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
10021 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
10022 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
27c868c2 10023 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
629d688d
MW
10024 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
10025 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
10026 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
27c868c2 10027 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
629d688d
MW
10028 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
10029 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
10030 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
27c868c2 10031 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
629d688d
MW
10032 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
10033 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
10034 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
27c868c2 10035 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
629d688d
MW
10036 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
10037 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
10038 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
27c868c2 10039 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
629d688d
MW
10040 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
10041 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
10042 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
27c868c2 10043 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
629d688d
MW
10044 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
10045 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
10046 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
27c868c2 10047 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
629d688d
MW
10048 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
10049 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10050 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
27c868c2 10051 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
629d688d
MW
10052 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10053 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
10054 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
27c868c2 10055 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
629d688d
MW
10056 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
10057 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
10058 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
27c868c2 10059 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
629d688d
MW
10060 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
10061 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
10062 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
27c868c2 10063 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
629d688d
MW
10064 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
10065 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
10066 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
27c868c2 10067 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
629d688d
MW
10068 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
10069 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
10070 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
27c868c2 10071 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
629d688d
MW
10072 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
10073 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
10074 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
27c868c2 10075 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
629d688d
MW
10076 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
10077 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
10078 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
27c868c2 10079 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
629d688d
MW
10080 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
10081 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
10082 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
27c868c2 10083 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
629d688d
MW
10084 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
10085 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
10086 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
27c868c2 10087 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
629d688d
MW
10088 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
10089 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
10090 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
27c868c2 10091 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
629d688d
MW
10092 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
10093 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
10094 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
27c868c2 10095 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
629d688d
MW
10096 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
10097 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
10098 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
27c868c2 10099 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
629d688d
MW
10100 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
10101 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
10102 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
27c868c2 10103 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
629d688d
MW
10104 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
10105 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
10106 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
27c868c2 10107 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
629d688d
MW
10108 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
10109 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
10110 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
27c868c2 10111 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
629d688d
MW
10112 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
10113 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
10114 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
27c868c2 10115 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
629d688d
MW
10116 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
10117 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
10118 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
27c868c2 10119 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
629d688d
MW
10120 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
10121 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
10122 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
27c868c2 10123 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
629d688d
MW
10124 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
10125 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
10126 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
27c868c2 10127 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
629d688d
MW
10128 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
10129 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
10130 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
27c868c2 10131 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
629d688d
MW
10132 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
10133 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
10134 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
27c868c2 10135 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
629d688d
MW
10136 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
10137 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
10138 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
27c868c2 10139 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
629d688d
MW
10140 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
10141 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
10142 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
27c868c2 10143 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
629d688d
MW
10144 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
10145 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
10146 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
27c868c2 10147 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
10148};
10149
27c868c2
MW
10150static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
10151static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
10152
10153/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
10154static unsigned char _adv_asc38C1600_buf[] = {
10155 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
629d688d
MW
10156 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
10157 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
10158 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
27c868c2 10159 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
629d688d
MW
10160 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
10161 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
10162 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
27c868c2 10163 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
629d688d
MW
10164 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
10165 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
10166 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
27c868c2 10167 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
629d688d
MW
10168 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
10169 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
10170 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
27c868c2 10171 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
629d688d
MW
10172 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
10173 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
10174 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
27c868c2 10175 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
629d688d
MW
10176 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
10177 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
10178 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
27c868c2 10179 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
629d688d
MW
10180 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
10181 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
10182 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
27c868c2 10183 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
629d688d
MW
10184 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
10185 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
10186 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
27c868c2 10187 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
629d688d
MW
10188 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
10189 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
10190 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
27c868c2 10191 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
629d688d
MW
10192 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
10193 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
10194 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
27c868c2 10195 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
629d688d
MW
10196 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
10197 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
10198 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
27c868c2 10199 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
10200 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
10201 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
10202 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
27c868c2 10203 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
10204 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
10205 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
10206 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
27c868c2 10207 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
629d688d
MW
10208 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
10209 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
10210 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
27c868c2 10211 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
629d688d
MW
10212 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
10213 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
10214 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
27c868c2 10215 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
629d688d
MW
10216 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
10217 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
10218 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
27c868c2 10219 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
629d688d
MW
10220 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
10221 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
10222 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
27c868c2 10223 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
629d688d
MW
10224 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
10225 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
10226 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
27c868c2 10227 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
629d688d
MW
10228 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
10229 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
10230 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
27c868c2 10231 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
629d688d
MW
10232 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
10233 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
10234 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
27c868c2 10235 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
629d688d
MW
10236 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
10237 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
10238 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
27c868c2 10239 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
629d688d
MW
10240 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
10241 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
10242 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
27c868c2 10243 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
629d688d
MW
10244 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
10245 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
10246 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
27c868c2 10247 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
629d688d
MW
10248 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
10249 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
10250 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
27c868c2 10251 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
629d688d
MW
10252 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
10253 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
10254 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
27c868c2 10255 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
629d688d
MW
10256 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
10257 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
10258 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
27c868c2 10259 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
629d688d
MW
10260 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
10261 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
10262 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
27c868c2 10263 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
629d688d
MW
10264 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
10265 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
10266 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
27c868c2 10267 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
629d688d
MW
10268 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
10269 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
10270 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
27c868c2 10271 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
629d688d
MW
10272 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
10273 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
10274 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
27c868c2 10275 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
629d688d
MW
10276 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
10277 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
10278 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
27c868c2 10279 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
629d688d
MW
10280 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
10281 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
10282 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
27c868c2 10283 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
629d688d
MW
10284 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
10285 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
10286 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
27c868c2 10287 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
629d688d
MW
10288 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
10289 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
10290 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
27c868c2 10291 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
629d688d
MW
10292 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
10293 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
10294 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
27c868c2 10295 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
629d688d
MW
10296 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
10297 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
10298 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
27c868c2 10299 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
629d688d
MW
10300 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
10301 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
10302 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
27c868c2 10303 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
629d688d
MW
10304 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
10305 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
10306 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
27c868c2 10307 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
629d688d
MW
10308 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
10309 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
10310 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
27c868c2 10311 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
629d688d
MW
10312 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
10313 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
10314 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
27c868c2 10315 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
629d688d
MW
10316 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
10317 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
10318 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
27c868c2 10319 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
629d688d
MW
10320 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
10321 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
10322 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 10323 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
629d688d
MW
10324 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
10325 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
10326 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
27c868c2 10327 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
629d688d
MW
10328 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
10329 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
10330 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 10331 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
629d688d
MW
10332 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
10333 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
10334 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
27c868c2 10335 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
629d688d
MW
10336 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
10337 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
10338 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
27c868c2 10339 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
629d688d
MW
10340 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
10341 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
10342 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
27c868c2 10343 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
629d688d
MW
10344 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
10345 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
10346 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
27c868c2 10347 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
629d688d
MW
10348 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
10349 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
10350 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
27c868c2 10351 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
629d688d
MW
10352 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
10353 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
10354 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
27c868c2 10355 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
629d688d
MW
10356 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
10357 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
10358 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
27c868c2 10359 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
629d688d
MW
10360 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
10361 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
10362 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
27c868c2 10363 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
629d688d
MW
10364 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
10365 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
10366 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
27c868c2 10367 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
629d688d
MW
10368 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
10369 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
10370 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
27c868c2 10371 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
629d688d
MW
10372 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
10373 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
10374 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
27c868c2 10375 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
629d688d
MW
10376 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
10377 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
10378 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
27c868c2 10379 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
629d688d
MW
10380 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
10381 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
10382 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
27c868c2 10383 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
629d688d
MW
10384 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
10385 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
10386 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
27c868c2 10387 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
629d688d
MW
10388 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
10389 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
10390 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
27c868c2 10391 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
629d688d
MW
10392 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
10393 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
10394 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
27c868c2 10395 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
629d688d
MW
10396 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
10397 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
10398 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
27c868c2 10399 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
629d688d
MW
10400 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
10401 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
10402 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
27c868c2 10403 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
629d688d
MW
10404 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
10405 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
10406 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
27c868c2 10407 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
629d688d
MW
10408 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
10409 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
10410 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
27c868c2 10411 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
629d688d
MW
10412 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
10413 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
10414 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
27c868c2 10415 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
629d688d
MW
10416 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
10417 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
10418 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
27c868c2 10419 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
629d688d
MW
10420 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
10421 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
10422 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
27c868c2 10423 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
629d688d
MW
10424 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
10425 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
10426 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
27c868c2 10427 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
629d688d
MW
10428 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
10429 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
10430 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
27c868c2 10431 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
629d688d
MW
10432 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
10433 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
10434 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
27c868c2 10435 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
629d688d
MW
10436 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
10437 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
10438 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
27c868c2 10439 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
629d688d
MW
10440 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
10441 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
10442 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
27c868c2 10443 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
629d688d
MW
10444 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
10445 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
10446 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
27c868c2 10447 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
629d688d
MW
10448 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
10449 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
10450 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
27c868c2 10451 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
629d688d
MW
10452 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
10453 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
10454 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
27c868c2 10455 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
629d688d
MW
10456 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
10457 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
10458 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
27c868c2 10459 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
629d688d
MW
10460 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
10461 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
10462 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
27c868c2 10463 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
629d688d
MW
10464 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
10465 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
10466 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
27c868c2 10467 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
629d688d
MW
10468 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
10469 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
10470 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
27c868c2 10471 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
629d688d
MW
10472 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
10473 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
10474 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
27c868c2 10475 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
629d688d
MW
10476 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
10477 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
10478 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
27c868c2 10479 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
629d688d
MW
10480 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
10481 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
10482 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
27c868c2 10483 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
629d688d
MW
10484 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
10485 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
10486 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
27c868c2 10487 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
629d688d
MW
10488 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
10489 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
10490 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
27c868c2 10491 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
629d688d
MW
10492 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
10493 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
10494 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
27c868c2 10495 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
629d688d
MW
10496 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
10497 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
10498 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
27c868c2 10499 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
629d688d
MW
10500 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
10501 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
10502 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
27c868c2 10503 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
629d688d
MW
10504 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
10505 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
10506 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
27c868c2 10507 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
629d688d
MW
10508 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
10509 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
10510 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
27c868c2 10511 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
629d688d
MW
10512 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
10513 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
10514 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
27c868c2 10515 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
629d688d
MW
10516 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
10517 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
10518 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
27c868c2 10519 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
629d688d
MW
10520 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
10521 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
10522 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
27c868c2 10523 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
629d688d
MW
10524 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
10525 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
10526 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
27c868c2 10527 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
629d688d
MW
10528 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
10529 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
10530 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
27c868c2 10531 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
629d688d
MW
10532 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
10533 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
10534 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
27c868c2 10535 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
629d688d
MW
10536 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
10537 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
10538 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
27c868c2 10539 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
629d688d
MW
10540 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
10541 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
10542 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
27c868c2 10543 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
629d688d
MW
10544 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
10545 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
10546 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
27c868c2 10547 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
629d688d
MW
10548 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
10549 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
10550 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
27c868c2 10551 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
629d688d
MW
10552 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
10553 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
10554 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
27c868c2 10555 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
629d688d
MW
10556 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
10557 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
10558 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
27c868c2 10559 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
629d688d
MW
10560 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
10561 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
10562 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
27c868c2 10563 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
629d688d
MW
10564 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
10565 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
10566 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
27c868c2 10567 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
629d688d
MW
10568 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
10569 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
10570 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
27c868c2 10571 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
629d688d
MW
10572 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
10573 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
10574 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
27c868c2 10575 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
629d688d
MW
10576 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
10577 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
10578 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
27c868c2 10579 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
629d688d
MW
10580 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
10581 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
10582 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
27c868c2 10583 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
629d688d
MW
10584 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
10585 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
10586 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
27c868c2 10587 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
629d688d
MW
10588 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
10589 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
10590 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
27c868c2 10591 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
629d688d
MW
10592 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
10593 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
10594 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
27c868c2 10595 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
629d688d
MW
10596 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
10597 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
10598 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
27c868c2 10599 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
629d688d
MW
10600 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
10601 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
10602 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
27c868c2 10603 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
629d688d
MW
10604 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
10605 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
10606 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
27c868c2 10607 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
629d688d
MW
10608 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
10609 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
10610 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
27c868c2 10611 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
629d688d
MW
10612 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
10613 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
10614 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
27c868c2 10615 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
629d688d
MW
10616 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
10617 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
10618 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
27c868c2 10619 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
629d688d
MW
10620 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
10621 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
10622 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
27c868c2 10623 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
629d688d
MW
10624 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
10625 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
10626 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
27c868c2 10627 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
629d688d
MW
10628 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
10629 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
10630 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
27c868c2 10631 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
629d688d
MW
10632 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
10633 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
10634 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
27c868c2 10635 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
629d688d
MW
10636 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
10637 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
10638 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
27c868c2 10639 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
629d688d
MW
10640 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
10641 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
10642 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
27c868c2 10643 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
629d688d
MW
10644 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
10645 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
10646 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
27c868c2 10647 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
629d688d
MW
10648 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
10649 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
10650 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
27c868c2 10651 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
629d688d
MW
10652 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
10653 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
10654 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
27c868c2 10655 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
629d688d
MW
10656 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
10657 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
10658 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
27c868c2 10659 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
629d688d
MW
10660 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
10661 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
10662 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
27c868c2 10663 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
629d688d
MW
10664 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
10665 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
10666 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
27c868c2 10667 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
629d688d
MW
10668 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
10669 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
10670 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
27c868c2 10671 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
629d688d
MW
10672 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
10673 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
10674 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 10675 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
10676 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
10677 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
10678 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 10679 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
10680 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
10681 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
10682 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
10683};
10684
27c868c2
MW
10685static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
10686static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4 10687
1da177e4
LT
10688/*
10689 * EEPROM Configuration.
10690 *
10691 * All drivers should use this structure to set the default EEPROM
10692 * configuration. The BIOS now uses this structure when it is built.
10693 * Additional structure information can be found in a_condor.h where
10694 * the structure is defined.
10695 *
10696 * The *_Field_IsChar structs are needed to correct for endianness.
10697 * These values are read from the board 16 bits at a time directly
10698 * into the structs. Because some fields are char, the values will be
10699 * in the wrong order. The *_Field_IsChar tells when to flip the
10700 * bytes. Data read and written to PCI memory is automatically swapped
10701 * on big-endian platforms so char fields read as words are actually being
10702 * unswapped on big-endian platforms.
10703 */
78e77d8b 10704static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
27c868c2
MW
10705 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
10706 0x0000, /* cfg_msw */
10707 0xFFFF, /* disc_enable */
10708 0xFFFF, /* wdtr_able */
10709 0xFFFF, /* sdtr_able */
10710 0xFFFF, /* start_motor */
10711 0xFFFF, /* tagqng_able */
10712 0xFFFF, /* bios_scan */
10713 0, /* scam_tolerant */
10714 7, /* adapter_scsi_id */
10715 0, /* bios_boot_delay */
10716 3, /* scsi_reset_delay */
10717 0, /* bios_id_lun */
10718 0, /* termination */
10719 0, /* reserved1 */
10720 0xFFE7, /* bios_ctrl */
10721 0xFFFF, /* ultra_able */
10722 0, /* reserved2 */
10723 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
10724 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
10725 0, /* dvc_cntl */
10726 0, /* bug_fix */
10727 0, /* serial_number_word1 */
10728 0, /* serial_number_word2 */
10729 0, /* serial_number_word3 */
10730 0, /* check_sum */
10731 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
10732 , /* oem_name[16] */
10733 0, /* dvc_err_code */
10734 0, /* adv_err_code */
10735 0, /* adv_err_addr */
10736 0, /* saved_dvc_err_code */
10737 0, /* saved_adv_err_code */
10738 0, /* saved_adv_err_addr */
10739 0 /* num_of_err */
1da177e4
LT
10740};
10741
78e77d8b 10742static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
27c868c2
MW
10743 0, /* cfg_lsw */
10744 0, /* cfg_msw */
10745 0, /* -disc_enable */
10746 0, /* wdtr_able */
10747 0, /* sdtr_able */
10748 0, /* start_motor */
10749 0, /* tagqng_able */
10750 0, /* bios_scan */
10751 0, /* scam_tolerant */
10752 1, /* adapter_scsi_id */
10753 1, /* bios_boot_delay */
10754 1, /* scsi_reset_delay */
10755 1, /* bios_id_lun */
10756 1, /* termination */
10757 1, /* reserved1 */
10758 0, /* bios_ctrl */
10759 0, /* ultra_able */
10760 0, /* reserved2 */
10761 1, /* max_host_qng */
10762 1, /* max_dvc_qng */
10763 0, /* dvc_cntl */
10764 0, /* bug_fix */
10765 0, /* serial_number_word1 */
10766 0, /* serial_number_word2 */
10767 0, /* serial_number_word3 */
10768 0, /* check_sum */
10769 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
10770 , /* oem_name[16] */
10771 0, /* dvc_err_code */
10772 0, /* adv_err_code */
10773 0, /* adv_err_addr */
10774 0, /* saved_dvc_err_code */
10775 0, /* saved_adv_err_code */
10776 0, /* saved_adv_err_addr */
10777 0 /* num_of_err */
1da177e4
LT
10778};
10779
78e77d8b 10780static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
27c868c2
MW
10781 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
10782 0x0000, /* 01 cfg_msw */
10783 0xFFFF, /* 02 disc_enable */
10784 0xFFFF, /* 03 wdtr_able */
10785 0x4444, /* 04 sdtr_speed1 */
10786 0xFFFF, /* 05 start_motor */
10787 0xFFFF, /* 06 tagqng_able */
10788 0xFFFF, /* 07 bios_scan */
10789 0, /* 08 scam_tolerant */
10790 7, /* 09 adapter_scsi_id */
10791 0, /* bios_boot_delay */
10792 3, /* 10 scsi_reset_delay */
10793 0, /* bios_id_lun */
10794 0, /* 11 termination_se */
10795 0, /* termination_lvd */
10796 0xFFE7, /* 12 bios_ctrl */
10797 0x4444, /* 13 sdtr_speed2 */
10798 0x4444, /* 14 sdtr_speed3 */
10799 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
10800 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
10801 0, /* 16 dvc_cntl */
10802 0x4444, /* 17 sdtr_speed4 */
10803 0, /* 18 serial_number_word1 */
10804 0, /* 19 serial_number_word2 */
10805 0, /* 20 serial_number_word3 */
10806 0, /* 21 check_sum */
10807 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
10808 , /* 22-29 oem_name[16] */
10809 0, /* 30 dvc_err_code */
10810 0, /* 31 adv_err_code */
10811 0, /* 32 adv_err_addr */
10812 0, /* 33 saved_dvc_err_code */
10813 0, /* 34 saved_adv_err_code */
10814 0, /* 35 saved_adv_err_addr */
10815 0, /* 36 reserved */
10816 0, /* 37 reserved */
10817 0, /* 38 reserved */
10818 0, /* 39 reserved */
10819 0, /* 40 reserved */
10820 0, /* 41 reserved */
10821 0, /* 42 reserved */
10822 0, /* 43 reserved */
10823 0, /* 44 reserved */
10824 0, /* 45 reserved */
10825 0, /* 46 reserved */
10826 0, /* 47 reserved */
10827 0, /* 48 reserved */
10828 0, /* 49 reserved */
10829 0, /* 50 reserved */
10830 0, /* 51 reserved */
10831 0, /* 52 reserved */
10832 0, /* 53 reserved */
10833 0, /* 54 reserved */
10834 0, /* 55 reserved */
10835 0, /* 56 cisptr_lsw */
10836 0, /* 57 cisprt_msw */
10837 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
10838 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
10839 0, /* 60 reserved */
10840 0, /* 61 reserved */
10841 0, /* 62 reserved */
10842 0 /* 63 reserved */
1da177e4
LT
10843};
10844
78e77d8b 10845static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
27c868c2
MW
10846 0, /* 00 cfg_lsw */
10847 0, /* 01 cfg_msw */
10848 0, /* 02 disc_enable */
10849 0, /* 03 wdtr_able */
10850 0, /* 04 sdtr_speed1 */
10851 0, /* 05 start_motor */
10852 0, /* 06 tagqng_able */
10853 0, /* 07 bios_scan */
10854 0, /* 08 scam_tolerant */
10855 1, /* 09 adapter_scsi_id */
10856 1, /* bios_boot_delay */
10857 1, /* 10 scsi_reset_delay */
10858 1, /* bios_id_lun */
10859 1, /* 11 termination_se */
10860 1, /* termination_lvd */
10861 0, /* 12 bios_ctrl */
10862 0, /* 13 sdtr_speed2 */
10863 0, /* 14 sdtr_speed3 */
10864 1, /* 15 max_host_qng */
10865 1, /* max_dvc_qng */
10866 0, /* 16 dvc_cntl */
10867 0, /* 17 sdtr_speed4 */
10868 0, /* 18 serial_number_word1 */
10869 0, /* 19 serial_number_word2 */
10870 0, /* 20 serial_number_word3 */
10871 0, /* 21 check_sum */
10872 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
10873 , /* 22-29 oem_name[16] */
10874 0, /* 30 dvc_err_code */
10875 0, /* 31 adv_err_code */
10876 0, /* 32 adv_err_addr */
10877 0, /* 33 saved_dvc_err_code */
10878 0, /* 34 saved_adv_err_code */
10879 0, /* 35 saved_adv_err_addr */
10880 0, /* 36 reserved */
10881 0, /* 37 reserved */
10882 0, /* 38 reserved */
10883 0, /* 39 reserved */
10884 0, /* 40 reserved */
10885 0, /* 41 reserved */
10886 0, /* 42 reserved */
10887 0, /* 43 reserved */
10888 0, /* 44 reserved */
10889 0, /* 45 reserved */
10890 0, /* 46 reserved */
10891 0, /* 47 reserved */
10892 0, /* 48 reserved */
10893 0, /* 49 reserved */
10894 0, /* 50 reserved */
10895 0, /* 51 reserved */
10896 0, /* 52 reserved */
10897 0, /* 53 reserved */
10898 0, /* 54 reserved */
10899 0, /* 55 reserved */
10900 0, /* 56 cisptr_lsw */
10901 0, /* 57 cisprt_msw */
10902 0, /* 58 subsysvid */
10903 0, /* 59 subsysid */
10904 0, /* 60 reserved */
10905 0, /* 61 reserved */
10906 0, /* 62 reserved */
10907 0 /* 63 reserved */
1da177e4
LT
10908};
10909
78e77d8b 10910static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
27c868c2
MW
10911 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
10912 0x0000, /* 01 cfg_msw */
10913 0xFFFF, /* 02 disc_enable */
10914 0xFFFF, /* 03 wdtr_able */
10915 0x5555, /* 04 sdtr_speed1 */
10916 0xFFFF, /* 05 start_motor */
10917 0xFFFF, /* 06 tagqng_able */
10918 0xFFFF, /* 07 bios_scan */
10919 0, /* 08 scam_tolerant */
10920 7, /* 09 adapter_scsi_id */
10921 0, /* bios_boot_delay */
10922 3, /* 10 scsi_reset_delay */
10923 0, /* bios_id_lun */
10924 0, /* 11 termination_se */
10925 0, /* termination_lvd */
10926 0xFFE7, /* 12 bios_ctrl */
10927 0x5555, /* 13 sdtr_speed2 */
10928 0x5555, /* 14 sdtr_speed3 */
10929 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
10930 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
10931 0, /* 16 dvc_cntl */
10932 0x5555, /* 17 sdtr_speed4 */
10933 0, /* 18 serial_number_word1 */
10934 0, /* 19 serial_number_word2 */
10935 0, /* 20 serial_number_word3 */
10936 0, /* 21 check_sum */
10937 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
10938 , /* 22-29 oem_name[16] */
10939 0, /* 30 dvc_err_code */
10940 0, /* 31 adv_err_code */
10941 0, /* 32 adv_err_addr */
10942 0, /* 33 saved_dvc_err_code */
10943 0, /* 34 saved_adv_err_code */
10944 0, /* 35 saved_adv_err_addr */
10945 0, /* 36 reserved */
10946 0, /* 37 reserved */
10947 0, /* 38 reserved */
10948 0, /* 39 reserved */
10949 0, /* 40 reserved */
10950 0, /* 41 reserved */
10951 0, /* 42 reserved */
10952 0, /* 43 reserved */
10953 0, /* 44 reserved */
10954 0, /* 45 reserved */
10955 0, /* 46 reserved */
10956 0, /* 47 reserved */
10957 0, /* 48 reserved */
10958 0, /* 49 reserved */
10959 0, /* 50 reserved */
10960 0, /* 51 reserved */
10961 0, /* 52 reserved */
10962 0, /* 53 reserved */
10963 0, /* 54 reserved */
10964 0, /* 55 reserved */
10965 0, /* 56 cisptr_lsw */
10966 0, /* 57 cisprt_msw */
10967 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
10968 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
10969 0, /* 60 reserved */
10970 0, /* 61 reserved */
10971 0, /* 62 reserved */
10972 0 /* 63 reserved */
1da177e4
LT
10973};
10974
78e77d8b 10975static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
27c868c2
MW
10976 0, /* 00 cfg_lsw */
10977 0, /* 01 cfg_msw */
10978 0, /* 02 disc_enable */
10979 0, /* 03 wdtr_able */
10980 0, /* 04 sdtr_speed1 */
10981 0, /* 05 start_motor */
10982 0, /* 06 tagqng_able */
10983 0, /* 07 bios_scan */
10984 0, /* 08 scam_tolerant */
10985 1, /* 09 adapter_scsi_id */
10986 1, /* bios_boot_delay */
10987 1, /* 10 scsi_reset_delay */
10988 1, /* bios_id_lun */
10989 1, /* 11 termination_se */
10990 1, /* termination_lvd */
10991 0, /* 12 bios_ctrl */
10992 0, /* 13 sdtr_speed2 */
10993 0, /* 14 sdtr_speed3 */
10994 1, /* 15 max_host_qng */
10995 1, /* max_dvc_qng */
10996 0, /* 16 dvc_cntl */
10997 0, /* 17 sdtr_speed4 */
10998 0, /* 18 serial_number_word1 */
10999 0, /* 19 serial_number_word2 */
11000 0, /* 20 serial_number_word3 */
11001 0, /* 21 check_sum */
11002 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11003 , /* 22-29 oem_name[16] */
11004 0, /* 30 dvc_err_code */
11005 0, /* 31 adv_err_code */
11006 0, /* 32 adv_err_addr */
11007 0, /* 33 saved_dvc_err_code */
11008 0, /* 34 saved_adv_err_code */
11009 0, /* 35 saved_adv_err_addr */
11010 0, /* 36 reserved */
11011 0, /* 37 reserved */
11012 0, /* 38 reserved */
11013 0, /* 39 reserved */
11014 0, /* 40 reserved */
11015 0, /* 41 reserved */
11016 0, /* 42 reserved */
11017 0, /* 43 reserved */
11018 0, /* 44 reserved */
11019 0, /* 45 reserved */
11020 0, /* 46 reserved */
11021 0, /* 47 reserved */
11022 0, /* 48 reserved */
11023 0, /* 49 reserved */
11024 0, /* 50 reserved */
11025 0, /* 51 reserved */
11026 0, /* 52 reserved */
11027 0, /* 53 reserved */
11028 0, /* 54 reserved */
11029 0, /* 55 reserved */
11030 0, /* 56 cisptr_lsw */
11031 0, /* 57 cisprt_msw */
11032 0, /* 58 subsysvid */
11033 0, /* 59 subsysid */
11034 0, /* 60 reserved */
11035 0, /* 61 reserved */
11036 0, /* 62 reserved */
11037 0 /* 63 reserved */
1da177e4
LT
11038};
11039
c2dce2fa 11040#ifdef CONFIG_PCI
1da177e4
LT
11041/*
11042 * Initialize the ADV_DVC_VAR structure.
11043 *
11044 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11045 *
11046 * For a non-fatal error return a warning code. If there are no warnings
11047 * then 0 is returned.
11048 */
394dbf3f 11049static int __devinit
c2dce2fa 11050AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 11051{
c2dce2fa 11052 ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
9649af39
MW
11053 unsigned short warn_code = 0;
11054 AdvPortAddr iop_base = asc_dvc->iop_base;
9649af39 11055 u16 cmd;
27c868c2
MW
11056 int status;
11057
27c868c2 11058 asc_dvc->err_code = 0;
1da177e4 11059
27c868c2
MW
11060 /*
11061 * Save the state of the PCI Configuration Command Register
11062 * "Parity Error Response Control" Bit. If the bit is clear (0),
11063 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
11064 * DMA parity errors.
11065 */
11066 asc_dvc->cfg->control_flag = 0;
9649af39
MW
11067 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
11068 if ((cmd & PCI_COMMAND_PARITY) == 0)
27c868c2 11069 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
1da177e4 11070
27c868c2
MW
11071 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
11072 ADV_LIB_VERSION_MINOR;
11073 asc_dvc->cfg->chip_version =
11074 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
11075
11076 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
11077 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
11078 (ushort)ADV_CHIP_ID_BYTE);
11079
11080 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
11081 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
11082 (ushort)ADV_CHIP_ID_WORD);
11083
11084 /*
11085 * Reset the chip to start and allow register writes.
11086 */
11087 if (AdvFindSignature(iop_base) == 0) {
11088 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11089 return ADV_ERROR;
11090 } else {
11091 /*
11092 * The caller must set 'chip_type' to a valid setting.
11093 */
11094 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
11095 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
11096 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
11097 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
11098 return ADV_ERROR;
11099 }
1da177e4 11100
27c868c2
MW
11101 /*
11102 * Reset Chip.
11103 */
11104 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11105 ADV_CTRL_REG_CMD_RESET);
b009bef6 11106 mdelay(100);
27c868c2
MW
11107 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11108 ADV_CTRL_REG_CMD_WR_IO_REG);
11109
11110 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
9649af39 11111 status = AdvInitFrom38C1600EEP(asc_dvc);
27c868c2 11112 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
9649af39 11113 status = AdvInitFrom38C0800EEP(asc_dvc);
27c868c2 11114 } else {
9649af39 11115 status = AdvInitFrom3550EEP(asc_dvc);
27c868c2
MW
11116 }
11117 warn_code |= status;
11118 }
1da177e4 11119
c2dce2fa
MW
11120 if (warn_code != 0) {
11121 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
11122 boardp->id, warn_code);
11123 }
11124
11125 if (asc_dvc->err_code) {
11126 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
11127 boardp->id, asc_dvc->err_code);
11128 }
11129
11130 return asc_dvc->err_code;
1da177e4 11131}
c2dce2fa 11132#endif
1da177e4 11133
a9f4a59a
MW
11134static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
11135{
11136 ADV_CARR_T *carrp;
11137 ADV_SDCNT buf_size;
11138 ADV_PADDR carr_paddr;
11139
11140 BUG_ON(!asc_dvc->carrier_buf);
11141
11142 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
11143 asc_dvc->carr_freelist = NULL;
11144 if (carrp == asc_dvc->carrier_buf) {
11145 buf_size = ADV_CARRIER_BUFSIZE;
11146 } else {
11147 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
11148 }
11149
11150 do {
11151 /* Get physical address of the carrier 'carrp'. */
11152 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
11153 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
11154 (uchar *)carrp,
11155 (ADV_SDCNT *)&contig_len,
11156 ADV_IS_CARRIER_FLAG));
11157
11158 buf_size -= sizeof(ADV_CARR_T);
11159
11160 /*
11161 * If the current carrier is not physically contiguous, then
11162 * maybe there was a page crossing. Try the next carrier
11163 * aligned start address.
11164 */
11165 if (contig_len < sizeof(ADV_CARR_T)) {
11166 carrp++;
11167 continue;
11168 }
11169
11170 carrp->carr_pa = carr_paddr;
11171 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
11172
11173 /*
11174 * Insert the carrier at the beginning of the freelist.
11175 */
11176 carrp->next_vpa =
11177 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
11178 asc_dvc->carr_freelist = carrp;
11179
11180 carrp++;
11181 } while (buf_size > 0);
11182}
11183
b9d96614
MW
11184/*
11185 * Load the Microcode
11186 *
11187 * Write the microcode image to RISC memory starting at address 0.
11188 *
11189 * The microcode is stored compressed in the following format:
11190 *
11191 * 254 word (508 byte) table indexed by byte code followed
11192 * by the following byte codes:
11193 *
11194 * 1-Byte Code:
11195 * 00: Emit word 0 in table.
11196 * 01: Emit word 1 in table.
11197 * .
11198 * FD: Emit word 253 in table.
11199 *
11200 * Multi-Byte Code:
11201 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
11202 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
11203 *
11204 * Returns 0 or an error if the checksum doesn't match
11205 */
11206static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
11207 int memsize, int chksum)
11208{
11209 int i, j, end, len = 0;
11210 ADV_DCNT sum;
11211
11212 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
11213
11214 for (i = 253 * 2; i < size; i++) {
11215 if (buf[i] == 0xff) {
11216 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
11217 for (j = 0; j < buf[i + 1]; j++) {
11218 AdvWriteWordAutoIncLram(iop_base, word);
11219 len += 2;
11220 }
11221 i += 3;
11222 } else if (buf[i] == 0xfe) {
11223 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
11224 AdvWriteWordAutoIncLram(iop_base, word);
11225 i += 2;
11226 len += 2;
11227 } else {
11228 unsigned char off = buf[i] * 2;
11229 unsigned short word = (buf[off + 1] << 8) | buf[off];
11230 AdvWriteWordAutoIncLram(iop_base, word);
11231 len += 2;
11232 }
11233 }
11234
11235 end = len;
11236
11237 while (len < memsize) {
11238 AdvWriteWordAutoIncLram(iop_base, 0);
11239 len += 2;
11240 }
11241
11242 /* Verify the microcode checksum. */
11243 sum = 0;
11244 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
11245
11246 for (len = 0; len < end; len += 2) {
11247 sum += AdvReadWordAutoIncLram(iop_base);
11248 }
11249
11250 if (sum != chksum)
11251 return ASC_IERR_MCODE_CHKSUM;
11252
11253 return 0;
11254}
11255
1da177e4
LT
11256/*
11257 * Initialize the ASC-3550.
11258 *
11259 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11260 *
11261 * For a non-fatal error return a warning code. If there are no warnings
11262 * then 0 is returned.
11263 *
11264 * Needed after initialization for error recovery.
11265 */
27c868c2 11266static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 11267{
27c868c2
MW
11268 AdvPortAddr iop_base;
11269 ushort warn_code;
27c868c2
MW
11270 int begin_addr;
11271 int end_addr;
11272 ushort code_sum;
11273 int word;
27c868c2
MW
11274 int i;
11275 ushort scsi_cfg1;
11276 uchar tid;
11277 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
11278 ushort wdtr_able = 0, sdtr_able, tagqng_able;
11279 uchar max_cmd[ADV_MAX_TID + 1];
11280
11281 /* If there is already an error, don't continue. */
b9d96614 11282 if (asc_dvc->err_code != 0)
27c868c2 11283 return ADV_ERROR;
1da177e4 11284
27c868c2
MW
11285 /*
11286 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
11287 */
11288 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
b9d96614 11289 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
27c868c2
MW
11290 return ADV_ERROR;
11291 }
1da177e4 11292
27c868c2
MW
11293 warn_code = 0;
11294 iop_base = asc_dvc->iop_base;
11295
11296 /*
11297 * Save the RISC memory BIOS region before writing the microcode.
11298 * The BIOS may already be loaded and using its RISC LRAM region
11299 * so its region must be saved and restored.
11300 *
11301 * Note: This code makes the assumption, which is currently true,
11302 * that a chip reset does not clear RISC LRAM.
11303 */
11304 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11305 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11306 bios_mem[i]);
11307 }
1da177e4 11308
27c868c2
MW
11309 /*
11310 * Save current per TID negotiated values.
11311 */
11312 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
11313 ushort bios_version, major, minor;
11314
11315 bios_version =
11316 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
11317 major = (bios_version >> 12) & 0xF;
11318 minor = (bios_version >> 8) & 0xF;
11319 if (major < 3 || (major == 3 && minor == 1)) {
11320 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
11321 AdvReadWordLram(iop_base, 0x120, wdtr_able);
11322 } else {
11323 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11324 }
11325 }
11326 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11327 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
11328 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11329 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
11330 max_cmd[tid]);
11331 }
1da177e4 11332
b9d96614
MW
11333 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
11334 _adv_asc3550_size, ADV_3550_MEMSIZE,
11335 _adv_asc3550_chksum);
11336 if (asc_dvc->err_code)
27c868c2 11337 return ADV_ERROR;
1da177e4 11338
27c868c2
MW
11339 /*
11340 * Restore the RISC memory BIOS region.
11341 */
11342 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11343 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11344 bios_mem[i]);
11345 }
1da177e4 11346
27c868c2
MW
11347 /*
11348 * Calculate and write the microcode code checksum to the microcode
11349 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
11350 */
11351 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
11352 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
11353 code_sum = 0;
11354 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
11355 for (word = begin_addr; word < end_addr; word += 2) {
11356 code_sum += AdvReadWordAutoIncLram(iop_base);
11357 }
11358 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
11359
11360 /*
11361 * Read and save microcode version and date.
11362 */
11363 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
11364 asc_dvc->cfg->mcode_date);
11365 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
11366 asc_dvc->cfg->mcode_version);
11367
11368 /*
11369 * Set the chip type to indicate the ASC3550.
11370 */
11371 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
11372
11373 /*
11374 * If the PCI Configuration Command Register "Parity Error Response
11375 * Control" Bit was clear (0), then set the microcode variable
11376 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
11377 * to ignore DMA parity errors.
11378 */
11379 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
11380 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11381 word |= CONTROL_FLAG_IGNORE_PERR;
11382 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11383 }
1da177e4 11384
27c868c2
MW
11385 /*
11386 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
11387 * threshold of 128 bytes. This register is only accessible to the host.
11388 */
11389 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
11390 START_CTL_EMFU | READ_CMD_MRM);
11391
11392 /*
11393 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 11394 * queuing will be set in slave_configure() based on what a
27c868c2
MW
11395 * device reports it is capable of in Inquiry byte 7.
11396 *
11397 * If SCSI Bus Resets have been disabled, then directly set
11398 * SDTR and WDTR from the EEPROM configuration. This will allow
11399 * the BIOS and warm boot to work without a SCSI bus hang on
11400 * the Inquiry caused by host and target mismatched DTR values.
11401 * Without the SCSI Bus Reset, before an Inquiry a device can't
11402 * be assumed to be in Asynchronous, Narrow mode.
11403 */
11404 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
11405 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
11406 asc_dvc->wdtr_able);
11407 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
11408 asc_dvc->sdtr_able);
11409 }
1da177e4 11410
27c868c2
MW
11411 /*
11412 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
11413 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
11414 * bitmask. These values determine the maximum SDTR speed negotiated
11415 * with a device.
11416 *
11417 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
11418 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
11419 * without determining here whether the device supports SDTR.
11420 *
11421 * 4-bit speed SDTR speed name
11422 * =========== ===============
11423 * 0000b (0x0) SDTR disabled
11424 * 0001b (0x1) 5 Mhz
11425 * 0010b (0x2) 10 Mhz
11426 * 0011b (0x3) 20 Mhz (Ultra)
11427 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
11428 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
11429 * 0110b (0x6) Undefined
11430 * .
11431 * 1111b (0xF) Undefined
11432 */
11433 word = 0;
11434 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11435 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
11436 /* Set Ultra speed for TID 'tid'. */
11437 word |= (0x3 << (4 * (tid % 4)));
11438 } else {
11439 /* Set Fast speed for TID 'tid'. */
11440 word |= (0x2 << (4 * (tid % 4)));
11441 }
11442 if (tid == 3) { /* Check if done with sdtr_speed1. */
11443 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
11444 word = 0;
11445 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
11446 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
11447 word = 0;
11448 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
11449 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
11450 word = 0;
11451 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
11452 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
11453 /* End of loop. */
11454 }
11455 }
1da177e4 11456
27c868c2
MW
11457 /*
11458 * Set microcode operating variable for the disconnect per TID bitmask.
11459 */
11460 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
11461 asc_dvc->cfg->disc_enable);
11462
11463 /*
11464 * Set SCSI_CFG0 Microcode Default Value.
11465 *
11466 * The microcode will set the SCSI_CFG0 register using this value
11467 * after it is started below.
11468 */
11469 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
11470 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
11471 asc_dvc->chip_scsi_id);
11472
11473 /*
11474 * Determine SCSI_CFG1 Microcode Default Value.
11475 *
11476 * The microcode will set the SCSI_CFG1 register using this value
11477 * after it is started below.
11478 */
11479
11480 /* Read current SCSI_CFG1 Register value. */
11481 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
11482
11483 /*
11484 * If all three connectors are in use, return an error.
11485 */
11486 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
11487 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
11488 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
11489 return ADV_ERROR;
11490 }
1da177e4 11491
27c868c2
MW
11492 /*
11493 * If the internal narrow cable is reversed all of the SCSI_CTRL
11494 * register signals will be set. Check for and return an error if
11495 * this condition is found.
11496 */
11497 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
11498 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
11499 return ADV_ERROR;
11500 }
1da177e4 11501
27c868c2
MW
11502 /*
11503 * If this is a differential board and a single-ended device
11504 * is attached to one of the connectors, return an error.
11505 */
11506 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
11507 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
11508 return ADV_ERROR;
11509 }
1da177e4 11510
27c868c2
MW
11511 /*
11512 * If automatic termination control is enabled, then set the
11513 * termination value based on a table listed in a_condor.h.
11514 *
11515 * If manual termination was specified with an EEPROM setting
11516 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
11517 * is ready to be 'ored' into SCSI_CFG1.
11518 */
11519 if (asc_dvc->cfg->termination == 0) {
11520 /*
11521 * The software always controls termination by setting TERM_CTL_SEL.
11522 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
11523 */
11524 asc_dvc->cfg->termination |= TERM_CTL_SEL;
11525
11526 switch (scsi_cfg1 & CABLE_DETECT) {
11527 /* TERM_CTL_H: on, TERM_CTL_L: on */
11528 case 0x3:
11529 case 0x7:
11530 case 0xB:
11531 case 0xD:
11532 case 0xE:
11533 case 0xF:
11534 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
11535 break;
11536
11537 /* TERM_CTL_H: on, TERM_CTL_L: off */
11538 case 0x1:
11539 case 0x5:
11540 case 0x9:
11541 case 0xA:
11542 case 0xC:
11543 asc_dvc->cfg->termination |= TERM_CTL_H;
11544 break;
11545
11546 /* TERM_CTL_H: off, TERM_CTL_L: off */
11547 case 0x2:
11548 case 0x6:
11549 break;
11550 }
11551 }
1da177e4 11552
27c868c2
MW
11553 /*
11554 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
11555 */
11556 scsi_cfg1 &= ~TERM_CTL;
11557
11558 /*
11559 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
11560 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
11561 * referenced, because the hardware internally inverts
11562 * the Termination High and Low bits if TERM_POL is set.
11563 */
11564 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
11565
11566 /*
11567 * Set SCSI_CFG1 Microcode Default Value
11568 *
11569 * Set filter value and possibly modified termination control
11570 * bits in the Microcode SCSI_CFG1 Register Value.
11571 *
11572 * The microcode will set the SCSI_CFG1 register using this value
11573 * after it is started below.
11574 */
11575 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
11576 FLTR_DISABLE | scsi_cfg1);
11577
11578 /*
11579 * Set MEM_CFG Microcode Default Value
11580 *
11581 * The microcode will set the MEM_CFG register using this value
11582 * after it is started below.
11583 *
11584 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
11585 * are defined.
11586 *
11587 * ASC-3550 has 8KB internal memory.
11588 */
11589 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
11590 BIOS_EN | RAM_SZ_8KB);
11591
11592 /*
11593 * Set SEL_MASK Microcode Default Value
11594 *
11595 * The microcode will set the SEL_MASK register using this value
11596 * after it is started below.
11597 */
11598 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
11599 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
11600
a9f4a59a 11601 AdvBuildCarrierFreelist(asc_dvc);
1da177e4 11602
27c868c2
MW
11603 /*
11604 * Set-up the Host->RISC Initiator Command Queue (ICQ).
11605 */
1da177e4 11606
27c868c2
MW
11607 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
11608 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
11609 return ADV_ERROR;
11610 }
11611 asc_dvc->carr_freelist = (ADV_CARR_T *)
11612 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
11613
11614 /*
11615 * The first command issued will be placed in the stopper carrier.
11616 */
11617 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11618
11619 /*
11620 * Set RISC ICQ physical address start value.
11621 */
11622 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
11623
11624 /*
11625 * Set-up the RISC->Host Initiator Response Queue (IRQ).
11626 */
11627 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
11628 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
11629 return ADV_ERROR;
11630 }
11631 asc_dvc->carr_freelist = (ADV_CARR_T *)
11632 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
11633
11634 /*
11635 * The first command completed by the RISC will be placed in
11636 * the stopper.
11637 *
11638 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
11639 * completed the RISC will set the ASC_RQ_STOPPER bit.
11640 */
11641 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11642
11643 /*
11644 * Set RISC IRQ physical address start value.
11645 */
11646 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
11647 asc_dvc->carr_pending_cnt = 0;
11648
11649 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
11650 (ADV_INTR_ENABLE_HOST_INTR |
11651 ADV_INTR_ENABLE_GLOBAL_INTR));
11652
11653 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
11654 AdvWriteWordRegister(iop_base, IOPW_PC, word);
11655
11656 /* finally, finally, gentlemen, start your engine */
11657 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
11658
11659 /*
11660 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
11661 * Resets should be performed. The RISC has to be running
11662 * to issue a SCSI Bus Reset.
11663 */
11664 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
11665 /*
11666 * If the BIOS Signature is present in memory, restore the
11667 * BIOS Handshake Configuration Table and do not perform
11668 * a SCSI Bus Reset.
11669 */
11670 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
11671 0x55AA) {
11672 /*
11673 * Restore per TID negotiated values.
11674 */
11675 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11676 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11677 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
11678 tagqng_able);
11679 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11680 AdvWriteByteLram(iop_base,
11681 ASC_MC_NUMBER_OF_MAX_CMD + tid,
11682 max_cmd[tid]);
11683 }
11684 } else {
11685 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
11686 warn_code = ASC_WARN_BUSRESET_ERROR;
11687 }
11688 }
11689 }
1da177e4 11690
27c868c2
MW
11691 return warn_code;
11692}
1da177e4 11693
27c868c2
MW
11694/*
11695 * Initialize the ASC-38C0800.
11696 *
11697 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11698 *
11699 * For a non-fatal error return a warning code. If there are no warnings
11700 * then 0 is returned.
11701 *
11702 * Needed after initialization for error recovery.
11703 */
11704static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
11705{
11706 AdvPortAddr iop_base;
11707 ushort warn_code;
27c868c2
MW
11708 int begin_addr;
11709 int end_addr;
11710 ushort code_sum;
11711 int word;
27c868c2
MW
11712 int i;
11713 ushort scsi_cfg1;
11714 uchar byte;
11715 uchar tid;
11716 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
11717 ushort wdtr_able, sdtr_able, tagqng_able;
11718 uchar max_cmd[ADV_MAX_TID + 1];
11719
11720 /* If there is already an error, don't continue. */
b9d96614 11721 if (asc_dvc->err_code != 0)
27c868c2 11722 return ADV_ERROR;
1da177e4 11723
27c868c2
MW
11724 /*
11725 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
11726 */
11727 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
11728 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
11729 return ADV_ERROR;
11730 }
1da177e4 11731
27c868c2
MW
11732 warn_code = 0;
11733 iop_base = asc_dvc->iop_base;
11734
11735 /*
11736 * Save the RISC memory BIOS region before writing the microcode.
11737 * The BIOS may already be loaded and using its RISC LRAM region
11738 * so its region must be saved and restored.
11739 *
11740 * Note: This code makes the assumption, which is currently true,
11741 * that a chip reset does not clear RISC LRAM.
11742 */
11743 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11744 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11745 bios_mem[i]);
11746 }
1da177e4 11747
27c868c2
MW
11748 /*
11749 * Save current per TID negotiated values.
11750 */
11751 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
11752 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
11753 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
11754 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
11755 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
11756 max_cmd[tid]);
11757 }
1da177e4 11758
27c868c2
MW
11759 /*
11760 * RAM BIST (RAM Built-In Self Test)
11761 *
11762 * Address : I/O base + offset 0x38h register (byte).
11763 * Function: Bit 7-6(RW) : RAM mode
11764 * Normal Mode : 0x00
11765 * Pre-test Mode : 0x40
11766 * RAM Test Mode : 0x80
11767 * Bit 5 : unused
11768 * Bit 4(RO) : Done bit
11769 * Bit 3-0(RO) : Status
11770 * Host Error : 0x08
11771 * Int_RAM Error : 0x04
11772 * RISC Error : 0x02
11773 * SCSI Error : 0x01
11774 * No Error : 0x00
11775 *
11776 * Note: RAM BIST code should be put right here, before loading the
11777 * microcode and after saving the RISC memory BIOS region.
11778 */
11779
11780 /*
11781 * LRAM Pre-test
11782 *
11783 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
11784 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
11785 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
11786 * to NORMAL_MODE, return an error too.
11787 */
11788 for (i = 0; i < 2; i++) {
11789 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
b009bef6 11790 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
11791 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
11792 if ((byte & RAM_TEST_DONE) == 0
11793 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 11794 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
11795 return ADV_ERROR;
11796 }
11797
11798 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
b009bef6 11799 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
11800 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
11801 != NORMAL_VALUE) {
b9d96614 11802 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
11803 return ADV_ERROR;
11804 }
11805 }
1da177e4 11806
27c868c2
MW
11807 /*
11808 * LRAM Test - It takes about 1.5 ms to run through the test.
11809 *
11810 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
11811 * If Done bit not set or Status not 0, save register byte, set the
11812 * err_code, and return an error.
11813 */
11814 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
b009bef6 11815 mdelay(10); /* Wait for 10ms before checking status. */
27c868c2
MW
11816
11817 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
11818 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
11819 /* Get here if Done bit not set or Status not 0. */
11820 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 11821 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
11822 return ADV_ERROR;
11823 }
1da177e4 11824
27c868c2
MW
11825 /* We need to reset back to normal mode after LRAM test passes. */
11826 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
11827
b9d96614
MW
11828 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
11829 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
11830 _adv_asc38C0800_chksum);
11831 if (asc_dvc->err_code)
27c868c2 11832 return ADV_ERROR;
1da177e4 11833
27c868c2
MW
11834 /*
11835 * Restore the RISC memory BIOS region.
11836 */
11837 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
11838 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
11839 bios_mem[i]);
11840 }
1da177e4 11841
27c868c2
MW
11842 /*
11843 * Calculate and write the microcode code checksum to the microcode
11844 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
11845 */
11846 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
11847 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
11848 code_sum = 0;
11849 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
11850 for (word = begin_addr; word < end_addr; word += 2) {
11851 code_sum += AdvReadWordAutoIncLram(iop_base);
11852 }
11853 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
11854
11855 /*
11856 * Read microcode version and date.
11857 */
11858 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
11859 asc_dvc->cfg->mcode_date);
11860 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
11861 asc_dvc->cfg->mcode_version);
11862
11863 /*
11864 * Set the chip type to indicate the ASC38C0800.
11865 */
11866 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
11867
11868 /*
11869 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
11870 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
11871 * cable detection and then we are able to read C_DET[3:0].
11872 *
11873 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
11874 * Microcode Default Value' section below.
11875 */
11876 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
11877 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
11878 scsi_cfg1 | DIS_TERM_DRV);
11879
11880 /*
11881 * If the PCI Configuration Command Register "Parity Error Response
11882 * Control" Bit was clear (0), then set the microcode variable
11883 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
11884 * to ignore DMA parity errors.
11885 */
11886 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
11887 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11888 word |= CONTROL_FLAG_IGNORE_PERR;
11889 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
11890 }
1da177e4 11891
27c868c2
MW
11892 /*
11893 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
11894 * bits for the default FIFO threshold.
11895 *
11896 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
11897 *
11898 * For DMA Errata #4 set the BC_THRESH_ENB bit.
11899 */
11900 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
11901 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
11902 READ_CMD_MRM);
11903
11904 /*
11905 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 11906 * queuing will be set in slave_configure() based on what a
27c868c2
MW
11907 * device reports it is capable of in Inquiry byte 7.
11908 *
11909 * If SCSI Bus Resets have been disabled, then directly set
11910 * SDTR and WDTR from the EEPROM configuration. This will allow
11911 * the BIOS and warm boot to work without a SCSI bus hang on
11912 * the Inquiry caused by host and target mismatched DTR values.
11913 * Without the SCSI Bus Reset, before an Inquiry a device can't
11914 * be assumed to be in Asynchronous, Narrow mode.
11915 */
11916 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
11917 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
11918 asc_dvc->wdtr_able);
11919 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
11920 asc_dvc->sdtr_able);
11921 }
1da177e4 11922
27c868c2
MW
11923 /*
11924 * Set microcode operating variables for DISC and SDTR_SPEED1,
11925 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
11926 * configuration values.
11927 *
11928 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
11929 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
11930 * without determining here whether the device supports SDTR.
11931 */
11932 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
11933 asc_dvc->cfg->disc_enable);
11934 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
11935 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
11936 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
11937 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
11938
11939 /*
11940 * Set SCSI_CFG0 Microcode Default Value.
11941 *
11942 * The microcode will set the SCSI_CFG0 register using this value
11943 * after it is started below.
11944 */
11945 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
11946 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
11947 asc_dvc->chip_scsi_id);
11948
11949 /*
11950 * Determine SCSI_CFG1 Microcode Default Value.
11951 *
11952 * The microcode will set the SCSI_CFG1 register using this value
11953 * after it is started below.
11954 */
11955
11956 /* Read current SCSI_CFG1 Register value. */
11957 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
11958
11959 /*
11960 * If the internal narrow cable is reversed all of the SCSI_CTRL
11961 * register signals will be set. Check for and return an error if
11962 * this condition is found.
11963 */
11964 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
11965 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
11966 return ADV_ERROR;
11967 }
1da177e4 11968
27c868c2 11969 /*
b9d96614
MW
11970 * All kind of combinations of devices attached to one of four
11971 * connectors are acceptable except HVD device attached. For example,
11972 * LVD device can be attached to SE connector while SE device attached
11973 * to LVD connector. If LVD device attached to SE connector, it only
11974 * runs up to Ultra speed.
27c868c2 11975 *
b9d96614
MW
11976 * If an HVD device is attached to one of LVD connectors, return an
11977 * error. However, there is no way to detect HVD device attached to
11978 * SE connectors.
27c868c2
MW
11979 */
11980 if (scsi_cfg1 & HVD) {
b9d96614 11981 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
27c868c2
MW
11982 return ADV_ERROR;
11983 }
1da177e4 11984
27c868c2
MW
11985 /*
11986 * If either SE or LVD automatic termination control is enabled, then
11987 * set the termination value based on a table listed in a_condor.h.
11988 *
11989 * If manual termination was specified with an EEPROM setting then
b9d96614
MW
11990 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
11991 * to be 'ored' into SCSI_CFG1.
27c868c2
MW
11992 */
11993 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
11994 /* SE automatic termination control is enabled. */
11995 switch (scsi_cfg1 & C_DET_SE) {
11996 /* TERM_SE_HI: on, TERM_SE_LO: on */
11997 case 0x1:
11998 case 0x2:
11999 case 0x3:
12000 asc_dvc->cfg->termination |= TERM_SE;
12001 break;
12002
12003 /* TERM_SE_HI: on, TERM_SE_LO: off */
12004 case 0x0:
12005 asc_dvc->cfg->termination |= TERM_SE_HI;
12006 break;
12007 }
12008 }
12009
12010 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
12011 /* LVD automatic termination control is enabled. */
12012 switch (scsi_cfg1 & C_DET_LVD) {
12013 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
12014 case 0x4:
12015 case 0x8:
12016 case 0xC:
12017 asc_dvc->cfg->termination |= TERM_LVD;
12018 break;
12019
12020 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
12021 case 0x0:
12022 break;
12023 }
12024 }
12025
12026 /*
12027 * Clear any set TERM_SE and TERM_LVD bits.
12028 */
12029 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
12030
12031 /*
12032 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
12033 */
12034 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
12035
12036 /*
b9d96614
MW
12037 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
12038 * bits and set possibly modified termination control bits in the
12039 * Microcode SCSI_CFG1 Register Value.
27c868c2
MW
12040 */
12041 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
12042
12043 /*
12044 * Set SCSI_CFG1 Microcode Default Value
12045 *
12046 * Set possibly modified termination control and reset DIS_TERM_DRV
12047 * bits in the Microcode SCSI_CFG1 Register Value.
12048 *
12049 * The microcode will set the SCSI_CFG1 register using this value
12050 * after it is started below.
12051 */
12052 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
12053
12054 /*
12055 * Set MEM_CFG Microcode Default Value
12056 *
12057 * The microcode will set the MEM_CFG register using this value
12058 * after it is started below.
12059 *
12060 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12061 * are defined.
12062 *
12063 * ASC-38C0800 has 16KB internal memory.
12064 */
12065 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12066 BIOS_EN | RAM_SZ_16KB);
12067
12068 /*
12069 * Set SEL_MASK Microcode Default Value
12070 *
12071 * The microcode will set the SEL_MASK register using this value
12072 * after it is started below.
12073 */
12074 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12075 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12076
a9f4a59a 12077 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
12078
12079 /*
12080 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12081 */
12082
12083 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12084 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12085 return ADV_ERROR;
12086 }
12087 asc_dvc->carr_freelist = (ADV_CARR_T *)
12088 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12089
12090 /*
12091 * The first command issued will be placed in the stopper carrier.
12092 */
12093 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12094
12095 /*
12096 * Set RISC ICQ physical address start value.
12097 * carr_pa is LE, must be native before write
12098 */
12099 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12100
12101 /*
12102 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12103 */
12104 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12105 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12106 return ADV_ERROR;
12107 }
12108 asc_dvc->carr_freelist = (ADV_CARR_T *)
12109 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12110
12111 /*
12112 * The first command completed by the RISC will be placed in
12113 * the stopper.
12114 *
12115 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12116 * completed the RISC will set the ASC_RQ_STOPPER bit.
12117 */
12118 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12119
12120 /*
12121 * Set RISC IRQ physical address start value.
12122 *
12123 * carr_pa is LE, must be native before write *
12124 */
12125 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12126 asc_dvc->carr_pending_cnt = 0;
12127
12128 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12129 (ADV_INTR_ENABLE_HOST_INTR |
12130 ADV_INTR_ENABLE_GLOBAL_INTR));
12131
12132 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12133 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12134
12135 /* finally, finally, gentlemen, start your engine */
12136 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12137
12138 /*
12139 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12140 * Resets should be performed. The RISC has to be running
12141 * to issue a SCSI Bus Reset.
12142 */
12143 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
12144 /*
12145 * If the BIOS Signature is present in memory, restore the
12146 * BIOS Handshake Configuration Table and do not perform
12147 * a SCSI Bus Reset.
12148 */
12149 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
12150 0x55AA) {
12151 /*
12152 * Restore per TID negotiated values.
12153 */
12154 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12155 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12156 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
12157 tagqng_able);
12158 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12159 AdvWriteByteLram(iop_base,
12160 ASC_MC_NUMBER_OF_MAX_CMD + tid,
12161 max_cmd[tid]);
12162 }
12163 } else {
12164 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
12165 warn_code = ASC_WARN_BUSRESET_ERROR;
12166 }
12167 }
12168 }
12169
12170 return warn_code;
1da177e4
LT
12171}
12172
12173/*
27c868c2 12174 * Initialize the ASC-38C1600.
1da177e4 12175 *
27c868c2 12176 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
12177 *
12178 * For a non-fatal error return a warning code. If there are no warnings
12179 * then 0 is returned.
12180 *
12181 * Needed after initialization for error recovery.
12182 */
27c868c2 12183static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 12184{
27c868c2
MW
12185 AdvPortAddr iop_base;
12186 ushort warn_code;
27c868c2
MW
12187 int begin_addr;
12188 int end_addr;
12189 ushort code_sum;
12190 long word;
27c868c2
MW
12191 int i;
12192 ushort scsi_cfg1;
12193 uchar byte;
12194 uchar tid;
12195 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
12196 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
12197 uchar max_cmd[ASC_MAX_TID + 1];
12198
12199 /* If there is already an error, don't continue. */
12200 if (asc_dvc->err_code != 0) {
12201 return ADV_ERROR;
12202 }
1da177e4 12203
27c868c2
MW
12204 /*
12205 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
12206 */
12207 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
12208 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
12209 return ADV_ERROR;
12210 }
1da177e4 12211
27c868c2
MW
12212 warn_code = 0;
12213 iop_base = asc_dvc->iop_base;
12214
12215 /*
12216 * Save the RISC memory BIOS region before writing the microcode.
12217 * The BIOS may already be loaded and using its RISC LRAM region
12218 * so its region must be saved and restored.
12219 *
12220 * Note: This code makes the assumption, which is currently true,
12221 * that a chip reset does not clear RISC LRAM.
12222 */
12223 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12224 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12225 bios_mem[i]);
12226 }
1da177e4 12227
27c868c2
MW
12228 /*
12229 * Save current per TID negotiated values.
12230 */
12231 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12232 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12233 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
12234 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
12235 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
12236 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
12237 max_cmd[tid]);
12238 }
1da177e4 12239
27c868c2
MW
12240 /*
12241 * RAM BIST (Built-In Self Test)
12242 *
12243 * Address : I/O base + offset 0x38h register (byte).
12244 * Function: Bit 7-6(RW) : RAM mode
12245 * Normal Mode : 0x00
12246 * Pre-test Mode : 0x40
12247 * RAM Test Mode : 0x80
12248 * Bit 5 : unused
12249 * Bit 4(RO) : Done bit
12250 * Bit 3-0(RO) : Status
12251 * Host Error : 0x08
12252 * Int_RAM Error : 0x04
12253 * RISC Error : 0x02
12254 * SCSI Error : 0x01
12255 * No Error : 0x00
12256 *
12257 * Note: RAM BIST code should be put right here, before loading the
12258 * microcode and after saving the RISC memory BIOS region.
12259 */
12260
12261 /*
12262 * LRAM Pre-test
12263 *
12264 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
12265 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
12266 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
12267 * to NORMAL_MODE, return an error too.
12268 */
12269 for (i = 0; i < 2; i++) {
12270 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
b009bef6 12271 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
12272 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12273 if ((byte & RAM_TEST_DONE) == 0
12274 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 12275 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12276 return ADV_ERROR;
12277 }
12278
12279 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
b009bef6 12280 mdelay(10); /* Wait for 10ms before reading back. */
27c868c2
MW
12281 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
12282 != NORMAL_VALUE) {
b9d96614 12283 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12284 return ADV_ERROR;
12285 }
12286 }
1da177e4 12287
27c868c2
MW
12288 /*
12289 * LRAM Test - It takes about 1.5 ms to run through the test.
12290 *
12291 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
12292 * If Done bit not set or Status not 0, save register byte, set the
12293 * err_code, and return an error.
12294 */
12295 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
b009bef6 12296 mdelay(10); /* Wait for 10ms before checking status. */
27c868c2
MW
12297
12298 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12299 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
12300 /* Get here if Done bit not set or Status not 0. */
12301 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 12302 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
12303 return ADV_ERROR;
12304 }
1da177e4 12305
27c868c2
MW
12306 /* We need to reset back to normal mode after LRAM test passes. */
12307 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12308
b9d96614
MW
12309 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
12310 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
12311 _adv_asc38C1600_chksum);
12312 if (asc_dvc->err_code)
27c868c2 12313 return ADV_ERROR;
1da177e4 12314
27c868c2
MW
12315 /*
12316 * Restore the RISC memory BIOS region.
12317 */
12318 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12319 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12320 bios_mem[i]);
12321 }
1da177e4 12322
27c868c2
MW
12323 /*
12324 * Calculate and write the microcode code checksum to the microcode
12325 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
12326 */
12327 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
12328 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
12329 code_sum = 0;
12330 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
12331 for (word = begin_addr; word < end_addr; word += 2) {
12332 code_sum += AdvReadWordAutoIncLram(iop_base);
12333 }
12334 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
12335
12336 /*
12337 * Read microcode version and date.
12338 */
12339 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
12340 asc_dvc->cfg->mcode_date);
12341 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
12342 asc_dvc->cfg->mcode_version);
12343
12344 /*
12345 * Set the chip type to indicate the ASC38C1600.
12346 */
12347 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
12348
12349 /*
12350 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
12351 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
12352 * cable detection and then we are able to read C_DET[3:0].
12353 *
12354 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
12355 * Microcode Default Value' section below.
12356 */
12357 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12358 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
12359 scsi_cfg1 | DIS_TERM_DRV);
12360
12361 /*
12362 * If the PCI Configuration Command Register "Parity Error Response
12363 * Control" Bit was clear (0), then set the microcode variable
12364 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
12365 * to ignore DMA parity errors.
12366 */
12367 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
12368 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12369 word |= CONTROL_FLAG_IGNORE_PERR;
12370 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12371 }
1da177e4 12372
27c868c2
MW
12373 /*
12374 * If the BIOS control flag AIPP (Asynchronous Information
12375 * Phase Protection) disable bit is not set, then set the firmware
12376 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
12377 * AIPP checking and encoding.
12378 */
12379 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
12380 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12381 word |= CONTROL_FLAG_ENABLE_AIPP;
12382 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12383 }
1da177e4 12384
27c868c2
MW
12385 /*
12386 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
12387 * and START_CTL_TH [3:2].
12388 */
12389 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
12390 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
12391
12392 /*
12393 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 12394 * queuing will be set in slave_configure() based on what a
27c868c2
MW
12395 * device reports it is capable of in Inquiry byte 7.
12396 *
12397 * If SCSI Bus Resets have been disabled, then directly set
12398 * SDTR and WDTR from the EEPROM configuration. This will allow
12399 * the BIOS and warm boot to work without a SCSI bus hang on
12400 * the Inquiry caused by host and target mismatched DTR values.
12401 * Without the SCSI Bus Reset, before an Inquiry a device can't
12402 * be assumed to be in Asynchronous, Narrow mode.
12403 */
12404 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
12405 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
12406 asc_dvc->wdtr_able);
12407 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
12408 asc_dvc->sdtr_able);
12409 }
1da177e4 12410
27c868c2
MW
12411 /*
12412 * Set microcode operating variables for DISC and SDTR_SPEED1,
12413 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
12414 * configuration values.
12415 *
12416 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
12417 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
12418 * without determining here whether the device supports SDTR.
12419 */
12420 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
12421 asc_dvc->cfg->disc_enable);
12422 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
12423 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
12424 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
12425 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
12426
12427 /*
12428 * Set SCSI_CFG0 Microcode Default Value.
12429 *
12430 * The microcode will set the SCSI_CFG0 register using this value
12431 * after it is started below.
12432 */
12433 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
12434 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
12435 asc_dvc->chip_scsi_id);
12436
12437 /*
12438 * Calculate SCSI_CFG1 Microcode Default Value.
12439 *
12440 * The microcode will set the SCSI_CFG1 register using this value
12441 * after it is started below.
12442 *
12443 * Each ASC-38C1600 function has only two cable detect bits.
12444 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
12445 */
12446 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12447
12448 /*
12449 * If the cable is reversed all of the SCSI_CTRL register signals
12450 * will be set. Check for and return an error if this condition is
12451 * found.
12452 */
12453 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
12454 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
12455 return ADV_ERROR;
12456 }
1da177e4 12457
27c868c2
MW
12458 /*
12459 * Each ASC-38C1600 function has two connectors. Only an HVD device
12460 * can not be connected to either connector. An LVD device or SE device
12461 * may be connected to either connecor. If an SE device is connected,
12462 * then at most Ultra speed (20 Mhz) can be used on both connectors.
12463 *
12464 * If an HVD device is attached, return an error.
12465 */
12466 if (scsi_cfg1 & HVD) {
12467 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
12468 return ADV_ERROR;
12469 }
1da177e4 12470
27c868c2
MW
12471 /*
12472 * Each function in the ASC-38C1600 uses only the SE cable detect and
12473 * termination because there are two connectors for each function. Each
12474 * function may use either LVD or SE mode. Corresponding the SE automatic
12475 * termination control EEPROM bits are used for each function. Each
12476 * function has its own EEPROM. If SE automatic control is enabled for
12477 * the function, then set the termination value based on a table listed
12478 * in a_condor.h.
12479 *
12480 * If manual termination is specified in the EEPROM for the function,
12481 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
12482 * ready to be 'ored' into SCSI_CFG1.
12483 */
12484 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
13ac2d9c 12485 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2
MW
12486 /* SE automatic termination control is enabled. */
12487 switch (scsi_cfg1 & C_DET_SE) {
12488 /* TERM_SE_HI: on, TERM_SE_LO: on */
12489 case 0x1:
12490 case 0x2:
12491 case 0x3:
12492 asc_dvc->cfg->termination |= TERM_SE;
12493 break;
12494
12495 case 0x0:
13ac2d9c 12496 if (PCI_FUNC(pdev->devfn) == 0) {
27c868c2
MW
12497 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
12498 } else {
12499 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
12500 asc_dvc->cfg->termination |= TERM_SE_HI;
12501 }
12502 break;
12503 }
12504 }
1da177e4 12505
27c868c2
MW
12506 /*
12507 * Clear any set TERM_SE bits.
12508 */
12509 scsi_cfg1 &= ~TERM_SE;
12510
12511 /*
12512 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
12513 */
12514 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
12515
12516 /*
12517 * Clear Big Endian and Terminator Polarity bits and set possibly
12518 * modified termination control bits in the Microcode SCSI_CFG1
12519 * Register Value.
12520 *
12521 * Big Endian bit is not used even on big endian machines.
12522 */
12523 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
12524
12525 /*
12526 * Set SCSI_CFG1 Microcode Default Value
12527 *
12528 * Set possibly modified termination control bits in the Microcode
12529 * SCSI_CFG1 Register Value.
12530 *
12531 * The microcode will set the SCSI_CFG1 register using this value
12532 * after it is started below.
12533 */
12534 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
12535
12536 /*
12537 * Set MEM_CFG Microcode Default Value
12538 *
12539 * The microcode will set the MEM_CFG register using this value
12540 * after it is started below.
12541 *
12542 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12543 * are defined.
12544 *
12545 * ASC-38C1600 has 32KB internal memory.
12546 *
12547 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
12548 * out a special 16K Adv Library and Microcode version. After the issue
12549 * resolved, we should turn back to the 32K support. Both a_condor.h and
12550 * mcode.sas files also need to be updated.
12551 *
12552 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12553 * BIOS_EN | RAM_SZ_32KB);
12554 */
12555 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12556 BIOS_EN | RAM_SZ_16KB);
12557
12558 /*
12559 * Set SEL_MASK Microcode Default Value
12560 *
12561 * The microcode will set the SEL_MASK register using this value
12562 * after it is started below.
12563 */
12564 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12565 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12566
a9f4a59a 12567 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
12568
12569 /*
12570 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12571 */
12572 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12573 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12574 return ADV_ERROR;
12575 }
12576 asc_dvc->carr_freelist = (ADV_CARR_T *)
12577 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12578
12579 /*
12580 * The first command issued will be placed in the stopper carrier.
12581 */
12582 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12583
12584 /*
12585 * Set RISC ICQ physical address start value. Initialize the
12586 * COMMA register to the same value otherwise the RISC will
12587 * prematurely detect a command is available.
12588 */
12589 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12590 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
12591 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
12592
12593 /*
12594 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12595 */
12596 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12597 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12598 return ADV_ERROR;
12599 }
12600 asc_dvc->carr_freelist = (ADV_CARR_T *)
12601 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12602
12603 /*
12604 * The first command completed by the RISC will be placed in
12605 * the stopper.
12606 *
12607 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12608 * completed the RISC will set the ASC_RQ_STOPPER bit.
12609 */
12610 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12611
12612 /*
12613 * Set RISC IRQ physical address start value.
12614 */
12615 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12616 asc_dvc->carr_pending_cnt = 0;
12617
12618 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12619 (ADV_INTR_ENABLE_HOST_INTR |
12620 ADV_INTR_ENABLE_GLOBAL_INTR));
12621 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12622 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12623
12624 /* finally, finally, gentlemen, start your engine */
12625 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12626
12627 /*
12628 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12629 * Resets should be performed. The RISC has to be running
12630 * to issue a SCSI Bus Reset.
12631 */
12632 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
12633 /*
12634 * If the BIOS Signature is present in memory, restore the
12635 * per TID microcode operating variables.
12636 */
12637 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
12638 0x55AA) {
12639 /*
12640 * Restore per TID negotiated values.
12641 */
12642 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12643 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12644 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
12645 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
12646 tagqng_able);
12647 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
12648 AdvWriteByteLram(iop_base,
12649 ASC_MC_NUMBER_OF_MAX_CMD + tid,
12650 max_cmd[tid]);
12651 }
12652 } else {
12653 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
12654 warn_code = ASC_WARN_BUSRESET_ERROR;
12655 }
12656 }
12657 }
1da177e4 12658
27c868c2
MW
12659 return warn_code;
12660}
1da177e4 12661
27c868c2
MW
12662/*
12663 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12664 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12665 * all of this is done.
12666 *
12667 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12668 *
12669 * For a non-fatal error return a warning code. If there are no warnings
12670 * then 0 is returned.
12671 *
12672 * Note: Chip is stopped on entry.
12673 */
78e77d8b 12674static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
12675{
12676 AdvPortAddr iop_base;
12677 ushort warn_code;
12678 ADVEEP_3550_CONFIG eep_config;
1da177e4 12679
27c868c2 12680 iop_base = asc_dvc->iop_base;
1da177e4 12681
27c868c2 12682 warn_code = 0;
1da177e4 12683
27c868c2
MW
12684 /*
12685 * Read the board's EEPROM configuration.
12686 *
12687 * Set default values if a bad checksum is found.
12688 */
12689 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12690 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 12691
27c868c2
MW
12692 /*
12693 * Set EEPROM default values.
12694 */
d68f4321
MW
12695 memcpy(&eep_config, &Default_3550_EEPROM_Config,
12696 sizeof(ADVEEP_3550_CONFIG));
1da177e4 12697
27c868c2 12698 /*
d68f4321
MW
12699 * Assume the 6 byte board serial number that was read from
12700 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
12701 */
12702 eep_config.serial_number_word3 =
12703 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 12704
27c868c2
MW
12705 eep_config.serial_number_word2 =
12706 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 12707
27c868c2
MW
12708 eep_config.serial_number_word1 =
12709 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 12710
27c868c2
MW
12711 AdvSet3550EEPConfig(iop_base, &eep_config);
12712 }
12713 /*
12714 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12715 * EEPROM configuration that was read.
12716 *
12717 * This is the mapping of EEPROM fields to Adv Library fields.
12718 */
12719 asc_dvc->wdtr_able = eep_config.wdtr_able;
12720 asc_dvc->sdtr_able = eep_config.sdtr_able;
12721 asc_dvc->ultra_able = eep_config.ultra_able;
12722 asc_dvc->tagqng_able = eep_config.tagqng_able;
12723 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12724 asc_dvc->max_host_qng = eep_config.max_host_qng;
12725 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12726 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12727 asc_dvc->start_motor = eep_config.start_motor;
12728 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12729 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12730 asc_dvc->no_scam = eep_config.scam_tolerant;
12731 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12732 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12733 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12734
12735 /*
12736 * Set the host maximum queuing (max. 253, min. 16) and the per device
12737 * maximum queuing (max. 63, min. 4).
12738 */
12739 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12740 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12741 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12742 /* If the value is zero, assume it is uninitialized. */
12743 if (eep_config.max_host_qng == 0) {
12744 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12745 } else {
12746 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12747 }
12748 }
1da177e4 12749
27c868c2
MW
12750 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12751 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12752 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12753 /* If the value is zero, assume it is uninitialized. */
12754 if (eep_config.max_dvc_qng == 0) {
12755 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12756 } else {
12757 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12758 }
12759 }
1da177e4 12760
27c868c2
MW
12761 /*
12762 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12763 * set 'max_dvc_qng' to 'max_host_qng'.
12764 */
12765 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12766 eep_config.max_dvc_qng = eep_config.max_host_qng;
12767 }
1da177e4 12768
27c868c2
MW
12769 /*
12770 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12771 * values based on possibly adjusted EEPROM values.
12772 */
12773 asc_dvc->max_host_qng = eep_config.max_host_qng;
12774 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12775
12776 /*
12777 * If the EEPROM 'termination' field is set to automatic (0), then set
12778 * the ADV_DVC_CFG 'termination' field to automatic also.
12779 *
12780 * If the termination is specified with a non-zero 'termination'
12781 * value check that a legal value is set and set the ADV_DVC_CFG
12782 * 'termination' field appropriately.
12783 */
12784 if (eep_config.termination == 0) {
12785 asc_dvc->cfg->termination = 0; /* auto termination */
12786 } else {
12787 /* Enable manual control with low off / high off. */
12788 if (eep_config.termination == 1) {
12789 asc_dvc->cfg->termination = TERM_CTL_SEL;
12790
12791 /* Enable manual control with low off / high on. */
12792 } else if (eep_config.termination == 2) {
12793 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
12794
12795 /* Enable manual control with low on / high on. */
12796 } else if (eep_config.termination == 3) {
12797 asc_dvc->cfg->termination =
12798 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
12799 } else {
12800 /*
12801 * The EEPROM 'termination' field contains a bad value. Use
12802 * automatic termination instead.
12803 */
12804 asc_dvc->cfg->termination = 0;
12805 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12806 }
12807 }
1da177e4 12808
27c868c2
MW
12809 return warn_code;
12810}
1da177e4 12811
27c868c2
MW
12812/*
12813 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12814 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12815 * all of this is done.
12816 *
12817 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12818 *
12819 * For a non-fatal error return a warning code. If there are no warnings
12820 * then 0 is returned.
12821 *
12822 * Note: Chip is stopped on entry.
12823 */
78e77d8b 12824static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
12825{
12826 AdvPortAddr iop_base;
12827 ushort warn_code;
12828 ADVEEP_38C0800_CONFIG eep_config;
27c868c2
MW
12829 uchar tid, termination;
12830 ushort sdtr_speed = 0;
12831
12832 iop_base = asc_dvc->iop_base;
12833
12834 warn_code = 0;
12835
12836 /*
12837 * Read the board's EEPROM configuration.
12838 *
12839 * Set default values if a bad checksum is found.
12840 */
12841 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
12842 eep_config.check_sum) {
12843 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 12844
27c868c2
MW
12845 /*
12846 * Set EEPROM default values.
12847 */
d68f4321
MW
12848 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
12849 sizeof(ADVEEP_38C0800_CONFIG));
1da177e4 12850
27c868c2 12851 /*
d68f4321
MW
12852 * Assume the 6 byte board serial number that was read from
12853 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
12854 */
12855 eep_config.serial_number_word3 =
12856 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 12857
27c868c2
MW
12858 eep_config.serial_number_word2 =
12859 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 12860
27c868c2
MW
12861 eep_config.serial_number_word1 =
12862 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 12863
27c868c2
MW
12864 AdvSet38C0800EEPConfig(iop_base, &eep_config);
12865 }
12866 /*
12867 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
12868 * EEPROM configuration that was read.
12869 *
12870 * This is the mapping of EEPROM fields to Adv Library fields.
12871 */
12872 asc_dvc->wdtr_able = eep_config.wdtr_able;
12873 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
12874 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
12875 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
12876 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
12877 asc_dvc->tagqng_able = eep_config.tagqng_able;
12878 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12879 asc_dvc->max_host_qng = eep_config.max_host_qng;
12880 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12881 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12882 asc_dvc->start_motor = eep_config.start_motor;
12883 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12884 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12885 asc_dvc->no_scam = eep_config.scam_tolerant;
12886 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12887 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12888 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12889
12890 /*
12891 * For every Target ID if any of its 'sdtr_speed[1234]' bits
12892 * are set, then set an 'sdtr_able' bit for it.
12893 */
12894 asc_dvc->sdtr_able = 0;
12895 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12896 if (tid == 0) {
12897 sdtr_speed = asc_dvc->sdtr_speed1;
12898 } else if (tid == 4) {
12899 sdtr_speed = asc_dvc->sdtr_speed2;
12900 } else if (tid == 8) {
12901 sdtr_speed = asc_dvc->sdtr_speed3;
12902 } else if (tid == 12) {
12903 sdtr_speed = asc_dvc->sdtr_speed4;
12904 }
12905 if (sdtr_speed & ADV_MAX_TID) {
12906 asc_dvc->sdtr_able |= (1 << tid);
12907 }
12908 sdtr_speed >>= 4;
12909 }
1da177e4 12910
27c868c2
MW
12911 /*
12912 * Set the host maximum queuing (max. 253, min. 16) and the per device
12913 * maximum queuing (max. 63, min. 4).
12914 */
12915 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12916 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12917 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12918 /* If the value is zero, assume it is uninitialized. */
12919 if (eep_config.max_host_qng == 0) {
12920 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12921 } else {
12922 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12923 }
12924 }
1da177e4 12925
27c868c2
MW
12926 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12927 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12928 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12929 /* If the value is zero, assume it is uninitialized. */
12930 if (eep_config.max_dvc_qng == 0) {
12931 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12932 } else {
12933 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12934 }
12935 }
1da177e4 12936
27c868c2
MW
12937 /*
12938 * If 'max_dvc_qng' is greater than 'max_host_qng', then
12939 * set 'max_dvc_qng' to 'max_host_qng'.
12940 */
12941 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12942 eep_config.max_dvc_qng = eep_config.max_host_qng;
12943 }
1da177e4 12944
27c868c2
MW
12945 /*
12946 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12947 * values based on possibly adjusted EEPROM values.
12948 */
12949 asc_dvc->max_host_qng = eep_config.max_host_qng;
12950 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12951
12952 /*
12953 * If the EEPROM 'termination' field is set to automatic (0), then set
12954 * the ADV_DVC_CFG 'termination' field to automatic also.
12955 *
12956 * If the termination is specified with a non-zero 'termination'
12957 * value check that a legal value is set and set the ADV_DVC_CFG
12958 * 'termination' field appropriately.
12959 */
12960 if (eep_config.termination_se == 0) {
12961 termination = 0; /* auto termination for SE */
12962 } else {
12963 /* Enable manual control with low off / high off. */
12964 if (eep_config.termination_se == 1) {
12965 termination = 0;
12966
12967 /* Enable manual control with low off / high on. */
12968 } else if (eep_config.termination_se == 2) {
12969 termination = TERM_SE_HI;
12970
12971 /* Enable manual control with low on / high on. */
12972 } else if (eep_config.termination_se == 3) {
12973 termination = TERM_SE;
12974 } else {
12975 /*
12976 * The EEPROM 'termination_se' field contains a bad value.
12977 * Use automatic termination instead.
12978 */
12979 termination = 0;
12980 warn_code |= ASC_WARN_EEPROM_TERMINATION;
12981 }
12982 }
1da177e4 12983
27c868c2
MW
12984 if (eep_config.termination_lvd == 0) {
12985 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
12986 } else {
12987 /* Enable manual control with low off / high off. */
12988 if (eep_config.termination_lvd == 1) {
12989 asc_dvc->cfg->termination = termination;
12990
12991 /* Enable manual control with low off / high on. */
12992 } else if (eep_config.termination_lvd == 2) {
12993 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
12994
12995 /* Enable manual control with low on / high on. */
12996 } else if (eep_config.termination_lvd == 3) {
12997 asc_dvc->cfg->termination = termination | TERM_LVD;
12998 } else {
12999 /*
13000 * The EEPROM 'termination_lvd' field contains a bad value.
13001 * Use automatic termination instead.
13002 */
13003 asc_dvc->cfg->termination = termination;
13004 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13005 }
13006 }
1da177e4 13007
27c868c2 13008 return warn_code;
1da177e4
LT
13009}
13010
13011/*
27c868c2
MW
13012 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13013 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13014 * all of this is done.
1da177e4
LT
13015 *
13016 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13017 *
13018 * For a non-fatal error return a warning code. If there are no warnings
13019 * then 0 is returned.
13020 *
27c868c2 13021 * Note: Chip is stopped on entry.
1da177e4 13022 */
78e77d8b 13023static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13024{
27c868c2
MW
13025 AdvPortAddr iop_base;
13026 ushort warn_code;
13027 ADVEEP_38C1600_CONFIG eep_config;
27c868c2
MW
13028 uchar tid, termination;
13029 ushort sdtr_speed = 0;
13030
13031 iop_base = asc_dvc->iop_base;
13032
13033 warn_code = 0;
13034
13035 /*
13036 * Read the board's EEPROM configuration.
13037 *
13038 * Set default values if a bad checksum is found.
13039 */
13040 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13041 eep_config.check_sum) {
13ac2d9c 13042 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2 13043 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13044
27c868c2
MW
13045 /*
13046 * Set EEPROM default values.
13047 */
d68f4321
MW
13048 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13049 sizeof(ADVEEP_38C1600_CONFIG));
27c868c2 13050
d68f4321
MW
13051 if (PCI_FUNC(pdev->devfn) != 0) {
13052 u8 ints;
13053 /*
13054 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13055 * and old Mac system booting problem. The Expansion
13056 * ROM must be disabled in Function 1 for these systems
13057 */
13058 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13059 /*
13060 * Clear the INTAB (bit 11) if the GPIO 0 input
13061 * indicates the Function 1 interrupt line is wired
13062 * to INTB.
13063 *
13064 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13065 * 1 - Function 1 interrupt line wired to INT A.
13066 * 0 - Function 1 interrupt line wired to INT B.
13067 *
13068 * Note: Function 0 is always wired to INTA.
13069 * Put all 5 GPIO bits in input mode and then read
13070 * their input values.
13071 */
13072 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13073 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13074 if ((ints & 0x01) == 0)
13075 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
27c868c2 13076 }
1da177e4 13077
27c868c2 13078 /*
d68f4321
MW
13079 * Assume the 6 byte board serial number that was read from
13080 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13081 */
13082 eep_config.serial_number_word3 =
d68f4321 13083 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
27c868c2 13084 eep_config.serial_number_word2 =
d68f4321 13085 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 13086 eep_config.serial_number_word1 =
d68f4321 13087 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13088
27c868c2
MW
13089 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13090 }
1da177e4 13091
27c868c2
MW
13092 /*
13093 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13094 * EEPROM configuration that was read.
13095 *
13096 * This is the mapping of EEPROM fields to Adv Library fields.
13097 */
13098 asc_dvc->wdtr_able = eep_config.wdtr_able;
13099 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13100 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13101 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13102 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13103 asc_dvc->ppr_able = 0;
13104 asc_dvc->tagqng_able = eep_config.tagqng_able;
13105 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13106 asc_dvc->max_host_qng = eep_config.max_host_qng;
13107 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13108 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13109 asc_dvc->start_motor = eep_config.start_motor;
13110 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13111 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13112 asc_dvc->no_scam = eep_config.scam_tolerant;
13113
13114 /*
13115 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13116 * are set, then set an 'sdtr_able' bit for it.
13117 */
13118 asc_dvc->sdtr_able = 0;
13119 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13120 if (tid == 0) {
13121 sdtr_speed = asc_dvc->sdtr_speed1;
13122 } else if (tid == 4) {
13123 sdtr_speed = asc_dvc->sdtr_speed2;
13124 } else if (tid == 8) {
13125 sdtr_speed = asc_dvc->sdtr_speed3;
13126 } else if (tid == 12) {
13127 sdtr_speed = asc_dvc->sdtr_speed4;
13128 }
13129 if (sdtr_speed & ASC_MAX_TID) {
13130 asc_dvc->sdtr_able |= (1 << tid);
13131 }
13132 sdtr_speed >>= 4;
13133 }
1da177e4 13134
27c868c2
MW
13135 /*
13136 * Set the host maximum queuing (max. 253, min. 16) and the per device
13137 * maximum queuing (max. 63, min. 4).
13138 */
13139 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13140 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13141 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13142 /* If the value is zero, assume it is uninitialized. */
13143 if (eep_config.max_host_qng == 0) {
13144 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13145 } else {
13146 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13147 }
13148 }
1da177e4 13149
27c868c2
MW
13150 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13151 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13152 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13153 /* If the value is zero, assume it is uninitialized. */
13154 if (eep_config.max_dvc_qng == 0) {
13155 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13156 } else {
13157 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13158 }
13159 }
1da177e4 13160
27c868c2
MW
13161 /*
13162 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13163 * set 'max_dvc_qng' to 'max_host_qng'.
13164 */
13165 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13166 eep_config.max_dvc_qng = eep_config.max_host_qng;
13167 }
1da177e4 13168
27c868c2
MW
13169 /*
13170 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13171 * values based on possibly adjusted EEPROM values.
13172 */
13173 asc_dvc->max_host_qng = eep_config.max_host_qng;
13174 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13175
13176 /*
13177 * If the EEPROM 'termination' field is set to automatic (0), then set
13178 * the ASC_DVC_CFG 'termination' field to automatic also.
13179 *
13180 * If the termination is specified with a non-zero 'termination'
13181 * value check that a legal value is set and set the ASC_DVC_CFG
13182 * 'termination' field appropriately.
13183 */
13184 if (eep_config.termination_se == 0) {
13185 termination = 0; /* auto termination for SE */
13186 } else {
13187 /* Enable manual control with low off / high off. */
13188 if (eep_config.termination_se == 1) {
13189 termination = 0;
13190
13191 /* Enable manual control with low off / high on. */
13192 } else if (eep_config.termination_se == 2) {
13193 termination = TERM_SE_HI;
13194
13195 /* Enable manual control with low on / high on. */
13196 } else if (eep_config.termination_se == 3) {
13197 termination = TERM_SE;
13198 } else {
13199 /*
13200 * The EEPROM 'termination_se' field contains a bad value.
13201 * Use automatic termination instead.
13202 */
13203 termination = 0;
13204 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13205 }
13206 }
1da177e4 13207
27c868c2
MW
13208 if (eep_config.termination_lvd == 0) {
13209 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13210 } else {
13211 /* Enable manual control with low off / high off. */
13212 if (eep_config.termination_lvd == 1) {
13213 asc_dvc->cfg->termination = termination;
13214
13215 /* Enable manual control with low off / high on. */
13216 } else if (eep_config.termination_lvd == 2) {
13217 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13218
13219 /* Enable manual control with low on / high on. */
13220 } else if (eep_config.termination_lvd == 3) {
13221 asc_dvc->cfg->termination = termination | TERM_LVD;
13222 } else {
13223 /*
13224 * The EEPROM 'termination_lvd' field contains a bad value.
13225 * Use automatic termination instead.
13226 */
13227 asc_dvc->cfg->termination = termination;
13228 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13229 }
13230 }
1da177e4 13231
27c868c2 13232 return warn_code;
1da177e4
LT
13233}
13234
13235/*
13236 * Read EEPROM configuration into the specified buffer.
13237 *
13238 * Return a checksum based on the EEPROM configuration read.
13239 */
78e77d8b 13240static ushort __devinit
1da177e4
LT
13241AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
13242{
27c868c2
MW
13243 ushort wval, chksum;
13244 ushort *wbuf;
13245 int eep_addr;
13246 ushort *charfields;
13247
13248 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
13249 wbuf = (ushort *)cfg_buf;
13250 chksum = 0;
13251
13252 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13253 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13254 wval = AdvReadEEPWord(iop_base, eep_addr);
13255 chksum += wval; /* Checksum is calculated from word values. */
13256 if (*charfields++) {
13257 *wbuf = le16_to_cpu(wval);
13258 } else {
13259 *wbuf = wval;
13260 }
13261 }
13262 /* Read checksum word. */
13263 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13264 wbuf++;
13265 charfields++;
13266
13267 /* Read rest of EEPROM not covered by the checksum. */
13268 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13269 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13270 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13271 if (*charfields++) {
13272 *wbuf = le16_to_cpu(*wbuf);
13273 }
13274 }
13275 return chksum;
1da177e4
LT
13276}
13277
13278/*
13279 * Read EEPROM configuration into the specified buffer.
13280 *
13281 * Return a checksum based on the EEPROM configuration read.
13282 */
78e77d8b 13283static ushort __devinit
27c868c2 13284AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 13285{
27c868c2
MW
13286 ushort wval, chksum;
13287 ushort *wbuf;
13288 int eep_addr;
13289 ushort *charfields;
13290
13291 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
13292 wbuf = (ushort *)cfg_buf;
13293 chksum = 0;
13294
13295 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13296 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13297 wval = AdvReadEEPWord(iop_base, eep_addr);
13298 chksum += wval; /* Checksum is calculated from word values. */
13299 if (*charfields++) {
13300 *wbuf = le16_to_cpu(wval);
13301 } else {
13302 *wbuf = wval;
13303 }
13304 }
13305 /* Read checksum word. */
13306 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13307 wbuf++;
13308 charfields++;
13309
13310 /* Read rest of EEPROM not covered by the checksum. */
13311 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13312 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13313 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13314 if (*charfields++) {
13315 *wbuf = le16_to_cpu(*wbuf);
13316 }
13317 }
13318 return chksum;
1da177e4
LT
13319}
13320
13321/*
13322 * Read EEPROM configuration into the specified buffer.
13323 *
13324 * Return a checksum based on the EEPROM configuration read.
13325 */
78e77d8b 13326static ushort __devinit
27c868c2 13327AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 13328{
27c868c2
MW
13329 ushort wval, chksum;
13330 ushort *wbuf;
13331 int eep_addr;
13332 ushort *charfields;
13333
13334 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
13335 wbuf = (ushort *)cfg_buf;
13336 chksum = 0;
13337
13338 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
13339 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
13340 wval = AdvReadEEPWord(iop_base, eep_addr);
13341 chksum += wval; /* Checksum is calculated from word values. */
13342 if (*charfields++) {
13343 *wbuf = le16_to_cpu(wval);
13344 } else {
13345 *wbuf = wval;
13346 }
13347 }
13348 /* Read checksum word. */
13349 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13350 wbuf++;
13351 charfields++;
13352
13353 /* Read rest of EEPROM not covered by the checksum. */
13354 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
13355 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
13356 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
13357 if (*charfields++) {
13358 *wbuf = le16_to_cpu(*wbuf);
13359 }
13360 }
13361 return chksum;
1da177e4
LT
13362}
13363
13364/*
13365 * Read the EEPROM from specified location
13366 */
78e77d8b 13367static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 13368{
27c868c2
MW
13369 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13370 ASC_EEP_CMD_READ | eep_word_addr);
13371 AdvWaitEEPCmd(iop_base);
13372 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
13373}
13374
13375/*
13376 * Wait for EEPROM command to complete
13377 */
78e77d8b 13378static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 13379{
27c868c2
MW
13380 int eep_delay_ms;
13381
13382 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
13383 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
13384 ASC_EEP_CMD_DONE) {
13385 break;
13386 }
b009bef6 13387 mdelay(1);
27c868c2
MW
13388 }
13389 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
b009bef6
MW
13390 0)
13391 BUG();
27c868c2 13392 return;
1da177e4
LT
13393}
13394
13395/*
13396 * Write the EEPROM from 'cfg_buf'.
13397 */
78e77d8b 13398void __devinit
1da177e4
LT
13399AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
13400{
27c868c2
MW
13401 ushort *wbuf;
13402 ushort addr, chksum;
13403 ushort *charfields;
13404
13405 wbuf = (ushort *)cfg_buf;
13406 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
13407 chksum = 0;
13408
13409 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13410 AdvWaitEEPCmd(iop_base);
13411
13412 /*
13413 * Write EEPROM from word 0 to word 20.
13414 */
13415 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13416 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13417 ushort word;
13418
13419 if (*charfields++) {
13420 word = cpu_to_le16(*wbuf);
13421 } else {
13422 word = *wbuf;
13423 }
13424 chksum += *wbuf; /* Checksum is calculated from word values. */
13425 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13426 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13427 ASC_EEP_CMD_WRITE | addr);
13428 AdvWaitEEPCmd(iop_base);
b009bef6 13429 mdelay(ADV_EEP_DELAY_MS);
27c868c2 13430 }
1da177e4 13431
27c868c2
MW
13432 /*
13433 * Write EEPROM checksum at word 21.
13434 */
13435 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13436 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13437 AdvWaitEEPCmd(iop_base);
13438 wbuf++;
13439 charfields++;
13440
13441 /*
13442 * Write EEPROM OEM name at words 22 to 29.
13443 */
13444 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13445 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13446 ushort word;
13447
13448 if (*charfields++) {
13449 word = cpu_to_le16(*wbuf);
13450 } else {
13451 word = *wbuf;
13452 }
13453 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13454 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13455 ASC_EEP_CMD_WRITE | addr);
13456 AdvWaitEEPCmd(iop_base);
13457 }
13458 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13459 AdvWaitEEPCmd(iop_base);
13460 return;
1da177e4
LT
13461}
13462
13463/*
13464 * Write the EEPROM from 'cfg_buf'.
13465 */
78e77d8b 13466void __devinit
27c868c2 13467AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 13468{
27c868c2
MW
13469 ushort *wbuf;
13470 ushort *charfields;
13471 ushort addr, chksum;
13472
13473 wbuf = (ushort *)cfg_buf;
13474 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
13475 chksum = 0;
13476
13477 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13478 AdvWaitEEPCmd(iop_base);
13479
13480 /*
13481 * Write EEPROM from word 0 to word 20.
13482 */
13483 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13484 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13485 ushort word;
13486
13487 if (*charfields++) {
13488 word = cpu_to_le16(*wbuf);
13489 } else {
13490 word = *wbuf;
13491 }
13492 chksum += *wbuf; /* Checksum is calculated from word values. */
13493 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13494 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13495 ASC_EEP_CMD_WRITE | addr);
13496 AdvWaitEEPCmd(iop_base);
b009bef6 13497 mdelay(ADV_EEP_DELAY_MS);
27c868c2 13498 }
1da177e4 13499
27c868c2
MW
13500 /*
13501 * Write EEPROM checksum at word 21.
13502 */
13503 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13504 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13505 AdvWaitEEPCmd(iop_base);
13506 wbuf++;
13507 charfields++;
13508
13509 /*
13510 * Write EEPROM OEM name at words 22 to 29.
13511 */
13512 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13513 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13514 ushort word;
13515
13516 if (*charfields++) {
13517 word = cpu_to_le16(*wbuf);
13518 } else {
13519 word = *wbuf;
13520 }
13521 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13522 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13523 ASC_EEP_CMD_WRITE | addr);
13524 AdvWaitEEPCmd(iop_base);
13525 }
13526 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13527 AdvWaitEEPCmd(iop_base);
13528 return;
1da177e4
LT
13529}
13530
13531/*
13532 * Write the EEPROM from 'cfg_buf'.
13533 */
78e77d8b 13534void __devinit
27c868c2 13535AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 13536{
27c868c2
MW
13537 ushort *wbuf;
13538 ushort *charfields;
13539 ushort addr, chksum;
13540
13541 wbuf = (ushort *)cfg_buf;
13542 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
13543 chksum = 0;
13544
13545 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
13546 AdvWaitEEPCmd(iop_base);
13547
13548 /*
13549 * Write EEPROM from word 0 to word 20.
13550 */
13551 for (addr = ADV_EEP_DVC_CFG_BEGIN;
13552 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
13553 ushort word;
13554
13555 if (*charfields++) {
13556 word = cpu_to_le16(*wbuf);
13557 } else {
13558 word = *wbuf;
13559 }
13560 chksum += *wbuf; /* Checksum is calculated from word values. */
13561 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13562 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13563 ASC_EEP_CMD_WRITE | addr);
13564 AdvWaitEEPCmd(iop_base);
b009bef6 13565 mdelay(ADV_EEP_DELAY_MS);
27c868c2 13566 }
1da177e4 13567
27c868c2
MW
13568 /*
13569 * Write EEPROM checksum at word 21.
13570 */
13571 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
13572 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
13573 AdvWaitEEPCmd(iop_base);
13574 wbuf++;
13575 charfields++;
13576
13577 /*
13578 * Write EEPROM OEM name at words 22 to 29.
13579 */
13580 for (addr = ADV_EEP_DVC_CTL_BEGIN;
13581 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
13582 ushort word;
13583
13584 if (*charfields++) {
13585 word = cpu_to_le16(*wbuf);
13586 } else {
13587 word = *wbuf;
13588 }
13589 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
13590 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
13591 ASC_EEP_CMD_WRITE | addr);
13592 AdvWaitEEPCmd(iop_base);
13593 }
13594 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
13595 AdvWaitEEPCmd(iop_base);
13596 return;
1da177e4
LT
13597}
13598
1da177e4
LT
13599/*
13600 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
13601 *
13602 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
13603 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
13604 * RISC to notify it a new command is ready to be executed.
13605 *
13606 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
13607 * set to SCSI_MAX_RETRY.
13608 *
13609 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
13610 * for DMA addresses or math operations are byte swapped to little-endian
13611 * order.
13612 *
13613 * Return:
13614 * ADV_SUCCESS(1) - The request was successfully queued.
13615 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
13616 * request completes.
13617 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
13618 * host IC error.
13619 */
27c868c2 13620static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 13621{
27c868c2
MW
13622 AdvPortAddr iop_base;
13623 ADV_DCNT req_size;
13624 ADV_PADDR req_paddr;
13625 ADV_CARR_T *new_carrp;
13626
27c868c2
MW
13627 /*
13628 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
13629 */
13630 if (scsiq->target_id > ADV_MAX_TID) {
13631 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
13632 scsiq->done_status = QD_WITH_ERROR;
13633 return ADV_ERROR;
13634 }
1da177e4 13635
27c868c2 13636 iop_base = asc_dvc->iop_base;
1da177e4 13637
27c868c2
MW
13638 /*
13639 * Allocate a carrier ensuring at least one carrier always
13640 * remains on the freelist and initialize fields.
13641 */
13642 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
27c868c2
MW
13643 return ADV_BUSY;
13644 }
13645 asc_dvc->carr_freelist = (ADV_CARR_T *)
13646 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
13647 asc_dvc->carr_pending_cnt++;
13648
13649 /*
13650 * Set the carrier to be a stopper by setting 'next_vpa'
13651 * to the stopper value. The current stopper will be changed
13652 * below to point to the new stopper.
13653 */
13654 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13655
13656 /*
13657 * Clear the ADV_SCSI_REQ_Q done flag.
13658 */
13659 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
13660
13661 req_size = sizeof(ADV_SCSI_REQ_Q);
13662 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
13663 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
13664
b009bef6
MW
13665 BUG_ON(req_paddr & 31);
13666 BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
27c868c2
MW
13667
13668 /* Wait for assertion before making little-endian */
13669 req_paddr = cpu_to_le32(req_paddr);
13670
13671 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
13672 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
13673 scsiq->scsiq_rptr = req_paddr;
13674
13675 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
13676 /*
13677 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
13678 * order during initialization.
13679 */
13680 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
13681
13682 /*
13683 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
13684 * the microcode. The newly allocated stopper will become the new
13685 * stopper.
13686 */
13687 asc_dvc->icq_sp->areq_vpa = req_paddr;
13688
13689 /*
13690 * Set the 'next_vpa' pointer for the old stopper to be the
13691 * physical address of the new stopper. The RISC can only
13692 * follow physical addresses.
13693 */
13694 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
13695
13696 /*
13697 * Set the host adapter stopper pointer to point to the new carrier.
13698 */
13699 asc_dvc->icq_sp = new_carrp;
13700
13701 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
13702 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13703 /*
13704 * Tickle the RISC to tell it to read its Command Queue Head pointer.
13705 */
13706 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
13707 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
13708 /*
13709 * Clear the tickle value. In the ASC-3550 the RISC flag
13710 * command 'clr_tickle_a' does not work unless the host
13711 * value is cleared.
13712 */
13713 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
13714 ADV_TICKLE_NOP);
13715 }
13716 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13717 /*
13718 * Notify the RISC a carrier is ready by writing the physical
13719 * address of the new carrier stopper to the COMMA register.
13720 */
13721 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
13722 le32_to_cpu(new_carrp->carr_pa));
13723 }
1da177e4 13724
27c868c2 13725 return ADV_SUCCESS;
1da177e4
LT
13726}
13727
13728/*
13729 * Reset SCSI Bus and purge all outstanding requests.
13730 *
13731 * Return Value:
13732 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
13733 * ADV_FALSE(0) - Microcode command failed.
13734 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
13735 * may be hung which requires driver recovery.
13736 */
27c868c2 13737static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 13738{
27c868c2
MW
13739 int status;
13740
13741 /*
13742 * Send the SCSI Bus Reset idle start idle command which asserts
13743 * the SCSI Bus Reset signal.
13744 */
13745 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
13746 if (status != ADV_TRUE) {
13747 return status;
13748 }
1da177e4 13749
27c868c2
MW
13750 /*
13751 * Delay for the specified SCSI Bus Reset hold time.
13752 *
13753 * The hold time delay is done on the host because the RISC has no
13754 * microsecond accurate timer.
13755 */
b009bef6 13756 udelay(ASC_SCSI_RESET_HOLD_TIME_US);
27c868c2
MW
13757
13758 /*
13759 * Send the SCSI Bus Reset end idle command which de-asserts
13760 * the SCSI Bus Reset signal and purges any pending requests.
13761 */
13762 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
13763 if (status != ADV_TRUE) {
13764 return status;
13765 }
13766
b009bef6 13767 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
1da177e4 13768
27c868c2 13769 return status;
1da177e4
LT
13770}
13771
13772/*
13773 * Reset chip and SCSI Bus.
13774 *
13775 * Return Value:
13776 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
13777 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
13778 */
27c868c2 13779static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 13780{
27c868c2
MW
13781 int status;
13782 ushort wdtr_able, sdtr_able, tagqng_able;
13783 ushort ppr_able = 0;
13784 uchar tid, max_cmd[ADV_MAX_TID + 1];
13785 AdvPortAddr iop_base;
13786 ushort bios_sig;
13787
13788 iop_base = asc_dvc->iop_base;
13789
13790 /*
13791 * Save current per TID negotiated values.
13792 */
13793 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13794 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13795 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13796 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
13797 }
13798 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13799 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13800 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13801 max_cmd[tid]);
13802 }
1da177e4 13803
27c868c2
MW
13804 /*
13805 * Force the AdvInitAsc3550/38C0800Driver() function to
13806 * perform a SCSI Bus Reset by clearing the BIOS signature word.
13807 * The initialization functions assumes a SCSI Bus Reset is not
13808 * needed if the BIOS signature word is present.
13809 */
13810 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
13811 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
13812
13813 /*
13814 * Stop chip and reset it.
13815 */
13816 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
13817 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
b009bef6 13818 mdelay(100);
27c868c2
MW
13819 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13820 ADV_CTRL_REG_CMD_WR_IO_REG);
13821
13822 /*
13823 * Reset Adv Library error code, if any, and try
13824 * re-initializing the chip.
13825 */
13826 asc_dvc->err_code = 0;
13827 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13828 status = AdvInitAsc38C1600Driver(asc_dvc);
13829 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13830 status = AdvInitAsc38C0800Driver(asc_dvc);
13831 } else {
13832 status = AdvInitAsc3550Driver(asc_dvc);
13833 }
1da177e4 13834
27c868c2
MW
13835 /* Translate initialization return value to status value. */
13836 if (status == 0) {
13837 status = ADV_TRUE;
13838 } else {
13839 status = ADV_FALSE;
13840 }
1da177e4 13841
27c868c2
MW
13842 /*
13843 * Restore the BIOS signature word.
13844 */
13845 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
13846
13847 /*
13848 * Restore per TID negotiated values.
13849 */
13850 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13851 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13852 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13853 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
13854 }
13855 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13856 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13857 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13858 max_cmd[tid]);
13859 }
1da177e4 13860
27c868c2 13861 return status;
1da177e4
LT
13862}
13863
13864/*
13865 * Adv Library Interrupt Service Routine
13866 *
13867 * This function is called by a driver's interrupt service routine.
13868 * The function disables and re-enables interrupts.
13869 *
13870 * When a microcode idle command is completed, the ADV_DVC_VAR
13871 * 'idle_cmd_done' field is set to ADV_TRUE.
13872 *
13873 * Note: AdvISR() can be called when interrupts are disabled or even
13874 * when there is no hardware interrupt condition present. It will
13875 * always check for completed idle commands and microcode requests.
13876 * This is an important feature that shouldn't be changed because it
13877 * allows commands to be completed from polling mode loops.
13878 *
13879 * Return:
13880 * ADV_TRUE(1) - interrupt was pending
13881 * ADV_FALSE(0) - no interrupt was pending
13882 */
27c868c2 13883static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 13884{
27c868c2
MW
13885 AdvPortAddr iop_base;
13886 uchar int_stat;
13887 ushort target_bit;
13888 ADV_CARR_T *free_carrp;
13889 ADV_VADDR irq_next_vpa;
27c868c2 13890 ADV_SCSI_REQ_Q *scsiq;
1da177e4 13891
27c868c2
MW
13892 iop_base = asc_dvc->iop_base;
13893
13894 /* Reading the register clears the interrupt. */
13895 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
13896
13897 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
13898 ADV_INTR_STATUS_INTRC)) == 0) {
27c868c2
MW
13899 return ADV_FALSE;
13900 }
13901
13902 /*
13903 * Notify the driver of an asynchronous microcode condition by
895d6b4c 13904 * calling the adv_async_callback function. The function
27c868c2
MW
13905 * is passed the microcode ASC_MC_INTRB_CODE byte value.
13906 */
13907 if (int_stat & ADV_INTR_STATUS_INTRB) {
13908 uchar intrb_code;
13909
13910 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
13911
13912 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
13913 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13914 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
13915 asc_dvc->carr_pending_cnt != 0) {
13916 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
13917 ADV_TICKLE_A);
13918 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
13919 AdvWriteByteRegister(iop_base,
13920 IOPB_TICKLE,
13921 ADV_TICKLE_NOP);
13922 }
13923 }
13924 }
13925
895d6b4c 13926 adv_async_callback(asc_dvc, intrb_code);
27c868c2
MW
13927 }
13928
13929 /*
13930 * Check if the IRQ stopper carrier contains a completed request.
13931 */
13932 while (((irq_next_vpa =
13933 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
13934 /*
13935 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
13936 * The RISC will have set 'areq_vpa' to a virtual address.
13937 *
13938 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
13939 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
13940 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
13941 * in AdvExeScsiQueue().
13942 */
13943 scsiq = (ADV_SCSI_REQ_Q *)
13944 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
13945
13946 /*
13947 * Request finished with good status and the queue was not
13948 * DMAed to host memory by the firmware. Set all status fields
13949 * to indicate good status.
13950 */
13951 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
13952 scsiq->done_status = QD_NO_ERROR;
13953 scsiq->host_status = scsiq->scsi_status = 0;
13954 scsiq->data_cnt = 0L;
13955 }
13956
13957 /*
13958 * Advance the stopper pointer to the next carrier
13959 * ignoring the lower four bits. Free the previous
13960 * stopper carrier.
13961 */
13962 free_carrp = asc_dvc->irq_sp;
13963 asc_dvc->irq_sp = (ADV_CARR_T *)
13964 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
13965
13966 free_carrp->next_vpa =
13967 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
13968 asc_dvc->carr_freelist = free_carrp;
13969 asc_dvc->carr_pending_cnt--;
13970
27c868c2
MW
13971 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
13972
13973 /*
13974 * Clear request microcode control flag.
13975 */
13976 scsiq->cntl = 0;
13977
27c868c2
MW
13978 /*
13979 * Notify the driver of the completed request by passing
13980 * the ADV_SCSI_REQ_Q pointer to its callback function.
13981 */
13982 scsiq->a_flag |= ADV_SCSIQ_DONE;
895d6b4c 13983 adv_isr_callback(asc_dvc, scsiq);
27c868c2
MW
13984 /*
13985 * Note: After the driver callback function is called, 'scsiq'
13986 * can no longer be referenced.
13987 *
13988 * Fall through and continue processing other completed
13989 * requests...
13990 */
27c868c2 13991 }
27c868c2 13992 return ADV_TRUE;
1da177e4
LT
13993}
13994
13995/*
13996 * Send an idle command to the chip and wait for completion.
13997 *
13998 * Command completion is polled for once per microsecond.
13999 *
14000 * The function can be called from anywhere including an interrupt handler.
14001 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
14002 * functions to prevent reentrancy.
14003 *
14004 * Return Values:
14005 * ADV_TRUE - command completed successfully
14006 * ADV_FALSE - command failed
14007 * ADV_ERROR - command timed out
14008 */
27c868c2 14009static int
1da177e4 14010AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 14011 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 14012{
27c868c2
MW
14013 int result;
14014 ADV_DCNT i, j;
14015 AdvPortAddr iop_base;
14016
27c868c2
MW
14017 iop_base = asc_dvc->iop_base;
14018
14019 /*
14020 * Clear the idle command status which is set by the microcode
14021 * to a non-zero value to indicate when the command is completed.
14022 * The non-zero result is one of the IDLE_CMD_STATUS_* values
27c868c2
MW
14023 */
14024 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
14025
14026 /*
14027 * Write the idle command value after the idle command parameter
14028 * has been written to avoid a race condition. If the order is not
14029 * followed, the microcode may process the idle command before the
14030 * parameters have been written to LRAM.
14031 */
14032 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
14033 cpu_to_le32(idle_cmd_parameter));
14034 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
14035
14036 /*
14037 * Tickle the RISC to tell it to process the idle command.
14038 */
14039 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
14040 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14041 /*
14042 * Clear the tickle value. In the ASC-3550 the RISC flag
14043 * command 'clr_tickle_b' does not work unless the host
14044 * value is cleared.
14045 */
14046 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
14047 }
1da177e4 14048
27c868c2
MW
14049 /* Wait for up to 100 millisecond for the idle command to timeout. */
14050 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
14051 /* Poll once each microsecond for command completion. */
14052 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
14053 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
14054 result);
b009bef6 14055 if (result != 0)
27c868c2 14056 return result;
b009bef6 14057 udelay(1);
27c868c2
MW
14058 }
14059 }
1da177e4 14060
b009bef6 14061 BUG(); /* The idle command should never timeout. */
27c868c2 14062 return ADV_ERROR;
1da177e4
LT
14063}
14064
b2c16f58
MW
14065static int __devinit
14066advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
14067{
14068 int req_cnt = 0;
14069 adv_req_t *reqp = NULL;
14070 int sg_cnt = 0;
14071 adv_sgblk_t *sgp;
14072 int warn_code, err_code;
14073
14074 /*
14075 * Allocate buffer carrier structures. The total size
14076 * is about 4 KB, so allocate all at once.
14077 */
14078 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
14079 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
14080
14081 if (!boardp->carrp)
14082 goto kmalloc_failed;
14083
14084 /*
14085 * Allocate up to 'max_host_qng' request structures for the Wide
14086 * board. The total size is about 16 KB, so allocate all at once.
14087 * If the allocation fails decrement and try again.
14088 */
14089 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
14090 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
14091
14092 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
14093 "bytes %lu\n", reqp, req_cnt,
14094 (ulong)sizeof(adv_req_t) * req_cnt);
14095
14096 if (reqp)
14097 break;
14098 }
14099
14100 if (!reqp)
14101 goto kmalloc_failed;
14102
14103 boardp->orig_reqp = reqp;
14104
14105 /*
14106 * Allocate up to ADV_TOT_SG_BLOCK request structures for
14107 * the Wide board. Each structure is about 136 bytes.
14108 */
14109 boardp->adv_sgblkp = NULL;
14110 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
14111 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
14112
14113 if (!sgp)
14114 break;
14115
14116 sgp->next_sgblkp = boardp->adv_sgblkp;
14117 boardp->adv_sgblkp = sgp;
14118
14119 }
14120
14121 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
14122 sg_cnt, sizeof(adv_sgblk_t),
14123 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
14124
14125 if (!boardp->adv_sgblkp)
14126 goto kmalloc_failed;
14127
14128 adv_dvc_varp->carrier_buf = boardp->carrp;
14129
14130 /*
14131 * Point 'adv_reqp' to the request structures and
14132 * link them together.
14133 */
14134 req_cnt--;
14135 reqp[req_cnt].next_reqp = NULL;
14136 for (; req_cnt > 0; req_cnt--) {
14137 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
14138 }
14139 boardp->adv_reqp = &reqp[0];
14140
14141 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
14142 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
14143 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
14144 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14145 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
14146 "\n");
14147 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
14148 } else {
14149 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
14150 "\n");
14151 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
14152 }
14153 err_code = adv_dvc_varp->err_code;
14154
14155 if (warn_code || err_code) {
14156 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
14157 " error 0x%x\n", boardp->id, warn_code, err_code);
14158 }
14159
14160 goto exit;
14161
14162 kmalloc_failed:
14163 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
14164 "failed\n", boardp->id);
14165 err_code = ADV_ERROR;
14166 exit:
14167 return err_code;
14168}
14169
14170static void advansys_wide_free_mem(asc_board_t *boardp)
14171{
14172 kfree(boardp->carrp);
14173 boardp->carrp = NULL;
14174 kfree(boardp->orig_reqp);
14175 boardp->orig_reqp = boardp->adv_reqp = NULL;
14176 while (boardp->adv_sgblkp) {
14177 adv_sgblk_t *sgp = boardp->adv_sgblkp;
14178 boardp->adv_sgblkp = sgp->next_sgblkp;
14179 kfree(sgp);
14180 }
14181}
14182
27c868c2
MW
14183static struct Scsi_Host *__devinit
14184advansys_board_found(int iop, struct device *dev, int bus_type)
14185{
14186 struct Scsi_Host *shost;
14187 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
14188 asc_board_t *boardp;
14189 ASC_DVC_VAR *asc_dvc_varp = NULL;
14190 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 14191 int share_irq;
27c868c2
MW
14192 int warn_code, err_code;
14193 int ret;
14194
14195 /*
27c868c2
MW
14196 * Register the adapter, get its configuration, and
14197 * initialize it.
14198 */
8dfb5379
MW
14199 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
14200 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
14201 if (!shost)
14202 return NULL;
14203
27c868c2
MW
14204 /* Initialize private per board data */
14205 boardp = ASC_BOARDP(shost);
14206 memset(boardp, 0, sizeof(asc_board_t));
78e77d8b 14207 boardp->id = asc_board_count++;
27c868c2 14208 spin_lock_init(&boardp->lock);
394dbf3f 14209 boardp->dev = dev;
27c868c2
MW
14210
14211 /*
14212 * Handle both narrow and wide boards.
14213 *
14214 * If a Wide board was detected, set the board structure
14215 * wide board flag. Set-up the board structure based on
14216 * the board type.
14217 */
14218#ifdef CONFIG_PCI
14219 if (bus_type == ASC_IS_PCI &&
14220 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14221 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14222 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
14223 boardp->flags |= ASC_IS_WIDE_BOARD;
14224 }
14225#endif /* CONFIG_PCI */
14226
14227 if (ASC_NARROW_BOARD(boardp)) {
14228 ASC_DBG(1, "advansys_board_found: narrow board\n");
14229 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
14230 asc_dvc_varp->bus_type = bus_type;
14231 asc_dvc_varp->drv_ptr = boardp;
14232 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
14233 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
14234 asc_dvc_varp->iop_base = iop;
27c868c2 14235 } else {
57ba5fe9 14236#ifdef CONFIG_PCI
27c868c2
MW
14237 ASC_DBG(1, "advansys_board_found: wide board\n");
14238 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
14239 adv_dvc_varp->drv_ptr = boardp;
14240 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
27c868c2
MW
14241 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
14242 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
14243 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
14244 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
14245 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
14246 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
14247 } else {
14248 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
14249 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
14250 }
27c868c2 14251
57ba5fe9
MW
14252 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
14253 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
14254 boardp->asc_n_io_port);
14255 if (!boardp->ioremap_addr) {
27c868c2
MW
14256 ASC_PRINT3
14257 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
57ba5fe9
MW
14258 boardp->id, pci_resource_start(pdev, 1),
14259 boardp->asc_n_io_port);
b2c16f58 14260 goto err_shost;
27c868c2 14261 }
57ba5fe9 14262 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
71f36115 14263 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
27c868c2 14264 adv_dvc_varp->iop_base);
27c868c2
MW
14265
14266 /*
14267 * Even though it isn't used to access wide boards, other
14268 * than for the debug line below, save I/O Port address so
14269 * that it can be reported.
14270 */
14271 boardp->ioport = iop;
14272
57ba5fe9
MW
14273 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
14274 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
14275 (ushort)inpw(iop));
14276#endif /* CONFIG_PCI */
27c868c2
MW
14277 }
14278
14279#ifdef CONFIG_PROC_FS
14280 /*
14281 * Allocate buffer for printing information from
14282 * /proc/scsi/advansys/[0...].
14283 */
b2c16f58
MW
14284 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
14285 if (!boardp->prtbuf) {
14286 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
14287 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
14288 goto err_unmap;
27c868c2
MW
14289 }
14290#endif /* CONFIG_PROC_FS */
14291
14292 if (ASC_NARROW_BOARD(boardp)) {
27c868c2
MW
14293 /*
14294 * Set the board bus type and PCI IRQ before
14295 * calling AscInitGetConfig().
14296 */
14297 switch (asc_dvc_varp->bus_type) {
14298#ifdef CONFIG_ISA
14299 case ASC_IS_ISA:
14300 shost->unchecked_isa_dma = TRUE;
074c8fe4 14301 share_irq = 0;
27c868c2
MW
14302 break;
14303 case ASC_IS_VL:
14304 shost->unchecked_isa_dma = FALSE;
074c8fe4 14305 share_irq = 0;
27c868c2
MW
14306 break;
14307 case ASC_IS_EISA:
14308 shost->unchecked_isa_dma = FALSE;
074c8fe4 14309 share_irq = IRQF_SHARED;
27c868c2
MW
14310 break;
14311#endif /* CONFIG_ISA */
14312#ifdef CONFIG_PCI
14313 case ASC_IS_PCI:
14314 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
27c868c2 14315 shost->unchecked_isa_dma = FALSE;
074c8fe4 14316 share_irq = IRQF_SHARED;
27c868c2
MW
14317 break;
14318#endif /* CONFIG_PCI */
14319 default:
14320 ASC_PRINT2
14321 ("advansys_board_found: board %d: unknown adapter type: %d\n",
14322 boardp->id, asc_dvc_varp->bus_type);
14323 shost->unchecked_isa_dma = TRUE;
074c8fe4 14324 share_irq = 0;
27c868c2
MW
14325 break;
14326 }
27c868c2 14327
27c868c2
MW
14328 /*
14329 * NOTE: AscInitGetConfig() may change the board's
14330 * bus_type value. The bus_type value should no
14331 * longer be used. If the bus_type field must be
14332 * referenced only use the bit-wise AND operator "&".
14333 */
14334 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
c2dce2fa 14335 err_code = AscInitGetConfig(boardp);
27c868c2 14336 } else {
c2dce2fa
MW
14337#ifdef CONFIG_PCI
14338 /*
14339 * For Wide boards set PCI information before calling
14340 * AdvInitGetConfig().
14341 */
14342 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
14343 shost->unchecked_isa_dma = FALSE;
14344 share_irq = IRQF_SHARED;
27c868c2 14345 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
394dbf3f 14346
c2dce2fa
MW
14347 err_code = AdvInitGetConfig(pdev, boardp);
14348#endif /* CONFIG_PCI */
27c868c2
MW
14349 }
14350
b2c16f58
MW
14351 if (err_code != 0)
14352 goto err_free_proc;
27c868c2
MW
14353
14354 /*
14355 * Save the EEPROM configuration so that it can be displayed
14356 * from /proc/scsi/advansys/[0...].
14357 */
14358 if (ASC_NARROW_BOARD(boardp)) {
14359
14360 ASCEEP_CONFIG *ep;
14361
14362 /*
14363 * Set the adapter's target id bit in the 'init_tidmask' field.
14364 */
14365 boardp->init_tidmask |=
14366 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
14367
14368 /*
14369 * Save EEPROM settings for the board.
14370 */
14371 ep = &boardp->eep_config.asc_eep;
14372
14373 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
14374 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
14375 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
14376 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
14377 ep->start_motor = asc_dvc_varp->start_motor;
14378 ep->cntl = asc_dvc_varp->dvc_cntl;
14379 ep->no_scam = asc_dvc_varp->no_scam;
14380 ep->max_total_qng = asc_dvc_varp->max_total_qng;
14381 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
14382 /* 'max_tag_qng' is set to the same value for every device. */
14383 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
14384 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
14385 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
14386 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
14387 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
14388 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
14389 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
14390
14391 /*
14392 * Modify board configuration.
14393 */
14394 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
c2dce2fa
MW
14395 err_code = AscInitSetConfig(pdev, boardp);
14396 if (err_code)
b2c16f58 14397 goto err_free_proc;
27c868c2
MW
14398
14399 /*
14400 * Finish initializing the 'Scsi_Host' structure.
14401 */
14402 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
14403 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
14404 shost->irq = asc_dvc_varp->irq_no;
14405 }
14406 } else {
14407 ADVEEP_3550_CONFIG *ep_3550;
14408 ADVEEP_38C0800_CONFIG *ep_38C0800;
14409 ADVEEP_38C1600_CONFIG *ep_38C1600;
14410
14411 /*
14412 * Save Wide EEP Configuration Information.
14413 */
14414 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
14415 ep_3550 = &boardp->eep_config.adv_3550_eep;
14416
14417 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
14418 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
14419 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14420 ep_3550->termination = adv_dvc_varp->cfg->termination;
14421 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
14422 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
14423 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
14424 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
14425 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
14426 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
14427 ep_3550->start_motor = adv_dvc_varp->start_motor;
14428 ep_3550->scsi_reset_delay =
14429 adv_dvc_varp->scsi_reset_wait;
14430 ep_3550->serial_number_word1 =
14431 adv_dvc_varp->cfg->serial1;
14432 ep_3550->serial_number_word2 =
14433 adv_dvc_varp->cfg->serial2;
14434 ep_3550->serial_number_word3 =
14435 adv_dvc_varp->cfg->serial3;
14436 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14437 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
14438
14439 ep_38C0800->adapter_scsi_id =
14440 adv_dvc_varp->chip_scsi_id;
14441 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
14442 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14443 ep_38C0800->termination_lvd =
14444 adv_dvc_varp->cfg->termination;
14445 ep_38C0800->disc_enable =
14446 adv_dvc_varp->cfg->disc_enable;
14447 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
14448 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
14449 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14450 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14451 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14452 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14453 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14454 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14455 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
14456 ep_38C0800->scsi_reset_delay =
14457 adv_dvc_varp->scsi_reset_wait;
14458 ep_38C0800->serial_number_word1 =
14459 adv_dvc_varp->cfg->serial1;
14460 ep_38C0800->serial_number_word2 =
14461 adv_dvc_varp->cfg->serial2;
14462 ep_38C0800->serial_number_word3 =
14463 adv_dvc_varp->cfg->serial3;
14464 } else {
14465 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
14466
14467 ep_38C1600->adapter_scsi_id =
14468 adv_dvc_varp->chip_scsi_id;
14469 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
14470 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14471 ep_38C1600->termination_lvd =
14472 adv_dvc_varp->cfg->termination;
14473 ep_38C1600->disc_enable =
14474 adv_dvc_varp->cfg->disc_enable;
14475 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
14476 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
14477 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14478 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14479 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14480 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14481 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14482 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14483 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
14484 ep_38C1600->scsi_reset_delay =
14485 adv_dvc_varp->scsi_reset_wait;
14486 ep_38C1600->serial_number_word1 =
14487 adv_dvc_varp->cfg->serial1;
14488 ep_38C1600->serial_number_word2 =
14489 adv_dvc_varp->cfg->serial2;
14490 ep_38C1600->serial_number_word3 =
14491 adv_dvc_varp->cfg->serial3;
14492 }
14493
14494 /*
14495 * Set the adapter's target id bit in the 'init_tidmask' field.
14496 */
14497 boardp->init_tidmask |=
14498 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
27c868c2
MW
14499 }
14500
14501 /*
14502 * Channels are numbered beginning with 0. For AdvanSys one host
14503 * structure supports one channel. Multi-channel boards have a
14504 * separate host structure for each channel.
14505 */
14506 shost->max_channel = 0;
14507 if (ASC_NARROW_BOARD(boardp)) {
14508 shost->max_id = ASC_MAX_TID + 1;
14509 shost->max_lun = ASC_MAX_LUN + 1;
f05ec594 14510 shost->max_cmd_len = ASC_MAX_CDB_LEN;
27c868c2
MW
14511
14512 shost->io_port = asc_dvc_varp->iop_base;
14513 boardp->asc_n_io_port = ASC_IOADR_GAP;
14514 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
14515
14516 /* Set maximum number of queues the adapter can handle. */
14517 shost->can_queue = asc_dvc_varp->max_total_qng;
14518 } else {
14519 shost->max_id = ADV_MAX_TID + 1;
14520 shost->max_lun = ADV_MAX_LUN + 1;
f05ec594 14521 shost->max_cmd_len = ADV_MAX_CDB_LEN;
27c868c2
MW
14522
14523 /*
14524 * Save the I/O Port address and length even though
14525 * I/O ports are not used to access Wide boards.
14526 * Instead the Wide boards are accessed with
14527 * PCI Memory Mapped I/O.
14528 */
14529 shost->io_port = iop;
27c868c2
MW
14530
14531 shost->this_id = adv_dvc_varp->chip_scsi_id;
14532
14533 /* Set maximum number of queues the adapter can handle. */
14534 shost->can_queue = adv_dvc_varp->max_host_qng;
14535 }
14536
27c868c2
MW
14537 /*
14538 * Following v1.3.89, 'cmd_per_lun' is no longer needed
14539 * and should be set to zero.
14540 *
14541 * But because of a bug introduced in v1.3.89 if the driver is
14542 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
14543 * SCSI function 'allocate_device' will panic. To allow the driver
14544 * to work as a module in these kernels set 'cmd_per_lun' to 1.
14545 *
14546 * Note: This is wrong. cmd_per_lun should be set to the depth
14547 * you want on untagged devices always.
14548 #ifdef MODULE
14549 */
14550 shost->cmd_per_lun = 1;
14551/* #else
14552 shost->cmd_per_lun = 0;
14553#endif */
14554
14555 /*
14556 * Set the maximum number of scatter-gather elements the
14557 * adapter can handle.
14558 */
14559 if (ASC_NARROW_BOARD(boardp)) {
14560 /*
14561 * Allow two commands with 'sg_tablesize' scatter-gather
14562 * elements to be executed simultaneously. This value is
14563 * the theoretical hardware limit. It may be decreased
14564 * below.
14565 */
14566 shost->sg_tablesize =
14567 (((asc_dvc_varp->max_total_qng - 2) / 2) *
14568 ASC_SG_LIST_PER_Q) + 1;
14569 } else {
14570 shost->sg_tablesize = ADV_MAX_SG_LIST;
14571 }
14572
14573 /*
14574 * The value of 'sg_tablesize' can not exceed the SCSI
14575 * mid-level driver definition of SG_ALL. SG_ALL also
14576 * must not be exceeded, because it is used to define the
14577 * size of the scatter-gather table in 'struct asc_sg_head'.
14578 */
14579 if (shost->sg_tablesize > SG_ALL) {
14580 shost->sg_tablesize = SG_ALL;
14581 }
14582
14583 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
14584
14585 /* BIOS start address. */
14586 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
14587 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
14588 asc_dvc_varp->bus_type);
27c868c2
MW
14589 } else {
14590 /*
14591 * Fill-in BIOS board variables. The Wide BIOS saves
14592 * information in LRAM that is used by the driver.
14593 */
14594 AdvReadWordLram(adv_dvc_varp->iop_base,
14595 BIOS_SIGNATURE, boardp->bios_signature);
14596 AdvReadWordLram(adv_dvc_varp->iop_base,
14597 BIOS_VERSION, boardp->bios_version);
14598 AdvReadWordLram(adv_dvc_varp->iop_base,
14599 BIOS_CODESEG, boardp->bios_codeseg);
14600 AdvReadWordLram(adv_dvc_varp->iop_base,
14601 BIOS_CODELEN, boardp->bios_codelen);
14602
14603 ASC_DBG2(1,
14604 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
14605 boardp->bios_signature, boardp->bios_version);
14606
14607 ASC_DBG2(1,
14608 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
14609 boardp->bios_codeseg, boardp->bios_codelen);
14610
14611 /*
14612 * If the BIOS saved a valid signature, then fill in
14613 * the BIOS code segment base address.
14614 */
14615 if (boardp->bios_signature == 0x55AA) {
14616 /*
14617 * Convert x86 realmode code segment to a linear
14618 * address by shifting left 4.
14619 */
14620 shost->base = ((ulong)boardp->bios_codeseg << 4);
14621 } else {
14622 shost->base = 0;
14623 }
14624 }
14625
14626 /*
14627 * Register Board Resources - I/O Port, DMA, IRQ
14628 */
14629
27c868c2
MW
14630 /* Register DMA Channel for Narrow boards. */
14631 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
14632#ifdef CONFIG_ISA
14633 if (ASC_NARROW_BOARD(boardp)) {
14634 /* Register DMA channel for ISA bus. */
14635 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
14636 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
b2c16f58
MW
14637 ret = request_dma(shost->dma_channel, "advansys");
14638 if (ret) {
27c868c2
MW
14639 ASC_PRINT3
14640 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
14641 boardp->id, shost->dma_channel, ret);
71f36115 14642 goto err_free_proc;
27c868c2
MW
14643 }
14644 AscEnableIsaDma(shost->dma_channel);
14645 }
14646 }
14647#endif /* CONFIG_ISA */
14648
14649 /* Register IRQ Number. */
14650 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
14651
14652 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
14653 "advansys", shost);
14654
14655 if (ret) {
27c868c2
MW
14656 if (ret == -EBUSY) {
14657 ASC_PRINT2
14658 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14659 boardp->id, shost->irq);
14660 } else if (ret == -EINVAL) {
14661 ASC_PRINT2
14662 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14663 boardp->id, shost->irq);
14664 } else {
14665 ASC_PRINT3
14666 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14667 boardp->id, shost->irq, ret);
14668 }
b2c16f58 14669 goto err_free_dma;
27c868c2
MW
14670 }
14671
14672 /*
14673 * Initialize board RISC chip and enable interrupts.
14674 */
14675 if (ASC_NARROW_BOARD(boardp)) {
14676 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
14677 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14678 err_code = asc_dvc_varp->err_code;
14679
14680 if (warn_code || err_code) {
14681 ASC_PRINT4
14682 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
14683 boardp->id,
14684 asc_dvc_varp->init_state, warn_code, err_code);
14685 }
14686 } else {
b2c16f58 14687 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
14688 }
14689
b2c16f58
MW
14690 if (err_code != 0)
14691 goto err_free_wide_mem;
14692
27c868c2
MW
14693 ASC_DBG_PRT_SCSI_HOST(2, shost);
14694
8dfb5379
MW
14695 ret = scsi_add_host(shost, dev);
14696 if (ret)
14697 goto err_free_wide_mem;
14698
14699 scsi_scan_host(shost);
27c868c2 14700 return shost;
b2c16f58
MW
14701
14702 err_free_wide_mem:
14703 advansys_wide_free_mem(boardp);
14704 free_irq(shost->irq, shost);
14705 err_free_dma:
14706 if (shost->dma_channel != NO_ISA_DMA)
14707 free_dma(shost->dma_channel);
b2c16f58
MW
14708 err_free_proc:
14709 kfree(boardp->prtbuf);
14710 err_unmap:
14711 if (boardp->ioremap_addr)
14712 iounmap(boardp->ioremap_addr);
14713 err_shost:
8dfb5379 14714 scsi_host_put(shost);
b2c16f58 14715 return NULL;
27c868c2
MW
14716}
14717
27c868c2
MW
14718/*
14719 * advansys_release()
14720 *
14721 * Release resources allocated for a single AdvanSys adapter.
14722 */
14723static int advansys_release(struct Scsi_Host *shost)
14724{
14725 asc_board_t *boardp;
14726
14727 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 14728 scsi_remove_host(shost);
27c868c2 14729 boardp = ASC_BOARDP(shost);
074c8fe4 14730 free_irq(shost->irq, shost);
27c868c2
MW
14731 if (shost->dma_channel != NO_ISA_DMA) {
14732 ASC_DBG(1, "advansys_release: free_dma()\n");
14733 free_dma(shost->dma_channel);
14734 }
27c868c2 14735 if (ASC_WIDE_BOARD(boardp)) {
27c868c2 14736 iounmap(boardp->ioremap_addr);
b2c16f58 14737 advansys_wide_free_mem(boardp);
27c868c2 14738 }
27c868c2 14739 kfree(boardp->prtbuf);
8dfb5379 14740 scsi_host_put(shost);
27c868c2
MW
14741 ASC_DBG(1, "advansys_release: end\n");
14742 return 0;
14743}
14744
95c9f162
MW
14745#define ASC_IOADR_TABLE_MAX_IX 11
14746
c304ec94
MW
14747static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14748 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14749 0x0210, 0x0230, 0x0250, 0x0330
14750};
14751
14752static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14753{
14754 PortAddr iop_base = _asc_def_iop_base[id];
14755 struct Scsi_Host *shost;
14756
14757 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
14758 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
14759 iop_base);
c304ec94
MW
14760 return -ENODEV;
14761 }
14762 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
14763 if (!AscFindSignature(iop_base))
14764 goto nodev;
14765 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14766 goto nodev;
14767
14768 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
c304ec94
MW
14769 if (!shost)
14770 goto nodev;
14771
14772 dev_set_drvdata(dev, shost);
14773 return 0;
14774
14775 nodev:
71f36115 14776 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
14777 return -ENODEV;
14778}
14779
14780static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14781{
71f36115 14782 int ioport = _asc_def_iop_base[id];
c304ec94 14783 advansys_release(dev_get_drvdata(dev));
71f36115 14784 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
14785 return 0;
14786}
14787
14788static struct isa_driver advansys_isa_driver = {
14789 .probe = advansys_isa_probe,
14790 .remove = __devexit_p(advansys_isa_remove),
14791 .driver = {
14792 .owner = THIS_MODULE,
14793 .name = "advansys",
14794 },
14795};
14796
14797static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14798{
14799 PortAddr iop_base = _asc_def_iop_base[id];
14800 struct Scsi_Host *shost;
14801
14802 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
14803 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
14804 iop_base);
c304ec94
MW
14805 return -ENODEV;
14806 }
14807 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
14808 if (!AscFindSignature(iop_base))
14809 goto nodev;
14810 /*
14811 * I don't think this condition can actually happen, but the old
14812 * driver did it, and the chances of finding a VLB setup in 2007
14813 * to do testing with is slight to none.
14814 */
14815 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14816 goto nodev;
14817
14818 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
c304ec94
MW
14819 if (!shost)
14820 goto nodev;
14821
14822 dev_set_drvdata(dev, shost);
14823 return 0;
14824
14825 nodev:
71f36115 14826 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
14827 return -ENODEV;
14828}
14829
14830static struct isa_driver advansys_vlb_driver = {
14831 .probe = advansys_vlb_probe,
14832 .remove = __devexit_p(advansys_isa_remove),
14833 .driver = {
14834 .owner = THIS_MODULE,
b8e5152b 14835 .name = "advansys_vlb",
c304ec94
MW
14836 },
14837};
14838
b09e05a7
MW
14839static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14840 { "ABP7401" },
14841 { "ABP7501" },
14842 { "" }
14843};
14844
14845MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14846
14847/*
14848 * EISA is a little more tricky than PCI; each EISA device may have two
14849 * channels, and this driver is written to make each channel its own Scsi_Host
14850 */
14851struct eisa_scsi_data {
14852 struct Scsi_Host *host[2];
14853};
14854
14855static int __devinit advansys_eisa_probe(struct device *dev)
14856{
14857 int i, ioport;
14858 int err;
14859 struct eisa_device *edev = to_eisa_device(dev);
14860 struct eisa_scsi_data *data;
14861
14862 err = -ENOMEM;
14863 data = kzalloc(sizeof(*data), GFP_KERNEL);
14864 if (!data)
14865 goto fail;
14866 ioport = edev->base_addr + 0xc30;
14867
14868 err = -ENODEV;
14869 for (i = 0; i < 2; i++, ioport += 0x20) {
71f36115
MW
14870 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
14871 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14872 ioport + ASC_IOADR_GAP - 1);
14873 continue;
14874 }
14875 if (!AscFindSignature(ioport)) {
14876 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 14877 continue;
71f36115
MW
14878 }
14879
b09e05a7
MW
14880 /*
14881 * I don't know why we need to do this for EISA chips, but
14882 * not for any others. It looks to be equivalent to
14883 * AscGetChipCfgMsw, but I may have overlooked something,
14884 * so I'm not converting it until I get an EISA board to
14885 * test with.
14886 */
14887 inw(ioport + 4);
14888 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
71f36115 14889 if (data->host[i]) {
b09e05a7 14890 err = 0;
71f36115
MW
14891 } else {
14892 release_region(ioport, ASC_IOADR_GAP);
14893 }
b09e05a7
MW
14894 }
14895
14896 if (err) {
14897 kfree(data);
14898 } else {
14899 dev_set_drvdata(dev, data);
14900 }
14901
14902 fail:
14903 return err;
14904}
14905
14906static __devexit int advansys_eisa_remove(struct device *dev)
14907{
14908 int i;
14909 struct eisa_scsi_data *data = dev_get_drvdata(dev);
14910
14911 for (i = 0; i < 2; i++) {
71f36115 14912 int ioport;
b09e05a7
MW
14913 struct Scsi_Host *shost = data->host[i];
14914 if (!shost)
14915 continue;
71f36115 14916 ioport = shost->io_port;
b09e05a7 14917 advansys_release(shost);
71f36115 14918 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
14919 }
14920
14921 kfree(data);
14922 return 0;
14923}
14924
14925static struct eisa_driver advansys_eisa_driver = {
14926 .id_table = advansys_eisa_table,
14927 .driver = {
14928 .name = "advansys",
14929 .probe = advansys_eisa_probe,
14930 .remove = __devexit_p(advansys_eisa_remove),
14931 }
14932};
14933
2672ea86
DJ
14934/* PCI Devices supported by this driver */
14935static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
14936 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14937 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14938 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14939 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14940 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14941 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14942 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14943 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14944 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14945 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14946 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14947 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14948 {}
2672ea86 14949};
27c868c2 14950
2672ea86 14951MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b 14952
9649af39
MW
14953static void __devinit advansys_set_latency(struct pci_dev *pdev)
14954{
14955 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14956 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14957 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14958 } else {
14959 u8 latency;
14960 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14961 if (latency < 0x20)
14962 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14963 }
14964}
14965
78e77d8b
MW
14966static int __devinit
14967advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14968{
14969 int err, ioport;
14970 struct Scsi_Host *shost;
14971
14972 err = pci_enable_device(pdev);
14973 if (err)
14974 goto fail;
71f36115
MW
14975 err = pci_request_regions(pdev, "advansys");
14976 if (err)
14977 goto disable_device;
9649af39
MW
14978 pci_set_master(pdev);
14979 advansys_set_latency(pdev);
78e77d8b
MW
14980
14981 if (pci_resource_len(pdev, 0) == 0)
14982 goto nodev;
14983
14984 ioport = pci_resource_start(pdev, 0);
14985 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
14986
14987 if (!shost)
14988 goto nodev;
14989
14990 pci_set_drvdata(pdev, shost);
14991 return 0;
14992
14993 nodev:
14994 err = -ENODEV;
71f36115
MW
14995 pci_release_regions(pdev);
14996 disable_device:
78e77d8b
MW
14997 pci_disable_device(pdev);
14998 fail:
14999 return err;
15000}
15001
15002static void __devexit advansys_pci_remove(struct pci_dev *pdev)
15003{
15004 advansys_release(pci_get_drvdata(pdev));
71f36115 15005 pci_release_regions(pdev);
78e77d8b
MW
15006 pci_disable_device(pdev);
15007}
15008
15009static struct pci_driver advansys_pci_driver = {
15010 .name = "advansys",
15011 .id_table = advansys_pci_tbl,
15012 .probe = advansys_pci_probe,
15013 .remove = __devexit_p(advansys_pci_remove),
15014};
8c6af9e1 15015
8dfb5379
MW
15016static int __init advansys_init(void)
15017{
c304ec94 15018 int error;
b09e05a7 15019
c304ec94
MW
15020 error = isa_register_driver(&advansys_isa_driver,
15021 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
15022 if (error)
15023 goto fail;
8dfb5379 15024
c304ec94
MW
15025 error = isa_register_driver(&advansys_vlb_driver,
15026 ASC_IOADR_TABLE_MAX_IX);
15027 if (error)
15028 goto unregister_isa;
15029
15030 error = eisa_driver_register(&advansys_eisa_driver);
15031 if (error)
15032 goto unregister_vlb;
15033
b09e05a7
MW
15034 error = pci_register_driver(&advansys_pci_driver);
15035 if (error)
15036 goto unregister_eisa;
15037
8dfb5379 15038 return 0;
78e77d8b 15039
b09e05a7
MW
15040 unregister_eisa:
15041 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15042 unregister_vlb:
15043 isa_unregister_driver(&advansys_vlb_driver);
15044 unregister_isa:
15045 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 15046 fail:
78e77d8b 15047 return error;
8dfb5379
MW
15048}
15049
15050static void __exit advansys_exit(void)
15051{
78e77d8b 15052 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 15053 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15054 isa_unregister_driver(&advansys_vlb_driver);
15055 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
15056}
15057
15058module_init(advansys_init);
15059module_exit(advansys_exit);
15060
8c6af9e1 15061MODULE_LICENSE("GPL");
This page took 1.000763 seconds and 5 git commands to generate.