[SCSI] advansys: Remove a check for an impossible condition
[linux-2.6-block.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
66 * 6. Remove internal queueing
67 * 7. Use scsi_transport_spi
68 * 8. advansys_info is not safe against multiple simultaneous callers
69 * 9. Kill boardp->id
70 * 10. Add module_param to override ISA/VLB ioport array
1da177e4
LT
71 */
72#warning this driver is still not properly converted to the DMA API
73
1da177e4
LT
74/* Enable driver assertions. */
75#define ADVANSYS_ASSERT
76
77/* Enable driver /proc statistics. */
78#define ADVANSYS_STATS
79
80/* Enable driver tracing. */
81/* #define ADVANSYS_DEBUG */
82
1da177e4
LT
83/*
84 * --- Asc Library Constants and Macros
85 */
86
87#define ASC_LIB_VERSION_MAJOR 1
88#define ASC_LIB_VERSION_MINOR 24
89#define ASC_LIB_SERIAL_NUMBER 123
90
91/*
92 * Portable Data Types
93 *
94 * Any instance where a 32-bit long or pointer type is assumed
95 * for precision or HW defined structures, the following define
96 * types must be used. In Linux the char, short, and int types
97 * are all consistent at 8, 16, and 32 bits respectively. Pointers
98 * and long types are 64 bits on Alpha and UltraSPARC.
99 */
27c868c2
MW
100#define ASC_PADDR __u32 /* Physical/Bus address data type. */
101#define ASC_VADDR __u32 /* Virtual address data type. */
102#define ASC_DCNT __u32 /* Unsigned Data count type. */
103#define ASC_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
104
105/*
106 * These macros are used to convert a virtual address to a
107 * 32-bit value. This currently can be used on Linux Alpha
108 * which uses 64-bit virtual address but a 32-bit bus address.
109 * This is likely to break in the future, but doing this now
110 * will give us time to change the HW and FW to handle 64-bit
111 * addresses.
112 */
113#define ASC_VADDR_TO_U32 virt_to_bus
114#define ASC_U32_TO_VADDR bus_to_virt
115
116typedef unsigned char uchar;
117
118#ifndef TRUE
119#define TRUE (1)
120#endif
121#ifndef FALSE
122#define FALSE (0)
123#endif
124
125#define EOF (-1)
126#define ERR (-1)
127#define UW_ERR (uint)(0xFFFF)
128#define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
1da177e4
LT
129
130#define ASC_DVCLIB_CALL_DONE (1)
131#define ASC_DVCLIB_CALL_FAILED (0)
132#define ASC_DVCLIB_CALL_ERROR (-1)
133
2672ea86
DJ
134#define PCI_VENDOR_ID_ASP 0x10cd
135#define PCI_DEVICE_ID_ASP_1200A 0x1100
136#define PCI_DEVICE_ID_ASP_ABP940 0x1200
137#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
138#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
139#define PCI_DEVICE_ID_38C0800_REV1 0x2500
140#define PCI_DEVICE_ID_38C1600_REV1 0x2700
141
1da177e4
LT
142/*
143 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
144 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
145 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
146 * SRB structure.
147 */
148#define CC_VERY_LONG_SG_LIST 0
149#define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
150
27c868c2 151#define PortAddr unsigned short /* port address size */
1da177e4
LT
152#define inp(port) inb(port)
153#define outp(port, byte) outb((byte), (port))
154
155#define inpw(port) inw(port)
156#define outpw(port, word) outw((word), (port))
157
158#define ASC_MAX_SG_QUEUE 7
159#define ASC_MAX_SG_LIST 255
160
161#define ASC_CS_TYPE unsigned short
162
163#define ASC_IS_ISA (0x0001)
164#define ASC_IS_ISAPNP (0x0081)
165#define ASC_IS_EISA (0x0002)
166#define ASC_IS_PCI (0x0004)
167#define ASC_IS_PCI_ULTRA (0x0104)
168#define ASC_IS_PCMCIA (0x0008)
169#define ASC_IS_MCA (0x0020)
170#define ASC_IS_VL (0x0040)
171#define ASC_ISA_PNP_PORT_ADDR (0x279)
172#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
173#define ASC_IS_WIDESCSI_16 (0x0100)
174#define ASC_IS_WIDESCSI_32 (0x0200)
175#define ASC_IS_BIG_ENDIAN (0x8000)
176#define ASC_CHIP_MIN_VER_VL (0x01)
177#define ASC_CHIP_MAX_VER_VL (0x07)
178#define ASC_CHIP_MIN_VER_PCI (0x09)
179#define ASC_CHIP_MAX_VER_PCI (0x0F)
180#define ASC_CHIP_VER_PCI_BIT (0x08)
181#define ASC_CHIP_MIN_VER_ISA (0x11)
182#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
183#define ASC_CHIP_MAX_VER_ISA (0x27)
184#define ASC_CHIP_VER_ISA_BIT (0x30)
185#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
186#define ASC_CHIP_VER_ASYN_BUG (0x21)
187#define ASC_CHIP_VER_PCI 0x08
188#define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
189#define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
190#define ASC_CHIP_MIN_VER_EISA (0x41)
191#define ASC_CHIP_MAX_VER_EISA (0x47)
192#define ASC_CHIP_VER_EISA_BIT (0x40)
193#define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
194#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
195#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
196#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
197#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
198#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
199#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
200#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
201#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
202#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
203#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
204
205#define ASC_SCSI_ID_BITS 3
206#define ASC_SCSI_TIX_TYPE uchar
207#define ASC_ALL_DEVICE_BIT_SET 0xFF
208#define ASC_SCSI_BIT_ID_TYPE uchar
209#define ASC_MAX_TID 7
210#define ASC_MAX_LUN 7
211#define ASC_SCSI_WIDTH_BIT_SET 0xFF
212#define ASC_MAX_SENSE_LEN 32
213#define ASC_MIN_SENSE_LEN 14
214#define ASC_MAX_CDB_LEN 12
215#define ASC_SCSI_RESET_HOLD_TIME_US 60
216
1da177e4
LT
217/*
218 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
219 * and CmdDt (Command Support Data) field bit definitions.
220 */
221#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
222#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
223#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
224#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
225
226#define ASC_SCSIDIR_NOCHK 0x00
227#define ASC_SCSIDIR_T2H 0x08
228#define ASC_SCSIDIR_H2T 0x10
229#define ASC_SCSIDIR_NODATA 0x18
230#define SCSI_ASC_NOMEDIA 0x3A
231#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
232#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
233#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
234#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1da177e4 235#define MS_SDTR_LEN 0x03
1da177e4 236#define MS_WDTR_LEN 0x02
1da177e4
LT
237
238#define ASC_SG_LIST_PER_Q 7
239#define QS_FREE 0x00
240#define QS_READY 0x01
241#define QS_DISC1 0x02
242#define QS_DISC2 0x04
243#define QS_BUSY 0x08
244#define QS_ABORTED 0x40
245#define QS_DONE 0x80
246#define QC_NO_CALLBACK 0x01
247#define QC_SG_SWAP_QUEUE 0x02
248#define QC_SG_HEAD 0x04
249#define QC_DATA_IN 0x08
250#define QC_DATA_OUT 0x10
251#define QC_URGENT 0x20
252#define QC_MSG_OUT 0x40
253#define QC_REQ_SENSE 0x80
254#define QCSG_SG_XFER_LIST 0x02
255#define QCSG_SG_XFER_MORE 0x04
256#define QCSG_SG_XFER_END 0x08
257#define QD_IN_PROGRESS 0x00
258#define QD_NO_ERROR 0x01
259#define QD_ABORTED_BY_HOST 0x02
260#define QD_WITH_ERROR 0x04
261#define QD_INVALID_REQUEST 0x80
262#define QD_INVALID_HOST_NUM 0x81
263#define QD_INVALID_DEVICE 0x82
264#define QD_ERR_INTERNAL 0xFF
265#define QHSTA_NO_ERROR 0x00
266#define QHSTA_M_SEL_TIMEOUT 0x11
267#define QHSTA_M_DATA_OVER_RUN 0x12
268#define QHSTA_M_DATA_UNDER_RUN 0x12
269#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
270#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
271#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
272#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
273#define QHSTA_D_HOST_ABORT_FAILED 0x23
274#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
275#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
276#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
277#define QHSTA_M_WTM_TIMEOUT 0x41
278#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
279#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
280#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
281#define QHSTA_M_TARGET_STATUS_BUSY 0x45
282#define QHSTA_M_BAD_TAG_CODE 0x46
283#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
284#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
285#define QHSTA_D_LRAM_CMP_ERROR 0x81
286#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
287#define ASC_FLAG_SCSIQ_REQ 0x01
288#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
289#define ASC_FLAG_BIOS_ASYNC_IO 0x04
290#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
291#define ASC_FLAG_WIN16 0x10
292#define ASC_FLAG_WIN32 0x20
293#define ASC_FLAG_ISA_OVER_16MB 0x40
294#define ASC_FLAG_DOS_VM_CALLBACK 0x80
295#define ASC_TAG_FLAG_EXTRA_BYTES 0x10
296#define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
297#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
298#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
299#define ASC_SCSIQ_CPY_BEG 4
300#define ASC_SCSIQ_SGHD_CPY_BEG 2
301#define ASC_SCSIQ_B_FWD 0
302#define ASC_SCSIQ_B_BWD 1
303#define ASC_SCSIQ_B_STATUS 2
304#define ASC_SCSIQ_B_QNO 3
305#define ASC_SCSIQ_B_CNTL 4
306#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
307#define ASC_SCSIQ_D_DATA_ADDR 8
308#define ASC_SCSIQ_D_DATA_CNT 12
309#define ASC_SCSIQ_B_SENSE_LEN 20
310#define ASC_SCSIQ_DONE_INFO_BEG 22
311#define ASC_SCSIQ_D_SRBPTR 22
312#define ASC_SCSIQ_B_TARGET_IX 26
313#define ASC_SCSIQ_B_CDB_LEN 28
314#define ASC_SCSIQ_B_TAG_CODE 29
315#define ASC_SCSIQ_W_VM_ID 30
316#define ASC_SCSIQ_DONE_STATUS 32
317#define ASC_SCSIQ_HOST_STATUS 33
318#define ASC_SCSIQ_SCSI_STATUS 34
319#define ASC_SCSIQ_CDB_BEG 36
320#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
321#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
322#define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
323#define ASC_SCSIQ_B_SG_WK_QP 49
324#define ASC_SCSIQ_B_SG_WK_IX 50
325#define ASC_SCSIQ_W_ALT_DC1 52
326#define ASC_SCSIQ_B_LIST_CNT 6
327#define ASC_SCSIQ_B_CUR_LIST_CNT 7
328#define ASC_SGQ_B_SG_CNTL 4
329#define ASC_SGQ_B_SG_HEAD_QP 5
330#define ASC_SGQ_B_SG_LIST_CNT 6
331#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
332#define ASC_SGQ_LIST_BEG 8
333#define ASC_DEF_SCSI1_QNG 4
334#define ASC_MAX_SCSI1_QNG 4
335#define ASC_DEF_SCSI2_QNG 16
336#define ASC_MAX_SCSI2_QNG 32
337#define ASC_TAG_CODE_MASK 0x23
338#define ASC_STOP_REQ_RISC_STOP 0x01
339#define ASC_STOP_ACK_RISC_STOP 0x03
340#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
341#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
342#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
343#define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
344#define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
345#define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
346#define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
347#define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
348#define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
349#define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
350
351typedef struct asc_scsiq_1 {
27c868c2
MW
352 uchar status;
353 uchar q_no;
354 uchar cntl;
355 uchar sg_queue_cnt;
356 uchar target_id;
357 uchar target_lun;
358 ASC_PADDR data_addr;
359 ASC_DCNT data_cnt;
360 ASC_PADDR sense_addr;
361 uchar sense_len;
362 uchar extra_bytes;
1da177e4
LT
363} ASC_SCSIQ_1;
364
365typedef struct asc_scsiq_2 {
27c868c2
MW
366 ASC_VADDR srb_ptr;
367 uchar target_ix;
368 uchar flag;
369 uchar cdb_len;
370 uchar tag_code;
371 ushort vm_id;
1da177e4
LT
372} ASC_SCSIQ_2;
373
374typedef struct asc_scsiq_3 {
27c868c2
MW
375 uchar done_stat;
376 uchar host_stat;
377 uchar scsi_stat;
378 uchar scsi_msg;
1da177e4
LT
379} ASC_SCSIQ_3;
380
381typedef struct asc_scsiq_4 {
27c868c2
MW
382 uchar cdb[ASC_MAX_CDB_LEN];
383 uchar y_first_sg_list_qp;
384 uchar y_working_sg_qp;
385 uchar y_working_sg_ix;
386 uchar y_res;
387 ushort x_req_count;
388 ushort x_reconnect_rtn;
389 ASC_PADDR x_saved_data_addr;
390 ASC_DCNT x_saved_data_cnt;
1da177e4
LT
391} ASC_SCSIQ_4;
392
393typedef struct asc_q_done_info {
27c868c2
MW
394 ASC_SCSIQ_2 d2;
395 ASC_SCSIQ_3 d3;
396 uchar q_status;
397 uchar q_no;
398 uchar cntl;
399 uchar sense_len;
400 uchar extra_bytes;
401 uchar res;
402 ASC_DCNT remain_bytes;
1da177e4
LT
403} ASC_QDONE_INFO;
404
405typedef struct asc_sg_list {
27c868c2
MW
406 ASC_PADDR addr;
407 ASC_DCNT bytes;
1da177e4
LT
408} ASC_SG_LIST;
409
410typedef struct asc_sg_head {
27c868c2
MW
411 ushort entry_cnt;
412 ushort queue_cnt;
413 ushort entry_to_copy;
414 ushort res;
415 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1da177e4
LT
416} ASC_SG_HEAD;
417
418#define ASC_MIN_SG_LIST 2
419
420typedef struct asc_min_sg_head {
27c868c2
MW
421 ushort entry_cnt;
422 ushort queue_cnt;
423 ushort entry_to_copy;
424 ushort res;
425 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1da177e4
LT
426} ASC_MIN_SG_HEAD;
427
428#define QCX_SORT (0x0001)
429#define QCX_COALEASE (0x0002)
430
431typedef struct asc_scsi_q {
27c868c2
MW
432 ASC_SCSIQ_1 q1;
433 ASC_SCSIQ_2 q2;
434 uchar *cdbptr;
435 ASC_SG_HEAD *sg_head;
436 ushort remain_sg_entry_cnt;
437 ushort next_sg_index;
1da177e4
LT
438} ASC_SCSI_Q;
439
440typedef struct asc_scsi_req_q {
27c868c2
MW
441 ASC_SCSIQ_1 r1;
442 ASC_SCSIQ_2 r2;
443 uchar *cdbptr;
444 ASC_SG_HEAD *sg_head;
445 uchar *sense_ptr;
446 ASC_SCSIQ_3 r3;
447 uchar cdb[ASC_MAX_CDB_LEN];
448 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
449} ASC_SCSI_REQ_Q;
450
451typedef struct asc_scsi_bios_req_q {
27c868c2
MW
452 ASC_SCSIQ_1 r1;
453 ASC_SCSIQ_2 r2;
454 uchar *cdbptr;
455 ASC_SG_HEAD *sg_head;
456 uchar *sense_ptr;
457 ASC_SCSIQ_3 r3;
458 uchar cdb[ASC_MAX_CDB_LEN];
459 uchar sense[ASC_MIN_SENSE_LEN];
1da177e4
LT
460} ASC_SCSI_BIOS_REQ_Q;
461
462typedef struct asc_risc_q {
27c868c2
MW
463 uchar fwd;
464 uchar bwd;
465 ASC_SCSIQ_1 i1;
466 ASC_SCSIQ_2 i2;
467 ASC_SCSIQ_3 i3;
468 ASC_SCSIQ_4 i4;
1da177e4
LT
469} ASC_RISC_Q;
470
471typedef struct asc_sg_list_q {
27c868c2
MW
472 uchar seq_no;
473 uchar q_no;
474 uchar cntl;
475 uchar sg_head_qp;
476 uchar sg_list_cnt;
477 uchar sg_cur_list_cnt;
1da177e4
LT
478} ASC_SG_LIST_Q;
479
480typedef struct asc_risc_sg_list_q {
27c868c2
MW
481 uchar fwd;
482 uchar bwd;
483 ASC_SG_LIST_Q sg;
484 ASC_SG_LIST sg_list[7];
1da177e4
LT
485} ASC_RISC_SG_LIST_Q;
486
487#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
488#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
489#define ASCQ_ERR_NO_ERROR 0
490#define ASCQ_ERR_IO_NOT_FOUND 1
491#define ASCQ_ERR_LOCAL_MEM 2
492#define ASCQ_ERR_CHKSUM 3
493#define ASCQ_ERR_START_CHIP 4
494#define ASCQ_ERR_INT_TARGET_ID 5
495#define ASCQ_ERR_INT_LOCAL_MEM 6
496#define ASCQ_ERR_HALT_RISC 7
497#define ASCQ_ERR_GET_ASPI_ENTRY 8
498#define ASCQ_ERR_CLOSE_ASPI 9
499#define ASCQ_ERR_HOST_INQUIRY 0x0A
500#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
501#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
502#define ASCQ_ERR_Q_STATUS 0x0D
503#define ASCQ_ERR_WR_SCSIQ 0x0E
504#define ASCQ_ERR_PC_ADDR 0x0F
505#define ASCQ_ERR_SYN_OFFSET 0x10
506#define ASCQ_ERR_SYN_XFER_TIME 0x11
507#define ASCQ_ERR_LOCK_DMA 0x12
508#define ASCQ_ERR_UNLOCK_DMA 0x13
509#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
510#define ASCQ_ERR_MICRO_CODE_HALT 0x15
511#define ASCQ_ERR_SET_LRAM_ADDR 0x16
512#define ASCQ_ERR_CUR_QNG 0x17
513#define ASCQ_ERR_SG_Q_LINKS 0x18
514#define ASCQ_ERR_SCSIQ_PTR 0x19
515#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
516#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
517#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
518#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
519#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
520#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
521#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
522#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
523#define ASCQ_ERR_SEND_SCSI_Q 0x22
524#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
525#define ASCQ_ERR_RESET_SDTR 0x24
526
527/*
528 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
529 */
530#define ASC_WARN_NO_ERROR 0x0000
531#define ASC_WARN_IO_PORT_ROTATE 0x0001
532#define ASC_WARN_EEPROM_CHKSUM 0x0002
533#define ASC_WARN_IRQ_MODIFIED 0x0004
534#define ASC_WARN_AUTO_CONFIG 0x0008
535#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
536#define ASC_WARN_EEPROM_RECOVER 0x0020
537#define ASC_WARN_CFG_MSW_RECOVER 0x0040
538#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
539
540/*
541 * Error code values are set in ASC_DVC_VAR 'err_code'.
542 */
543#define ASC_IERR_WRITE_EEPROM 0x0001
544#define ASC_IERR_MCODE_CHKSUM 0x0002
545#define ASC_IERR_SET_PC_ADDR 0x0004
546#define ASC_IERR_START_STOP_CHIP 0x0008
547#define ASC_IERR_IRQ_NO 0x0010
548#define ASC_IERR_SET_IRQ_NO 0x0020
549#define ASC_IERR_CHIP_VERSION 0x0040
550#define ASC_IERR_SET_SCSI_ID 0x0080
551#define ASC_IERR_GET_PHY_ADDR 0x0100
552#define ASC_IERR_BAD_SIGNATURE 0x0200
553#define ASC_IERR_NO_BUS_TYPE 0x0400
554#define ASC_IERR_SCAM 0x0800
555#define ASC_IERR_SET_SDTR 0x1000
556#define ASC_IERR_RW_LRAM 0x8000
557
558#define ASC_DEF_IRQ_NO 10
559#define ASC_MAX_IRQ_NO 15
560#define ASC_MIN_IRQ_NO 10
561#define ASC_MIN_REMAIN_Q (0x02)
562#define ASC_DEF_MAX_TOTAL_QNG (0xF0)
563#define ASC_MIN_TAG_Q_PER_DVC (0x04)
564#define ASC_DEF_TAG_Q_PER_DVC (0x04)
565#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
566#define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
567#define ASC_MAX_TOTAL_QNG 240
568#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
569#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
570#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
571#define ASC_MAX_INRAM_TAG_QNG 16
572#define ASC_IOADR_TABLE_MAX_IX 11
573#define ASC_IOADR_GAP 0x10
1da177e4
LT
574#define ASC_LIB_SCSIQ_WK_SP 256
575#define ASC_MAX_SYN_XFER_NO 16
576#define ASC_SYN_MAX_OFFSET 0x0F
577#define ASC_DEF_SDTR_OFFSET 0x0F
578#define ASC_DEF_SDTR_INDEX 0x00
579#define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
580#define SYN_XFER_NS_0 25
581#define SYN_XFER_NS_1 30
582#define SYN_XFER_NS_2 35
583#define SYN_XFER_NS_3 40
584#define SYN_XFER_NS_4 50
585#define SYN_XFER_NS_5 60
586#define SYN_XFER_NS_6 70
587#define SYN_XFER_NS_7 85
588#define SYN_ULTRA_XFER_NS_0 12
589#define SYN_ULTRA_XFER_NS_1 19
590#define SYN_ULTRA_XFER_NS_2 25
591#define SYN_ULTRA_XFER_NS_3 32
592#define SYN_ULTRA_XFER_NS_4 38
593#define SYN_ULTRA_XFER_NS_5 44
594#define SYN_ULTRA_XFER_NS_6 50
595#define SYN_ULTRA_XFER_NS_7 57
596#define SYN_ULTRA_XFER_NS_8 63
597#define SYN_ULTRA_XFER_NS_9 69
598#define SYN_ULTRA_XFER_NS_10 75
599#define SYN_ULTRA_XFER_NS_11 82
600#define SYN_ULTRA_XFER_NS_12 88
601#define SYN_ULTRA_XFER_NS_13 94
602#define SYN_ULTRA_XFER_NS_14 100
603#define SYN_ULTRA_XFER_NS_15 107
604
605typedef struct ext_msg {
27c868c2
MW
606 uchar msg_type;
607 uchar msg_len;
608 uchar msg_req;
609 union {
610 struct {
611 uchar sdtr_xfer_period;
612 uchar sdtr_req_ack_offset;
613 } sdtr;
614 struct {
615 uchar wdtr_width;
616 } wdtr;
617 struct {
618 uchar mdp_b3;
619 uchar mdp_b2;
620 uchar mdp_b1;
621 uchar mdp_b0;
622 } mdp;
623 } u_ext_msg;
624 uchar res;
1da177e4
LT
625} EXT_MSG;
626
627#define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
628#define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
629#define wdtr_width u_ext_msg.wdtr.wdtr_width
630#define mdp_b3 u_ext_msg.mdp_b3
631#define mdp_b2 u_ext_msg.mdp_b2
632#define mdp_b1 u_ext_msg.mdp_b1
633#define mdp_b0 u_ext_msg.mdp_b0
634
635typedef struct asc_dvc_cfg {
27c868c2
MW
636 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
637 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
638 ASC_SCSI_BIT_ID_TYPE disc_enable;
639 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
640 uchar chip_scsi_id;
641 uchar isa_dma_speed;
642 uchar isa_dma_channel;
643 uchar chip_version;
644 ushort lib_serial_no;
645 ushort lib_version;
646 ushort mcode_date;
647 ushort mcode_version;
648 uchar max_tag_qng[ASC_MAX_TID + 1];
649 uchar *overrun_buf;
650 uchar sdtr_period_offset[ASC_MAX_TID + 1];
27c868c2 651 uchar adapter_info[6];
1da177e4
LT
652} ASC_DVC_CFG;
653
654#define ASC_DEF_DVC_CNTL 0xFFFF
655#define ASC_DEF_CHIP_SCSI_ID 7
656#define ASC_DEF_ISA_DMA_SPEED 4
657#define ASC_INIT_STATE_NULL 0x0000
658#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
659#define ASC_INIT_STATE_END_GET_CFG 0x0002
660#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
661#define ASC_INIT_STATE_END_SET_CFG 0x0008
662#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
663#define ASC_INIT_STATE_END_LOAD_MC 0x0020
664#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
665#define ASC_INIT_STATE_END_INQUIRY 0x0080
666#define ASC_INIT_RESET_SCSI_DONE 0x0100
667#define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1da177e4
LT
668#define ASC_BUG_FIX_IF_NOT_DWB 0x0001
669#define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
670#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
671#define ASC_MIN_TAGGED_CMD 7
672#define ASC_MAX_SCSI_RESET_WAIT 30
673
27c868c2 674struct asc_dvc_var; /* Forward Declaration. */
1da177e4 675
1da177e4 676typedef struct asc_dvc_var {
27c868c2
MW
677 PortAddr iop_base;
678 ushort err_code;
679 ushort dvc_cntl;
680 ushort bug_fix_cntl;
681 ushort bus_type;
27c868c2
MW
682 ASC_SCSI_BIT_ID_TYPE init_sdtr;
683 ASC_SCSI_BIT_ID_TYPE sdtr_done;
684 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
685 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
686 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
687 ASC_SCSI_BIT_ID_TYPE start_motor;
688 uchar scsi_reset_wait;
689 uchar chip_no;
690 char is_in_int;
691 uchar max_total_qng;
692 uchar cur_total_qng;
693 uchar in_critical_cnt;
694 uchar irq_no;
695 uchar last_q_shortage;
696 ushort init_state;
697 uchar cur_dvc_qng[ASC_MAX_TID + 1];
698 uchar max_dvc_qng[ASC_MAX_TID + 1];
699 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
700 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
701 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
702 ASC_DVC_CFG *cfg;
703 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
704 char redo_scam;
705 ushort res2;
706 uchar dos_int13_table[ASC_MAX_TID + 1];
707 ASC_DCNT max_dma_count;
708 ASC_SCSI_BIT_ID_TYPE no_scam;
709 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
710 uchar max_sdtr_index;
711 uchar host_init_sdtr_index;
712 struct asc_board *drv_ptr;
713 ASC_DCNT uc_break;
1da177e4
LT
714} ASC_DVC_VAR;
715
716typedef struct asc_dvc_inq_info {
27c868c2 717 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
718} ASC_DVC_INQ_INFO;
719
720typedef struct asc_cap_info {
27c868c2
MW
721 ASC_DCNT lba;
722 ASC_DCNT blk_size;
1da177e4
LT
723} ASC_CAP_INFO;
724
725typedef struct asc_cap_info_array {
27c868c2 726 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1da177e4
LT
727} ASC_CAP_INFO_ARRAY;
728
729#define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
730#define ASC_MCNTL_NULL_TARGET (ushort)0x0002
731#define ASC_CNTL_INITIATOR (ushort)0x0001
732#define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
733#define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
734#define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
735#define ASC_CNTL_NO_SCAM (ushort)0x0010
736#define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
737#define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
738#define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
739#define ASC_CNTL_RESET_SCSI (ushort)0x0200
740#define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
741#define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
742#define ASC_CNTL_SCSI_PARITY (ushort)0x1000
743#define ASC_CNTL_BURST_MODE (ushort)0x2000
744#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
745#define ASC_EEP_DVC_CFG_BEG_VL 2
746#define ASC_EEP_MAX_DVC_ADDR_VL 15
747#define ASC_EEP_DVC_CFG_BEG 32
748#define ASC_EEP_MAX_DVC_ADDR 45
749#define ASC_EEP_DEFINED_WORDS 10
750#define ASC_EEP_MAX_ADDR 63
751#define ASC_EEP_RES_WORDS 0
752#define ASC_EEP_MAX_RETRY 20
753#define ASC_MAX_INIT_BUSY_RETRY 8
754#define ASC_EEP_ISA_PNP_WSIZE 16
755
756/*
757 * These macros keep the chip SCSI id and ISA DMA speed
758 * bitfields in board order. C bitfields aren't portable
759 * between big and little-endian platforms so they are
760 * not used.
761 */
762
763#define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
764#define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
765#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
766 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
767#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
768 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
769
770typedef struct asceep_config {
27c868c2
MW
771 ushort cfg_lsw;
772 ushort cfg_msw;
773 uchar init_sdtr;
774 uchar disc_enable;
775 uchar use_cmd_qng;
776 uchar start_motor;
777 uchar max_total_qng;
778 uchar max_tag_qng;
779 uchar bios_scan;
780 uchar power_up_wait;
781 uchar no_scam;
782 uchar id_speed; /* low order 4 bits is chip scsi id */
783 /* high order 4 bits is isa dma speed */
784 uchar dos_int13_table[ASC_MAX_TID + 1];
785 uchar adapter_info[6];
786 ushort cntl;
787 ushort chksum;
1da177e4
LT
788} ASCEEP_CONFIG;
789
790#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
791#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
792#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
793
794#define ASC_EEP_CMD_READ 0x80
795#define ASC_EEP_CMD_WRITE 0x40
796#define ASC_EEP_CMD_WRITE_ABLE 0x30
797#define ASC_EEP_CMD_WRITE_DISABLE 0x00
798#define ASC_OVERRUN_BSIZE 0x00000048UL
799#define ASC_CTRL_BREAK_ONCE 0x0001
800#define ASC_CTRL_BREAK_STAY_IDLE 0x0002
801#define ASCV_MSGOUT_BEG 0x0000
802#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
803#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
804#define ASCV_BREAK_SAVED_CODE (ushort)0x0006
805#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
806#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
807#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
808#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
809#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
810#define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
811#define ASCV_BREAK_ADDR (ushort)0x0028
812#define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
813#define ASCV_BREAK_CONTROL (ushort)0x002C
814#define ASCV_BREAK_HIT_COUNT (ushort)0x002E
815
816#define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
817#define ASCV_MCODE_CHKSUM_W (ushort)0x0032
818#define ASCV_MCODE_SIZE_W (ushort)0x0034
819#define ASCV_STOP_CODE_B (ushort)0x0036
820#define ASCV_DVC_ERR_CODE_B (ushort)0x0037
821#define ASCV_OVERRUN_PADDR_D (ushort)0x0038
822#define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
823#define ASCV_HALTCODE_W (ushort)0x0040
824#define ASCV_CHKSUM_W (ushort)0x0042
825#define ASCV_MC_DATE_W (ushort)0x0044
826#define ASCV_MC_VER_W (ushort)0x0046
827#define ASCV_NEXTRDY_B (ushort)0x0048
828#define ASCV_DONENEXT_B (ushort)0x0049
829#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
830#define ASCV_SCSIBUSY_B (ushort)0x004B
831#define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
832#define ASCV_CURCDB_B (ushort)0x004D
833#define ASCV_RCLUN_B (ushort)0x004E
834#define ASCV_BUSY_QHEAD_B (ushort)0x004F
835#define ASCV_DISC1_QHEAD_B (ushort)0x0050
836#define ASCV_DISC_ENABLE_B (ushort)0x0052
837#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
838#define ASCV_HOSTSCSI_ID_B (ushort)0x0055
839#define ASCV_MCODE_CNTL_B (ushort)0x0056
840#define ASCV_NULL_TARGET_B (ushort)0x0057
841#define ASCV_FREE_Q_HEAD_W (ushort)0x0058
842#define ASCV_DONE_Q_TAIL_W (ushort)0x005A
843#define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
844#define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
845#define ASCV_HOST_FLAG_B (ushort)0x005D
846#define ASCV_TOTAL_READY_Q_B (ushort)0x0064
847#define ASCV_VER_SERIAL_B (ushort)0x0065
848#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
849#define ASCV_WTM_FLAG_B (ushort)0x0068
850#define ASCV_RISC_FLAG_B (ushort)0x006A
851#define ASCV_REQ_SG_LIST_QP (ushort)0x006B
852#define ASC_HOST_FLAG_IN_ISR 0x01
853#define ASC_HOST_FLAG_ACK_INT 0x02
854#define ASC_RISC_FLAG_GEN_INT 0x01
855#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
856#define IOP_CTRL (0x0F)
857#define IOP_STATUS (0x0E)
858#define IOP_INT_ACK IOP_STATUS
859#define IOP_REG_IFC (0x0D)
860#define IOP_SYN_OFFSET (0x0B)
861#define IOP_EXTRA_CONTROL (0x0D)
862#define IOP_REG_PC (0x0C)
863#define IOP_RAM_ADDR (0x0A)
864#define IOP_RAM_DATA (0x08)
865#define IOP_EEP_DATA (0x06)
866#define IOP_EEP_CMD (0x07)
867#define IOP_VERSION (0x03)
868#define IOP_CONFIG_HIGH (0x04)
869#define IOP_CONFIG_LOW (0x02)
870#define IOP_SIG_BYTE (0x01)
871#define IOP_SIG_WORD (0x00)
872#define IOP_REG_DC1 (0x0E)
873#define IOP_REG_DC0 (0x0C)
874#define IOP_REG_SB (0x0B)
875#define IOP_REG_DA1 (0x0A)
876#define IOP_REG_DA0 (0x08)
877#define IOP_REG_SC (0x09)
878#define IOP_DMA_SPEED (0x07)
879#define IOP_REG_FLAG (0x07)
880#define IOP_FIFO_H (0x06)
881#define IOP_FIFO_L (0x04)
882#define IOP_REG_ID (0x05)
883#define IOP_REG_QP (0x03)
884#define IOP_REG_IH (0x02)
885#define IOP_REG_IX (0x01)
886#define IOP_REG_AX (0x00)
887#define IFC_REG_LOCK (0x00)
888#define IFC_REG_UNLOCK (0x09)
889#define IFC_WR_EN_FILTER (0x10)
890#define IFC_RD_NO_EEPROM (0x10)
891#define IFC_SLEW_RATE (0x20)
892#define IFC_ACT_NEG (0x40)
893#define IFC_INP_FILTER (0x80)
894#define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
895#define SC_SEL (uchar)(0x80)
896#define SC_BSY (uchar)(0x40)
897#define SC_ACK (uchar)(0x20)
898#define SC_REQ (uchar)(0x10)
899#define SC_ATN (uchar)(0x08)
900#define SC_IO (uchar)(0x04)
901#define SC_CD (uchar)(0x02)
902#define SC_MSG (uchar)(0x01)
903#define SEC_SCSI_CTL (uchar)(0x80)
904#define SEC_ACTIVE_NEGATE (uchar)(0x40)
905#define SEC_SLEW_RATE (uchar)(0x20)
906#define SEC_ENABLE_FILTER (uchar)(0x10)
907#define ASC_HALT_EXTMSG_IN (ushort)0x8000
908#define ASC_HALT_CHK_CONDITION (ushort)0x8100
909#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
910#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
911#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
912#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
913#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
914#define ASC_MAX_QNO 0xF8
915#define ASC_DATA_SEC_BEG (ushort)0x0080
916#define ASC_DATA_SEC_END (ushort)0x0080
917#define ASC_CODE_SEC_BEG (ushort)0x0080
918#define ASC_CODE_SEC_END (ushort)0x0080
919#define ASC_QADR_BEG (0x4000)
920#define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
921#define ASC_QADR_END (ushort)0x7FFF
922#define ASC_QLAST_ADR (ushort)0x7FC0
923#define ASC_QBLK_SIZE 0x40
924#define ASC_BIOS_DATA_QBEG 0xF8
925#define ASC_MIN_ACTIVE_QNO 0x01
926#define ASC_QLINK_END 0xFF
927#define ASC_EEPROM_WORDS 0x10
928#define ASC_MAX_MGS_LEN 0x10
929#define ASC_BIOS_ADDR_DEF 0xDC00
930#define ASC_BIOS_SIZE 0x3800
931#define ASC_BIOS_RAM_OFF 0x3800
932#define ASC_BIOS_RAM_SIZE 0x800
933#define ASC_BIOS_MIN_ADDR 0xC000
934#define ASC_BIOS_MAX_ADDR 0xEC00
935#define ASC_BIOS_BANK_SIZE 0x0400
936#define ASC_MCODE_START_ADDR 0x0080
937#define ASC_CFG0_HOST_INT_ON 0x0020
938#define ASC_CFG0_BIOS_ON 0x0040
939#define ASC_CFG0_VERA_BURST_ON 0x0080
940#define ASC_CFG0_SCSI_PARITY_ON 0x0800
941#define ASC_CFG1_SCSI_TARGET_ON 0x0080
942#define ASC_CFG1_LRAM_8BITS_ON 0x0800
943#define ASC_CFG_MSW_CLR_MASK 0x3080
944#define CSW_TEST1 (ASC_CS_TYPE)0x8000
945#define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
946#define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
947#define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
948#define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
949#define CSW_TEST2 (ASC_CS_TYPE)0x0400
950#define CSW_TEST3 (ASC_CS_TYPE)0x0200
951#define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
952#define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
953#define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
954#define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
955#define CSW_HALTED (ASC_CS_TYPE)0x0010
956#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
957#define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
958#define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
959#define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
960#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
961#define CIW_INT_ACK (ASC_CS_TYPE)0x0100
962#define CIW_TEST1 (ASC_CS_TYPE)0x0200
963#define CIW_TEST2 (ASC_CS_TYPE)0x0400
964#define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
965#define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
966#define CC_CHIP_RESET (uchar)0x80
967#define CC_SCSI_RESET (uchar)0x40
968#define CC_HALT (uchar)0x20
969#define CC_SINGLE_STEP (uchar)0x10
970#define CC_DMA_ABLE (uchar)0x08
971#define CC_TEST (uchar)0x04
972#define CC_BANK_ONE (uchar)0x02
973#define CC_DIAG (uchar)0x01
974#define ASC_1000_ID0W 0x04C1
975#define ASC_1000_ID0W_FIX 0x00C1
976#define ASC_1000_ID1B 0x25
1da177e4
LT
977#define ASC_EISA_REV_IOP_MASK (0x0C83)
978#define ASC_EISA_PID_IOP_MASK (0x0C80)
979#define ASC_EISA_CFG_IOP_MASK (0x0C86)
980#define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1da177e4
LT
981#define INS_HALTINT (ushort)0x6281
982#define INS_HALT (ushort)0x6280
983#define INS_SINT (ushort)0x6200
984#define INS_RFLAG_WTM (ushort)0x7380
985#define ASC_MC_SAVE_CODE_WSIZE 0x500
986#define ASC_MC_SAVE_DATA_WSIZE 0x40
987
988typedef struct asc_mc_saved {
27c868c2
MW
989 ushort data[ASC_MC_SAVE_DATA_WSIZE];
990 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1da177e4
LT
991} ASC_MC_SAVED;
992
993#define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
994#define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
995#define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
996#define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
997#define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
998#define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
999#define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1000#define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1001#define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1002#define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1003#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1004#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1005#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1006#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1007#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1008#define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1009#define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1010#define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1011#define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1012#define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1013#define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1014#define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1015#define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1016#define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1017#define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1018#define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1019#define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1020#define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1021#define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1022#define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1023#define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1024#define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1025#define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1026#define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1027#define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1028#define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1029#define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1030#define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1031#define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1032#define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1033#define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1034#define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1035#define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1036#define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1037#define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1038#define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1039#define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1040#define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1041#define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1042#define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1043#define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1044#define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1045#define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1046#define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1047#define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1048#define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1049#define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1050#define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1051#define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1052#define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1053#define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1054#define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1055#define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1056#define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1057#define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1058#define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1059#define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1060#define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1061
27c868c2
MW
1062static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1063static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1064static void AscWaitEEPRead(void);
1065static void AscWaitEEPWrite(void);
1066static ushort AscReadEEPWord(PortAddr, uchar);
1067static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1068static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1069static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1070static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1071static int AscStartChip(PortAddr);
1072static int AscStopChip(PortAddr);
1073static void AscSetChipIH(PortAddr, ushort);
1074static int AscIsChipHalted(PortAddr);
1075static void AscAckInterrupt(PortAddr);
1076static void AscDisableInterrupt(PortAddr);
1077static void AscEnableInterrupt(PortAddr);
1078static void AscSetBank(PortAddr, uchar);
1079static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1da177e4 1080#ifdef CONFIG_ISA
27c868c2 1081static uchar AscGetIsaDmaSpeed(PortAddr);
1da177e4 1082#endif /* CONFIG_ISA */
27c868c2
MW
1083static uchar AscReadLramByte(PortAddr, ushort);
1084static ushort AscReadLramWord(PortAddr, ushort);
1da177e4 1085#if CC_VERY_LONG_SG_LIST
27c868c2 1086static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1da177e4 1087#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
1088static void AscWriteLramWord(PortAddr, ushort, ushort);
1089static void AscWriteLramByte(PortAddr, ushort, uchar);
1090static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1091static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1092static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1093static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1094static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1095static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1096static ushort AscInitFromEEP(ASC_DVC_VAR *);
27c868c2
MW
1097static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1098static int AscTestExternalLram(ASC_DVC_VAR *);
1099static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1100static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1101static void AscSetChipSDTR(PortAddr, uchar, uchar);
1102static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1103static uchar AscAllocFreeQueue(PortAddr, uchar);
1104static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1105static int AscHostReqRiscHalt(PortAddr);
1106static int AscStopQueueExe(PortAddr);
1107static int AscSendScsiQueue(ASC_DVC_VAR *,
1108 ASC_SCSI_Q *scsiq, uchar n_q_required);
1109static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1110static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1111static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1112static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1113static ushort AscInitLram(ASC_DVC_VAR *);
1114static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1115static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1116static int AscIsrChipHalted(ASC_DVC_VAR *);
1117static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1118 ASC_QDONE_INFO *, ASC_DCNT);
1119static int AscIsrQDone(ASC_DVC_VAR *);
1da177e4 1120#ifdef CONFIG_ISA
27c868c2 1121static ushort AscGetEisaChipCfg(PortAddr);
1da177e4 1122#endif /* CONFIG_ISA */
27c868c2 1123static uchar AscGetChipScsiCtrl(PortAddr);
27c868c2 1124static uchar AscGetChipVersion(PortAddr, ushort);
27c868c2 1125static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
27c868c2 1126static void AscToggleIRQAct(PortAddr);
27c868c2
MW
1127static inline ulong DvcEnterCritical(void);
1128static inline void DvcLeaveCritical(ulong);
27c868c2
MW
1129static void DvcSleepMilliSecond(ASC_DCNT);
1130static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1131static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1132static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
27c868c2 1133static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
47d853cc 1134static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
27c868c2
MW
1135static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1136static int AscISR(ASC_DVC_VAR *);
1137static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1138static int AscSgListToQueue(int);
1da177e4 1139#ifdef CONFIG_ISA
27c868c2 1140static void AscEnableIsaDma(uchar);
1da177e4 1141#endif /* CONFIG_ISA */
27c868c2 1142static const char *advansys_info(struct Scsi_Host *shost);
1da177e4
LT
1143
1144/*
1145 * --- Adv Library Constants and Macros
1146 */
1147
1148#define ADV_LIB_VERSION_MAJOR 5
1149#define ADV_LIB_VERSION_MINOR 14
1150
1151/*
1152 * Define Adv Library required special types.
1153 */
1154
1155/*
1156 * Portable Data Types
1157 *
1158 * Any instance where a 32-bit long or pointer type is assumed
1159 * for precision or HW defined structures, the following define
1160 * types must be used. In Linux the char, short, and int types
1161 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1162 * and long types are 64 bits on Alpha and UltraSPARC.
1163 */
27c868c2
MW
1164#define ADV_PADDR __u32 /* Physical address data type. */
1165#define ADV_VADDR __u32 /* Virtual address data type. */
1166#define ADV_DCNT __u32 /* Unsigned Data count type. */
1167#define ADV_SDCNT __s32 /* Signed Data count type. */
1da177e4
LT
1168
1169/*
1170 * These macros are used to convert a virtual address to a
1171 * 32-bit value. This currently can be used on Linux Alpha
1172 * which uses 64-bit virtual address but a 32-bit bus address.
1173 * This is likely to break in the future, but doing this now
1174 * will give us time to change the HW and FW to handle 64-bit
1175 * addresses.
1176 */
1177#define ADV_VADDR_TO_U32 virt_to_bus
1178#define ADV_U32_TO_VADDR bus_to_virt
1179
27c868c2 1180#define AdvPortAddr void __iomem * /* Virtual memory address size */
1da177e4
LT
1181
1182/*
1183 * Define Adv Library required memory access macros.
1184 */
1185#define ADV_MEM_READB(addr) readb(addr)
1186#define ADV_MEM_READW(addr) readw(addr)
1187#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1188#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1189#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1190
1191#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1192
1193/*
1194 * For wide boards a CDB length maximum of 16 bytes
1195 * is supported.
1196 */
1197#define ADV_MAX_CDB_LEN 16
1198
1199/*
1200 * Define total number of simultaneous maximum element scatter-gather
1201 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1202 * maximum number of outstanding commands per wide host adapter. Each
1203 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1204 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1205 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1206 * structures or 255 scatter-gather elements.
1207 *
1208 */
1209#define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
1210
1211/*
1212 * Define Adv Library required maximum number of scatter-gather
1213 * elements per request.
1214 */
1215#define ADV_MAX_SG_LIST 255
1216
1217/* Number of SG blocks needed. */
1218#define ADV_NUM_SG_BLOCK \
1219 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1220
1221/* Total contiguous memory needed for SG blocks. */
1222#define ADV_SG_TOTAL_MEM_SIZE \
1223 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
1224
1225#define ADV_PAGE_SIZE PAGE_SIZE
1226
1227#define ADV_NUM_PAGE_CROSSING \
1228 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1229
1da177e4
LT
1230#define ADV_EEP_DVC_CFG_BEGIN (0x00)
1231#define ADV_EEP_DVC_CFG_END (0x15)
27c868c2 1232#define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
1da177e4
LT
1233#define ADV_EEP_MAX_WORD_ADDR (0x1E)
1234
1235#define ADV_EEP_DELAY_MS 100
1236
27c868c2
MW
1237#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
1238#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
1da177e4
LT
1239/*
1240 * For the ASC3550 Bit 13 is Termination Polarity control bit.
1241 * For later ICs Bit 13 controls whether the CIS (Card Information
1242 * Service Section) is loaded from EEPROM.
1243 */
27c868c2
MW
1244#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
1245#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
1da177e4
LT
1246/*
1247 * ASC38C1600 Bit 11
1248 *
1249 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1250 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1251 * Function 0 will specify INT B.
1252 *
1253 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1254 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1255 * Function 1 will specify INT A.
1256 */
27c868c2
MW
1257#define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
1258
1259typedef struct adveep_3550_config {
1260 /* Word Offset, Description */
1261
1262 ushort cfg_lsw; /* 00 power up initialization */
1263 /* bit 13 set - Term Polarity Control */
1264 /* bit 14 set - BIOS Enable */
1265 /* bit 15 set - Big Endian Mode */
1266 ushort cfg_msw; /* 01 unused */
1267 ushort disc_enable; /* 02 disconnect enable */
1268 ushort wdtr_able; /* 03 Wide DTR able */
1269 ushort sdtr_able; /* 04 Synchronous DTR able */
1270 ushort start_motor; /* 05 send start up motor */
1271 ushort tagqng_able; /* 06 tag queuing able */
1272 ushort bios_scan; /* 07 BIOS device control */
1273 ushort scam_tolerant; /* 08 no scam */
1274
1275 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1276 uchar bios_boot_delay; /* power up wait */
1277
1278 uchar scsi_reset_delay; /* 10 reset delay */
1279 uchar bios_id_lun; /* first boot device scsi id & lun */
1280 /* high nibble is lun */
1281 /* low nibble is scsi id */
1282
1283 uchar termination; /* 11 0 - automatic */
1284 /* 1 - low off / high off */
1285 /* 2 - low off / high on */
1286 /* 3 - low on / high on */
1287 /* There is no low on / high off */
1288
1289 uchar reserved1; /* reserved byte (not used) */
1290
1291 ushort bios_ctrl; /* 12 BIOS control bits */
1292 /* bit 0 BIOS don't act as initiator. */
1293 /* bit 1 BIOS > 1 GB support */
1294 /* bit 2 BIOS > 2 Disk Support */
1295 /* bit 3 BIOS don't support removables */
1296 /* bit 4 BIOS support bootable CD */
1297 /* bit 5 BIOS scan enabled */
1298 /* bit 6 BIOS support multiple LUNs */
1299 /* bit 7 BIOS display of message */
1300 /* bit 8 SCAM disabled */
1301 /* bit 9 Reset SCSI bus during init. */
1302 /* bit 10 */
1303 /* bit 11 No verbose initialization. */
1304 /* bit 12 SCSI parity enabled */
1305 /* bit 13 */
1306 /* bit 14 */
1307 /* bit 15 */
1308 ushort ultra_able; /* 13 ULTRA speed able */
1309 ushort reserved2; /* 14 reserved */
1310 uchar max_host_qng; /* 15 maximum host queuing */
1311 uchar max_dvc_qng; /* maximum per device queuing */
1312 ushort dvc_cntl; /* 16 control bit for driver */
1313 ushort bug_fix; /* 17 control bit for bug fix */
1314 ushort serial_number_word1; /* 18 Board serial number word 1 */
1315 ushort serial_number_word2; /* 19 Board serial number word 2 */
1316 ushort serial_number_word3; /* 20 Board serial number word 3 */
1317 ushort check_sum; /* 21 EEP check sum */
1318 uchar oem_name[16]; /* 22 OEM name */
1319 ushort dvc_err_code; /* 30 last device driver error code */
1320 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1321 ushort adv_err_addr; /* 32 last uc error address */
1322 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1323 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1324 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1325 ushort num_of_err; /* 36 number of error */
1da177e4
LT
1326} ADVEEP_3550_CONFIG;
1327
27c868c2
MW
1328typedef struct adveep_38C0800_config {
1329 /* Word Offset, Description */
1330
1331 ushort cfg_lsw; /* 00 power up initialization */
1332 /* bit 13 set - Load CIS */
1333 /* bit 14 set - BIOS Enable */
1334 /* bit 15 set - Big Endian Mode */
1335 ushort cfg_msw; /* 01 unused */
1336 ushort disc_enable; /* 02 disconnect enable */
1337 ushort wdtr_able; /* 03 Wide DTR able */
1338 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1339 ushort start_motor; /* 05 send start up motor */
1340 ushort tagqng_able; /* 06 tag queuing able */
1341 ushort bios_scan; /* 07 BIOS device control */
1342 ushort scam_tolerant; /* 08 no scam */
1343
1344 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1345 uchar bios_boot_delay; /* power up wait */
1346
1347 uchar scsi_reset_delay; /* 10 reset delay */
1348 uchar bios_id_lun; /* first boot device scsi id & lun */
1349 /* high nibble is lun */
1350 /* low nibble is scsi id */
1351
1352 uchar termination_se; /* 11 0 - automatic */
1353 /* 1 - low off / high off */
1354 /* 2 - low off / high on */
1355 /* 3 - low on / high on */
1356 /* There is no low on / high off */
1357
1358 uchar termination_lvd; /* 11 0 - automatic */
1359 /* 1 - low off / high off */
1360 /* 2 - low off / high on */
1361 /* 3 - low on / high on */
1362 /* There is no low on / high off */
1363
1364 ushort bios_ctrl; /* 12 BIOS control bits */
1365 /* bit 0 BIOS don't act as initiator. */
1366 /* bit 1 BIOS > 1 GB support */
1367 /* bit 2 BIOS > 2 Disk Support */
1368 /* bit 3 BIOS don't support removables */
1369 /* bit 4 BIOS support bootable CD */
1370 /* bit 5 BIOS scan enabled */
1371 /* bit 6 BIOS support multiple LUNs */
1372 /* bit 7 BIOS display of message */
1373 /* bit 8 SCAM disabled */
1374 /* bit 9 Reset SCSI bus during init. */
1375 /* bit 10 */
1376 /* bit 11 No verbose initialization. */
1377 /* bit 12 SCSI parity enabled */
1378 /* bit 13 */
1379 /* bit 14 */
1380 /* bit 15 */
1381 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1382 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1383 uchar max_host_qng; /* 15 maximum host queueing */
1384 uchar max_dvc_qng; /* maximum per device queuing */
1385 ushort dvc_cntl; /* 16 control bit for driver */
1386 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1387 ushort serial_number_word1; /* 18 Board serial number word 1 */
1388 ushort serial_number_word2; /* 19 Board serial number word 2 */
1389 ushort serial_number_word3; /* 20 Board serial number word 3 */
1390 ushort check_sum; /* 21 EEP check sum */
1391 uchar oem_name[16]; /* 22 OEM name */
1392 ushort dvc_err_code; /* 30 last device driver error code */
1393 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1394 ushort adv_err_addr; /* 32 last uc error address */
1395 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1396 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1397 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1398 ushort reserved36; /* 36 reserved */
1399 ushort reserved37; /* 37 reserved */
1400 ushort reserved38; /* 38 reserved */
1401 ushort reserved39; /* 39 reserved */
1402 ushort reserved40; /* 40 reserved */
1403 ushort reserved41; /* 41 reserved */
1404 ushort reserved42; /* 42 reserved */
1405 ushort reserved43; /* 43 reserved */
1406 ushort reserved44; /* 44 reserved */
1407 ushort reserved45; /* 45 reserved */
1408 ushort reserved46; /* 46 reserved */
1409 ushort reserved47; /* 47 reserved */
1410 ushort reserved48; /* 48 reserved */
1411 ushort reserved49; /* 49 reserved */
1412 ushort reserved50; /* 50 reserved */
1413 ushort reserved51; /* 51 reserved */
1414 ushort reserved52; /* 52 reserved */
1415 ushort reserved53; /* 53 reserved */
1416 ushort reserved54; /* 54 reserved */
1417 ushort reserved55; /* 55 reserved */
1418 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1419 ushort cisprt_msw; /* 57 CIS PTR MSW */
1420 ushort subsysvid; /* 58 SubSystem Vendor ID */
1421 ushort subsysid; /* 59 SubSystem ID */
1422 ushort reserved60; /* 60 reserved */
1423 ushort reserved61; /* 61 reserved */
1424 ushort reserved62; /* 62 reserved */
1425 ushort reserved63; /* 63 reserved */
1da177e4
LT
1426} ADVEEP_38C0800_CONFIG;
1427
27c868c2
MW
1428typedef struct adveep_38C1600_config {
1429 /* Word Offset, Description */
1430
1431 ushort cfg_lsw; /* 00 power up initialization */
1432 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
1433 /* clear - Func. 0 INTA, Func. 1 INTB */
1434 /* bit 13 set - Load CIS */
1435 /* bit 14 set - BIOS Enable */
1436 /* bit 15 set - Big Endian Mode */
1437 ushort cfg_msw; /* 01 unused */
1438 ushort disc_enable; /* 02 disconnect enable */
1439 ushort wdtr_able; /* 03 Wide DTR able */
1440 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
1441 ushort start_motor; /* 05 send start up motor */
1442 ushort tagqng_able; /* 06 tag queuing able */
1443 ushort bios_scan; /* 07 BIOS device control */
1444 ushort scam_tolerant; /* 08 no scam */
1445
1446 uchar adapter_scsi_id; /* 09 Host Adapter ID */
1447 uchar bios_boot_delay; /* power up wait */
1448
1449 uchar scsi_reset_delay; /* 10 reset delay */
1450 uchar bios_id_lun; /* first boot device scsi id & lun */
1451 /* high nibble is lun */
1452 /* low nibble is scsi id */
1453
1454 uchar termination_se; /* 11 0 - automatic */
1455 /* 1 - low off / high off */
1456 /* 2 - low off / high on */
1457 /* 3 - low on / high on */
1458 /* There is no low on / high off */
1459
1460 uchar termination_lvd; /* 11 0 - automatic */
1461 /* 1 - low off / high off */
1462 /* 2 - low off / high on */
1463 /* 3 - low on / high on */
1464 /* There is no low on / high off */
1465
1466 ushort bios_ctrl; /* 12 BIOS control bits */
1467 /* bit 0 BIOS don't act as initiator. */
1468 /* bit 1 BIOS > 1 GB support */
1469 /* bit 2 BIOS > 2 Disk Support */
1470 /* bit 3 BIOS don't support removables */
1471 /* bit 4 BIOS support bootable CD */
1472 /* bit 5 BIOS scan enabled */
1473 /* bit 6 BIOS support multiple LUNs */
1474 /* bit 7 BIOS display of message */
1475 /* bit 8 SCAM disabled */
1476 /* bit 9 Reset SCSI bus during init. */
1477 /* bit 10 Basic Integrity Checking disabled */
1478 /* bit 11 No verbose initialization. */
1479 /* bit 12 SCSI parity enabled */
1480 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1481 /* bit 14 */
1482 /* bit 15 */
1483 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
1484 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
1485 uchar max_host_qng; /* 15 maximum host queueing */
1486 uchar max_dvc_qng; /* maximum per device queuing */
1487 ushort dvc_cntl; /* 16 control bit for driver */
1488 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
1489 ushort serial_number_word1; /* 18 Board serial number word 1 */
1490 ushort serial_number_word2; /* 19 Board serial number word 2 */
1491 ushort serial_number_word3; /* 20 Board serial number word 3 */
1492 ushort check_sum; /* 21 EEP check sum */
1493 uchar oem_name[16]; /* 22 OEM name */
1494 ushort dvc_err_code; /* 30 last device driver error code */
1495 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
1496 ushort adv_err_addr; /* 32 last uc error address */
1497 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
1498 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
1499 ushort saved_adv_err_addr; /* 35 saved last uc error address */
1500 ushort reserved36; /* 36 reserved */
1501 ushort reserved37; /* 37 reserved */
1502 ushort reserved38; /* 38 reserved */
1503 ushort reserved39; /* 39 reserved */
1504 ushort reserved40; /* 40 reserved */
1505 ushort reserved41; /* 41 reserved */
1506 ushort reserved42; /* 42 reserved */
1507 ushort reserved43; /* 43 reserved */
1508 ushort reserved44; /* 44 reserved */
1509 ushort reserved45; /* 45 reserved */
1510 ushort reserved46; /* 46 reserved */
1511 ushort reserved47; /* 47 reserved */
1512 ushort reserved48; /* 48 reserved */
1513 ushort reserved49; /* 49 reserved */
1514 ushort reserved50; /* 50 reserved */
1515 ushort reserved51; /* 51 reserved */
1516 ushort reserved52; /* 52 reserved */
1517 ushort reserved53; /* 53 reserved */
1518 ushort reserved54; /* 54 reserved */
1519 ushort reserved55; /* 55 reserved */
1520 ushort cisptr_lsw; /* 56 CIS PTR LSW */
1521 ushort cisprt_msw; /* 57 CIS PTR MSW */
1522 ushort subsysvid; /* 58 SubSystem Vendor ID */
1523 ushort subsysid; /* 59 SubSystem ID */
1524 ushort reserved60; /* 60 reserved */
1525 ushort reserved61; /* 61 reserved */
1526 ushort reserved62; /* 62 reserved */
1527 ushort reserved63; /* 63 reserved */
1da177e4
LT
1528} ADVEEP_38C1600_CONFIG;
1529
1530/*
1531 * EEPROM Commands
1532 */
1533#define ASC_EEP_CMD_DONE 0x0200
1534#define ASC_EEP_CMD_DONE_ERR 0x0001
1535
1536/* cfg_word */
1537#define EEP_CFG_WORD_BIG_ENDIAN 0x8000
1538
1539/* bios_ctrl */
1540#define BIOS_CTRL_BIOS 0x0001
1541#define BIOS_CTRL_EXTENDED_XLAT 0x0002
1542#define BIOS_CTRL_GT_2_DISK 0x0004
1543#define BIOS_CTRL_BIOS_REMOVABLE 0x0008
1544#define BIOS_CTRL_BOOTABLE_CD 0x0010
1545#define BIOS_CTRL_MULTIPLE_LUN 0x0040
1546#define BIOS_CTRL_DISPLAY_MSG 0x0080
1547#define BIOS_CTRL_NO_SCAM 0x0100
1548#define BIOS_CTRL_RESET_SCSI_BUS 0x0200
1549#define BIOS_CTRL_INIT_VERBOSE 0x0800
1550#define BIOS_CTRL_SCSI_PARITY 0x1000
1551#define BIOS_CTRL_AIPP_DIS 0x2000
1552
27c868c2 1553#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
1da177e4 1554
27c868c2 1555#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1556
1557/*
1558 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1559 * a special 16K Adv Library and Microcode version. After the issue is
1560 * resolved, should restore 32K support.
1561 *
1562 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
1563 */
27c868c2 1564#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
1da177e4
LT
1565
1566/*
1567 * Byte I/O register address from base of 'iop_base'.
1568 */
1569#define IOPB_INTR_STATUS_REG 0x00
1570#define IOPB_CHIP_ID_1 0x01
1571#define IOPB_INTR_ENABLES 0x02
1572#define IOPB_CHIP_TYPE_REV 0x03
1573#define IOPB_RES_ADDR_4 0x04
1574#define IOPB_RES_ADDR_5 0x05
1575#define IOPB_RAM_DATA 0x06
1576#define IOPB_RES_ADDR_7 0x07
1577#define IOPB_FLAG_REG 0x08
1578#define IOPB_RES_ADDR_9 0x09
1579#define IOPB_RISC_CSR 0x0A
1580#define IOPB_RES_ADDR_B 0x0B
1581#define IOPB_RES_ADDR_C 0x0C
1582#define IOPB_RES_ADDR_D 0x0D
1583#define IOPB_SOFT_OVER_WR 0x0E
1584#define IOPB_RES_ADDR_F 0x0F
1585#define IOPB_MEM_CFG 0x10
1586#define IOPB_RES_ADDR_11 0x11
1587#define IOPB_GPIO_DATA 0x12
1588#define IOPB_RES_ADDR_13 0x13
1589#define IOPB_FLASH_PAGE 0x14
1590#define IOPB_RES_ADDR_15 0x15
1591#define IOPB_GPIO_CNTL 0x16
1592#define IOPB_RES_ADDR_17 0x17
1593#define IOPB_FLASH_DATA 0x18
1594#define IOPB_RES_ADDR_19 0x19
1595#define IOPB_RES_ADDR_1A 0x1A
1596#define IOPB_RES_ADDR_1B 0x1B
1597#define IOPB_RES_ADDR_1C 0x1C
1598#define IOPB_RES_ADDR_1D 0x1D
1599#define IOPB_RES_ADDR_1E 0x1E
1600#define IOPB_RES_ADDR_1F 0x1F
1601#define IOPB_DMA_CFG0 0x20
1602#define IOPB_DMA_CFG1 0x21
1603#define IOPB_TICKLE 0x22
1604#define IOPB_DMA_REG_WR 0x23
1605#define IOPB_SDMA_STATUS 0x24
1606#define IOPB_SCSI_BYTE_CNT 0x25
1607#define IOPB_HOST_BYTE_CNT 0x26
1608#define IOPB_BYTE_LEFT_TO_XFER 0x27
1609#define IOPB_BYTE_TO_XFER_0 0x28
1610#define IOPB_BYTE_TO_XFER_1 0x29
1611#define IOPB_BYTE_TO_XFER_2 0x2A
1612#define IOPB_BYTE_TO_XFER_3 0x2B
1613#define IOPB_ACC_GRP 0x2C
1614#define IOPB_RES_ADDR_2D 0x2D
1615#define IOPB_DEV_ID 0x2E
1616#define IOPB_RES_ADDR_2F 0x2F
1617#define IOPB_SCSI_DATA 0x30
1618#define IOPB_RES_ADDR_31 0x31
1619#define IOPB_RES_ADDR_32 0x32
1620#define IOPB_SCSI_DATA_HSHK 0x33
1621#define IOPB_SCSI_CTRL 0x34
1622#define IOPB_RES_ADDR_35 0x35
1623#define IOPB_RES_ADDR_36 0x36
1624#define IOPB_RES_ADDR_37 0x37
1625#define IOPB_RAM_BIST 0x38
1626#define IOPB_PLL_TEST 0x39
1627#define IOPB_PCI_INT_CFG 0x3A
1628#define IOPB_RES_ADDR_3B 0x3B
1629#define IOPB_RFIFO_CNT 0x3C
1630#define IOPB_RES_ADDR_3D 0x3D
1631#define IOPB_RES_ADDR_3E 0x3E
1632#define IOPB_RES_ADDR_3F 0x3F
1633
1634/*
1635 * Word I/O register address from base of 'iop_base'.
1636 */
27c868c2
MW
1637#define IOPW_CHIP_ID_0 0x00 /* CID0 */
1638#define IOPW_CTRL_REG 0x02 /* CC */
1639#define IOPW_RAM_ADDR 0x04 /* LA */
1640#define IOPW_RAM_DATA 0x06 /* LD */
1da177e4 1641#define IOPW_RES_ADDR_08 0x08
27c868c2
MW
1642#define IOPW_RISC_CSR 0x0A /* CSR */
1643#define IOPW_SCSI_CFG0 0x0C /* CFG0 */
1644#define IOPW_SCSI_CFG1 0x0E /* CFG1 */
1da177e4 1645#define IOPW_RES_ADDR_10 0x10
27c868c2 1646#define IOPW_SEL_MASK 0x12 /* SM */
1da177e4 1647#define IOPW_RES_ADDR_14 0x14
27c868c2 1648#define IOPW_FLASH_ADDR 0x16 /* FA */
1da177e4 1649#define IOPW_RES_ADDR_18 0x18
27c868c2
MW
1650#define IOPW_EE_CMD 0x1A /* EC */
1651#define IOPW_EE_DATA 0x1C /* ED */
1652#define IOPW_SFIFO_CNT 0x1E /* SFC */
1da177e4 1653#define IOPW_RES_ADDR_20 0x20
27c868c2
MW
1654#define IOPW_Q_BASE 0x22 /* QB */
1655#define IOPW_QP 0x24 /* QP */
1656#define IOPW_IX 0x26 /* IX */
1657#define IOPW_SP 0x28 /* SP */
1658#define IOPW_PC 0x2A /* PC */
1da177e4
LT
1659#define IOPW_RES_ADDR_2C 0x2C
1660#define IOPW_RES_ADDR_2E 0x2E
27c868c2
MW
1661#define IOPW_SCSI_DATA 0x30 /* SD */
1662#define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
1663#define IOPW_SCSI_CTRL 0x34 /* SC */
1664#define IOPW_HSHK_CFG 0x36 /* HCFG */
1665#define IOPW_SXFR_STATUS 0x36 /* SXS */
1666#define IOPW_SXFR_CNTL 0x38 /* SXL */
1667#define IOPW_SXFR_CNTH 0x3A /* SXH */
1da177e4 1668#define IOPW_RES_ADDR_3C 0x3C
27c868c2 1669#define IOPW_RFIFO_DATA 0x3E /* RFD */
1da177e4
LT
1670
1671/*
1672 * Doubleword I/O register address from base of 'iop_base'.
1673 */
1674#define IOPDW_RES_ADDR_0 0x00
1675#define IOPDW_RAM_DATA 0x04
1676#define IOPDW_RES_ADDR_8 0x08
1677#define IOPDW_RES_ADDR_C 0x0C
1678#define IOPDW_RES_ADDR_10 0x10
1679#define IOPDW_COMMA 0x14
1680#define IOPDW_COMMB 0x18
1681#define IOPDW_RES_ADDR_1C 0x1C
1682#define IOPDW_SDMA_ADDR0 0x20
1683#define IOPDW_SDMA_ADDR1 0x24
1684#define IOPDW_SDMA_COUNT 0x28
1685#define IOPDW_SDMA_ERROR 0x2C
1686#define IOPDW_RDMA_ADDR0 0x30
1687#define IOPDW_RDMA_ADDR1 0x34
1688#define IOPDW_RDMA_COUNT 0x38
1689#define IOPDW_RDMA_ERROR 0x3C
1690
1691#define ADV_CHIP_ID_BYTE 0x25
1692#define ADV_CHIP_ID_WORD 0x04C1
1693
1694#define ADV_SC_SCSI_BUS_RESET 0x2000
1695
1696#define ADV_INTR_ENABLE_HOST_INTR 0x01
1697#define ADV_INTR_ENABLE_SEL_INTR 0x02
1698#define ADV_INTR_ENABLE_DPR_INTR 0x04
1699#define ADV_INTR_ENABLE_RTA_INTR 0x08
1700#define ADV_INTR_ENABLE_RMA_INTR 0x10
1701#define ADV_INTR_ENABLE_RST_INTR 0x20
1702#define ADV_INTR_ENABLE_DPE_INTR 0x40
1703#define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
1704
1705#define ADV_INTR_STATUS_INTRA 0x01
1706#define ADV_INTR_STATUS_INTRB 0x02
1707#define ADV_INTR_STATUS_INTRC 0x04
1708
1709#define ADV_RISC_CSR_STOP (0x0000)
1710#define ADV_RISC_TEST_COND (0x2000)
1711#define ADV_RISC_CSR_RUN (0x4000)
1712#define ADV_RISC_CSR_SINGLE_STEP (0x8000)
1713
1714#define ADV_CTRL_REG_HOST_INTR 0x0100
1715#define ADV_CTRL_REG_SEL_INTR 0x0200
1716#define ADV_CTRL_REG_DPR_INTR 0x0400
1717#define ADV_CTRL_REG_RTA_INTR 0x0800
1718#define ADV_CTRL_REG_RMA_INTR 0x1000
1719#define ADV_CTRL_REG_RES_BIT14 0x2000
1720#define ADV_CTRL_REG_DPE_INTR 0x4000
1721#define ADV_CTRL_REG_POWER_DONE 0x8000
1722#define ADV_CTRL_REG_ANY_INTR 0xFF00
1723
1724#define ADV_CTRL_REG_CMD_RESET 0x00C6
1725#define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
1726#define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
1727#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
1728#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
1729
1730#define ADV_TICKLE_NOP 0x00
1731#define ADV_TICKLE_A 0x01
1732#define ADV_TICKLE_B 0x02
1733#define ADV_TICKLE_C 0x03
1734
1735#define ADV_SCSI_CTRL_RSTOUT 0x2000
1736
1737#define AdvIsIntPending(port) \
1738 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1739
1740/*
1741 * SCSI_CFG0 Register bit definitions
1742 */
27c868c2
MW
1743#define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
1744#define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
1745#define EVEN_PARITY 0x1000 /* Select Even Parity */
1746#define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1747#define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
1748#define PRIM_MODE 0x0100 /* Primitive SCSI mode */
1749#define SCAM_EN 0x0080 /* Enable SCAM selection */
1750#define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1751#define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1752#define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
1753#define OUR_ID 0x000F /* SCSI ID */
1da177e4
LT
1754
1755/*
1756 * SCSI_CFG1 Register bit definitions
1757 */
27c868c2
MW
1758#define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
1759#define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1760#define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
1761#define FILTER_SEL 0x0C00 /* Filter Period Selection */
1762#define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
1763#define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1764#define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1765#define ACTIVE_DBL 0x0200 /* Disable Active Negation */
1766#define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
1767#define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
1768#define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
1769#define TERM_CTL 0x0030 /* External SCSI Termination Bits */
1770#define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
1771#define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
1772#define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
1da177e4
LT
1773
1774/*
1775 * Addendum for ASC-38C0800 Chip
1776 *
1777 * The ASC-38C1600 Chip uses the same definitions except that the
1778 * bus mode override bits [12:10] have been moved to byte register
1779 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1780 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1781 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1782 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1783 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1784 */
27c868c2
MW
1785#define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
1786#define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
1787#define HVD 0x1000 /* HVD Device Detect */
1788#define LVD 0x0800 /* LVD Device Detect */
1789#define SE 0x0400 /* SE Device Detect */
1790#define TERM_LVD 0x00C0 /* LVD Termination Bits */
1791#define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
1792#define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
1793#define TERM_SE 0x0030 /* SE Termination Bits */
1794#define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
1795#define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
1796#define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
1797#define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
1798#define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
1799#define C_DET_SE 0x0003 /* SE Cable Detect Bits */
1800#define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
1801#define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
1da177e4
LT
1802
1803#define CABLE_ILLEGAL_A 0x7
1804 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
1805
1806#define CABLE_ILLEGAL_B 0xB
1807 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
1808
1809/*
1810 * MEM_CFG Register bit definitions
1811 */
27c868c2
MW
1812#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
1813#define FAST_EE_CLK 0x20 /* Diagnostic Bit */
1814#define RAM_SZ 0x1C /* Specify size of RAM to RISC */
1815#define RAM_SZ_2KB 0x00 /* 2 KB */
1816#define RAM_SZ_4KB 0x04 /* 4 KB */
1817#define RAM_SZ_8KB 0x08 /* 8 KB */
1818#define RAM_SZ_16KB 0x0C /* 16 KB */
1819#define RAM_SZ_32KB 0x10 /* 32 KB */
1820#define RAM_SZ_64KB 0x14 /* 64 KB */
1da177e4
LT
1821
1822/*
1823 * DMA_CFG0 Register bit definitions
1824 *
1825 * This register is only accessible to the host.
1826 */
27c868c2
MW
1827#define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
1828#define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
1829#define FIFO_THRESH_16B 0x00 /* 16 bytes */
1830#define FIFO_THRESH_32B 0x20 /* 32 bytes */
1831#define FIFO_THRESH_48B 0x30 /* 48 bytes */
1832#define FIFO_THRESH_64B 0x40 /* 64 bytes */
1833#define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
1834#define FIFO_THRESH_96B 0x60 /* 96 bytes */
1835#define FIFO_THRESH_112B 0x70 /* 112 bytes */
1836#define START_CTL 0x0C /* DMA start conditions */
1837#define START_CTL_TH 0x00 /* Wait threshold level (default) */
1838#define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
1839#define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
1840#define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
1841#define READ_CMD 0x03 /* Memory Read Method */
1842#define READ_CMD_MR 0x00 /* Memory Read */
1843#define READ_CMD_MRL 0x02 /* Memory Read Long */
1844#define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
1da177e4
LT
1845
1846/*
1847 * ASC-38C0800 RAM BIST Register bit definitions
1848 */
1849#define RAM_TEST_MODE 0x80
1850#define PRE_TEST_MODE 0x40
1851#define NORMAL_MODE 0x00
1852#define RAM_TEST_DONE 0x10
1853#define RAM_TEST_STATUS 0x0F
1854#define RAM_TEST_HOST_ERROR 0x08
1855#define RAM_TEST_INTRAM_ERROR 0x04
1856#define RAM_TEST_RISC_ERROR 0x02
1857#define RAM_TEST_SCSI_ERROR 0x01
1858#define RAM_TEST_SUCCESS 0x00
1859#define PRE_TEST_VALUE 0x05
1860#define NORMAL_VALUE 0x00
1861
1862/*
1863 * ASC38C1600 Definitions
1864 *
1865 * IOPB_PCI_INT_CFG Bit Field Definitions
1866 */
1867
27c868c2 1868#define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
1da177e4
LT
1869
1870/*
1871 * Bit 1 can be set to change the interrupt for the Function to operate in
1872 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1873 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1874 * mode, otherwise the operating mode is undefined.
1875 */
1876#define TOTEMPOLE 0x02
1877
1878/*
1879 * Bit 0 can be used to change the Int Pin for the Function. The value is
1880 * 0 by default for both Functions with Function 0 using INT A and Function
1881 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1882 * INT A is used.
1883 *
1884 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1885 * value specified in the PCI Configuration Space.
1886 */
1887#define INTAB 0x01
1888
1889/* a_advlib.h */
1890
1891/*
1892 * Adv Library Status Definitions
1893 */
1894#define ADV_TRUE 1
1895#define ADV_FALSE 0
1896#define ADV_NOERROR 1
1897#define ADV_SUCCESS 1
1898#define ADV_BUSY 0
1899#define ADV_ERROR (-1)
1900
1da177e4
LT
1901/*
1902 * ADV_DVC_VAR 'warn_code' values
1903 */
27c868c2
MW
1904#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
1905#define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
1906#define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
1907#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
1908#define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
1da177e4 1909
27c868c2
MW
1910#define ADV_MAX_TID 15 /* max. target identifier */
1911#define ADV_MAX_LUN 7 /* max. logical unit number */
1da177e4
LT
1912
1913/*
1914 * Error code values are set in ADV_DVC_VAR 'err_code'.
1915 */
27c868c2
MW
1916#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
1917#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
1918#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
1919#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
1920#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
1921#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
1922#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
1923#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
1924#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
1925#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
1926#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
1927#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
1928#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
1929#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
1da177e4
LT
1930
1931/*
1932 * Fixed locations of microcode operating variables.
1933 */
27c868c2
MW
1934#define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
1935#define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
1936#define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
1937#define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
1938#define ASC_MC_VERSION_NUM 0x003A /* microcode number */
1939#define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
1940#define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
1941#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
1942#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
1943#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
1944#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
1945#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
1946#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
1da177e4
LT
1947#define ASC_MC_CHIP_TYPE 0x009A
1948#define ASC_MC_INTRB_CODE 0x009B
1949#define ASC_MC_WDTR_ABLE 0x009C
1950#define ASC_MC_SDTR_ABLE 0x009E
1951#define ASC_MC_TAGQNG_ABLE 0x00A0
1952#define ASC_MC_DISC_ENABLE 0x00A2
1953#define ASC_MC_IDLE_CMD_STATUS 0x00A4
1954#define ASC_MC_IDLE_CMD 0x00A6
1955#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
1956#define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
1957#define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
1958#define ASC_MC_DEFAULT_MEM_CFG 0x00B0
1959#define ASC_MC_DEFAULT_SEL_MASK 0x00B2
1960#define ASC_MC_SDTR_DONE 0x00B6
1961#define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
1962#define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
1963#define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
27c868c2 1964#define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
1da177e4 1965#define ASC_MC_WDTR_DONE 0x0124
27c868c2 1966#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
1da177e4
LT
1967#define ASC_MC_ICQ 0x0160
1968#define ASC_MC_IRQ 0x0164
1969#define ASC_MC_PPR_ABLE 0x017A
1970
1971/*
1972 * BIOS LRAM variable absolute offsets.
1973 */
1974#define BIOS_CODESEG 0x54
1975#define BIOS_CODELEN 0x56
1976#define BIOS_SIGNATURE 0x58
1977#define BIOS_VERSION 0x5A
1978
1979/*
1980 * Microcode Control Flags
1981 *
1982 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1983 * and handled by the microcode.
1984 */
27c868c2
MW
1985#define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
1986#define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
1da177e4
LT
1987
1988/*
1989 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1990 */
1991#define HSHK_CFG_WIDE_XFR 0x8000
1992#define HSHK_CFG_RATE 0x0F00
1993#define HSHK_CFG_OFFSET 0x001F
1994
27c868c2
MW
1995#define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
1996#define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
1997#define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
1998#define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
1999
2000#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2001#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2002#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2003#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2004#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2005
2006#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2007#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2008#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2009#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2010#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
1da177e4
LT
2011/*
2012 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2013 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2014 */
27c868c2
MW
2015#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2016#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
1da177e4
LT
2017
2018/*
2019 * All fields here are accessed by the board microcode and need to be
2020 * little-endian.
2021 */
27c868c2
MW
2022typedef struct adv_carr_t {
2023 ADV_VADDR carr_va; /* Carrier Virtual Address */
2024 ADV_PADDR carr_pa; /* Carrier Physical Address */
2025 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2026 /*
2027 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2028 *
2029 * next_vpa [3:1] Reserved Bits
2030 * next_vpa [0] Done Flag set in Response Queue.
2031 */
2032 ADV_VADDR next_vpa;
1da177e4
LT
2033} ADV_CARR_T;
2034
2035/*
2036 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2037 */
2038#define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2039
2040#define ASC_RQ_DONE 0x00000001
2041#define ASC_RQ_GOOD 0x00000002
2042#define ASC_CQ_STOPPER 0x00000000
2043
2044#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2045
2046#define ADV_CARRIER_NUM_PAGE_CROSSING \
2047 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2048 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2049
2050#define ADV_CARRIER_BUFSIZE \
2051 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2052
2053/*
2054 * ASC_SCSI_REQ_Q 'a_flag' definitions
2055 *
2056 * The Adv Library should limit use to the lower nibble (4 bits) of
2057 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2058 */
27c868c2
MW
2059#define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2060#define ADV_SCSIQ_DONE 0x02 /* request done */
2061#define ADV_DONT_RETRY 0x08 /* don't do retry */
1da177e4 2062
27c868c2
MW
2063#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2064#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2065#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
1da177e4
LT
2066
2067/*
2068 * Adapter temporary configuration structure
2069 *
2070 * This structure can be discarded after initialization. Don't add
2071 * fields here needed after initialization.
2072 *
2073 * Field naming convention:
2074 *
2075 * *_enable indicates the field enables or disables a feature. The
2076 * value of the field is never reset.
2077 */
2078typedef struct adv_dvc_cfg {
27c868c2
MW
2079 ushort disc_enable; /* enable disconnection */
2080 uchar chip_version; /* chip version */
2081 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2082 ushort lib_version; /* Adv Library version number */
2083 ushort control_flag; /* Microcode Control Flag */
2084 ushort mcode_date; /* Microcode date */
2085 ushort mcode_version; /* Microcode version */
27c868c2
MW
2086 ushort serial1; /* EEPROM serial number word 1 */
2087 ushort serial2; /* EEPROM serial number word 2 */
2088 ushort serial3; /* EEPROM serial number word 3 */
1da177e4
LT
2089} ADV_DVC_CFG;
2090
2091struct adv_dvc_var;
2092struct adv_scsi_req_q;
2093
1da177e4
LT
2094/*
2095 * Adapter operation variable structure.
2096 *
2097 * One structure is required per host adapter.
2098 *
2099 * Field naming convention:
2100 *
2101 * *_able indicates both whether a feature should be enabled or disabled
2102 * and whether a device isi capable of the feature. At initialization
2103 * this field may be set, but later if a device is found to be incapable
2104 * of the feature, the field is cleared.
2105 */
2106typedef struct adv_dvc_var {
27c868c2
MW
2107 AdvPortAddr iop_base; /* I/O port address */
2108 ushort err_code; /* fatal error code */
2109 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
27c868c2
MW
2110 ushort wdtr_able; /* try WDTR for a device */
2111 ushort sdtr_able; /* try SDTR for a device */
2112 ushort ultra_able; /* try SDTR Ultra speed for a device */
2113 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2114 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2115 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2116 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2117 ushort tagqng_able; /* try tagged queuing with a device */
2118 ushort ppr_able; /* PPR message capable per TID bitmask. */
2119 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2120 ushort start_motor; /* start motor command allowed */
2121 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2122 uchar chip_no; /* should be assigned by caller */
2123 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2124 uchar irq_no; /* IRQ number */
2125 ushort no_scam; /* scam_tolerant of EEPROM */
2126 struct asc_board *drv_ptr; /* driver pointer to private structure */
2127 uchar chip_scsi_id; /* chip SCSI target ID */
2128 uchar chip_type;
2129 uchar bist_err_code;
2130 ADV_CARR_T *carrier_buf;
2131 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2132 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2133 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2134 ushort carr_pending_cnt; /* Count of pending carriers. */
2135 /*
2136 * Note: The following fields will not be used after initialization. The
2137 * driver may discard the buffer after initialization is done.
2138 */
2139 ADV_DVC_CFG *cfg; /* temporary configuration structure */
1da177e4
LT
2140} ADV_DVC_VAR;
2141
2142#define NO_OF_SG_PER_BLOCK 15
2143
2144typedef struct asc_sg_block {
27c868c2
MW
2145 uchar reserved1;
2146 uchar reserved2;
2147 uchar reserved3;
2148 uchar sg_cnt; /* Valid entries in block. */
2149 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2150 struct {
2151 ADV_PADDR sg_addr; /* SG element address. */
2152 ADV_DCNT sg_count; /* SG element count. */
2153 } sg_list[NO_OF_SG_PER_BLOCK];
1da177e4
LT
2154} ADV_SG_BLOCK;
2155
2156/*
2157 * ADV_SCSI_REQ_Q - microcode request structure
2158 *
2159 * All fields in this structure up to byte 60 are used by the microcode.
2160 * The microcode makes assumptions about the size and ordering of fields
2161 * in this structure. Do not change the structure definition here without
2162 * coordinating the change with the microcode.
2163 *
2164 * All fields accessed by microcode must be maintained in little_endian
2165 * order.
2166 */
2167typedef struct adv_scsi_req_q {
27c868c2
MW
2168 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
2169 uchar target_cmd;
2170 uchar target_id; /* Device target identifier. */
2171 uchar target_lun; /* Device target logical unit number. */
2172 ADV_PADDR data_addr; /* Data buffer physical address. */
2173 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
2174 ADV_PADDR sense_addr;
2175 ADV_PADDR carr_pa;
2176 uchar mflag;
2177 uchar sense_len;
2178 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
2179 uchar scsi_cntl;
2180 uchar done_status; /* Completion status. */
2181 uchar scsi_status; /* SCSI status byte. */
2182 uchar host_status; /* Ucode host status. */
2183 uchar sg_working_ix;
2184 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
2185 ADV_PADDR sg_real_addr; /* SG list physical address. */
2186 ADV_PADDR scsiq_rptr;
2187 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
2188 ADV_VADDR scsiq_ptr;
2189 ADV_VADDR carr_va;
2190 /*
2191 * End of microcode structure - 60 bytes. The rest of the structure
2192 * is used by the Adv Library and ignored by the microcode.
2193 */
2194 ADV_VADDR srb_ptr;
2195 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
2196 char *vdata_addr; /* Data buffer virtual address. */
2197 uchar a_flag;
2198 uchar pad[2]; /* Pad out to a word boundary. */
1da177e4
LT
2199} ADV_SCSI_REQ_Q;
2200
2201/*
2202 * Microcode idle loop commands
2203 */
2204#define IDLE_CMD_COMPLETED 0
2205#define IDLE_CMD_STOP_CHIP 0x0001
2206#define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
2207#define IDLE_CMD_SEND_INT 0x0004
2208#define IDLE_CMD_ABORT 0x0008
2209#define IDLE_CMD_DEVICE_RESET 0x0010
27c868c2
MW
2210#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
2211#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
1da177e4
LT
2212#define IDLE_CMD_SCSIREQ 0x0080
2213
2214#define IDLE_CMD_STATUS_SUCCESS 0x0001
2215#define IDLE_CMD_STATUS_FAILURE 0x0002
2216
2217/*
2218 * AdvSendIdleCmd() flag definitions.
2219 */
2220#define ADV_NOWAIT 0x01
2221
2222/*
2223 * Wait loop time out values.
2224 */
27c868c2
MW
2225#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
2226#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
2227#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
2228#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
2229#define SCSI_MAX_RETRY 10 /* retry count */
1da177e4 2230
27c868c2
MW
2231#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
2232#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
2233#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
2234#define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
1da177e4 2235
27c868c2 2236#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
1da177e4
LT
2237
2238/*
2239 * Device drivers must define the following functions.
2240 */
27c868c2
MW
2241static inline ulong DvcEnterCritical(void);
2242static inline void DvcLeaveCritical(ulong);
2243static void DvcSleepMilliSecond(ADV_DCNT);
27c868c2
MW
2244static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2245 uchar *, ASC_SDCNT *, int);
2246static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
1da177e4
LT
2247
2248/*
2249 * Adv Library functions available to drivers.
2250 */
27c868c2
MW
2251static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2252static int AdvISR(ADV_DVC_VAR *);
27c868c2
MW
2253static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2254static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
2255static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
2256static int AdvResetChipAndSB(ADV_DVC_VAR *);
2257static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
1da177e4
LT
2258
2259/*
2260 * Internal Adv Library functions.
2261 */
27c868c2 2262static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
27c868c2
MW
2263static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
2264static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
2265static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
2266static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2267static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2268static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2269static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2270static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2271static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2272static void AdvWaitEEPCmd(AdvPortAddr);
2273static ushort AdvReadEEPWord(AdvPortAddr, int);
1da177e4 2274
1da177e4
LT
2275/* Read byte from a register. */
2276#define AdvReadByteRegister(iop_base, reg_off) \
2277 (ADV_MEM_READB((iop_base) + (reg_off)))
2278
2279/* Write byte to a register. */
2280#define AdvWriteByteRegister(iop_base, reg_off, byte) \
2281 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2282
2283/* Read word (2 bytes) from a register. */
2284#define AdvReadWordRegister(iop_base, reg_off) \
2285 (ADV_MEM_READW((iop_base) + (reg_off)))
2286
2287/* Write word (2 bytes) to a register. */
2288#define AdvWriteWordRegister(iop_base, reg_off, word) \
2289 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2290
2291/* Write dword (4 bytes) to a register. */
2292#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2293 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2294
2295/* Read byte from LRAM. */
2296#define AdvReadByteLram(iop_base, addr, byte) \
2297do { \
2298 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2299 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2300} while (0)
2301
2302/* Write byte to LRAM. */
2303#define AdvWriteByteLram(iop_base, addr, byte) \
2304 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2305 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2306
2307/* Read word (2 bytes) from LRAM. */
2308#define AdvReadWordLram(iop_base, addr, word) \
2309do { \
2310 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2311 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2312} while (0)
2313
2314/* Write word (2 bytes) to LRAM. */
2315#define AdvWriteWordLram(iop_base, addr, word) \
2316 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2317 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2318
2319/* Write little-endian double word (4 bytes) to LRAM */
2320/* Because of unspecified C language ordering don't use auto-increment. */
2321#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2322 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2323 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2324 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2325 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2326 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2327 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2328
2329/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2330#define AdvReadWordAutoIncLram(iop_base) \
2331 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2332
2333/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2334#define AdvWriteWordAutoIncLram(iop_base, word) \
2335 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2336
1da177e4
LT
2337/*
2338 * Define macro to check for Condor signature.
2339 *
2340 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2341 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2342 */
2343#define AdvFindSignature(iop_base) \
2344 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2345 ADV_CHIP_ID_BYTE) && \
2346 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2347 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
2348
2349/*
2350 * Define macro to Return the version number of the chip at 'iop_base'.
2351 *
2352 * The second parameter 'bus_type' is currently unused.
2353 */
2354#define AdvGetChipVersion(iop_base, bus_type) \
2355 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2356
2357/*
2358 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2359 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2360 *
2361 * If the request has not yet been sent to the device it will simply be
2362 * aborted from RISC memory. If the request is disconnected it will be
2363 * aborted on reselection by sending an Abort Message to the target ID.
2364 *
2365 * Return value:
2366 * ADV_TRUE(1) - Queue was successfully aborted.
2367 * ADV_FALSE(0) - Queue was not found on the active queue list.
2368 */
2369#define AdvAbortQueue(asc_dvc, scsiq) \
2370 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2371 (ADV_DCNT) (scsiq))
2372
2373/*
2374 * Send a Bus Device Reset Message to the specified target ID.
2375 *
2376 * All outstanding commands will be purged if sending the
2377 * Bus Device Reset Message is successful.
2378 *
2379 * Return Value:
2380 * ADV_TRUE(1) - All requests on the target are purged.
2381 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2382 * are not purged.
2383 */
2384#define AdvResetDevice(asc_dvc, target_id) \
2385 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2386 (ADV_DCNT) (target_id))
2387
2388/*
2389 * SCSI Wide Type definition.
2390 */
2391#define ADV_SCSI_BIT_ID_TYPE ushort
2392
2393/*
2394 * AdvInitScsiTarget() 'cntl_flag' options.
2395 */
2396#define ADV_SCAN_LUN 0x01
2397#define ADV_CAPINFO_NOLUN 0x02
2398
2399/*
2400 * Convert target id to target id bit mask.
2401 */
2402#define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
2403
2404/*
2405 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2406 */
2407
27c868c2 2408#define QD_NO_STATUS 0x00 /* Request not completed yet. */
1da177e4
LT
2409#define QD_NO_ERROR 0x01
2410#define QD_ABORTED_BY_HOST 0x02
2411#define QD_WITH_ERROR 0x04
2412
2413#define QHSTA_NO_ERROR 0x00
2414#define QHSTA_M_SEL_TIMEOUT 0x11
2415#define QHSTA_M_DATA_OVER_RUN 0x12
2416#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2417#define QHSTA_M_QUEUE_ABORTED 0x15
27c868c2
MW
2418#define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
2419#define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
2420#define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
2421#define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
2422#define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
2423#define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
2424#define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
1da177e4 2425/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
27c868c2
MW
2426#define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
2427#define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
2428#define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
2429#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
2430#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
2431#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
2432#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
2433#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
1da177e4
LT
2434#define QHSTA_M_WTM_TIMEOUT 0x41
2435#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
2436#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
2437#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
27c868c2
MW
2438#define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
2439#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
2440#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
1da177e4 2441
1da177e4
LT
2442/*
2443 * DvcGetPhyAddr() flag arguments
2444 */
27c868c2
MW
2445#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
2446#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
2447#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
2448#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
2449#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
2450#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
1da177e4
LT
2451
2452/* Return the address that is aligned at the next doubleword >= to 'addr'. */
2453#define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
2454#define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
2455#define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
2456
2457/*
2458 * Total contiguous memory needed for driver SG blocks.
2459 *
2460 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2461 * number of scatter-gather elements the driver supports in a
2462 * single request.
2463 */
2464
2465#define ADV_SG_LIST_MAX_BYTE_SIZE \
2466 (sizeof(ADV_SG_BLOCK) * \
2467 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2468
1da177e4
LT
2469/*
2470 * --- Driver Constants and Macros
2471 */
2472
1da177e4
LT
2473/* Reference Scsi_Host hostdata */
2474#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2475
2476/* asc_board_t flags */
2477#define ASC_HOST_IN_RESET 0x01
27c868c2 2478#define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
1da177e4
LT
2479#define ASC_SELECT_QUEUE_DEPTHS 0x08
2480
2481#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2482#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
2483
27c868c2 2484#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
1da177e4 2485
27c868c2 2486#define ASC_INFO_SIZE 128 /* advansys_info() line size */
1da177e4
LT
2487
2488#ifdef CONFIG_PROC_FS
2489/* /proc/scsi/advansys/[0...] related definitions */
2490#define ASC_PRTBUF_SIZE 2048
2491#define ASC_PRTLINE_SIZE 160
2492
2493#define ASC_PRT_NEXT() \
2494 if (cp) { \
2495 totlen += len; \
2496 leftlen -= len; \
2497 if (leftlen == 0) { \
2498 return totlen; \
2499 } \
2500 cp += len; \
2501 }
2502#endif /* CONFIG_PROC_FS */
2503
2504/* Asc Library return codes */
2505#define ASC_TRUE 1
2506#define ASC_FALSE 0
2507#define ASC_NOERROR 1
2508#define ASC_BUSY 0
2509#define ASC_ERROR (-1)
2510
2511/* struct scsi_cmnd function return codes */
2512#define STATUS_BYTE(byte) (byte)
2513#define MSG_BYTE(byte) ((byte) << 8)
2514#define HOST_BYTE(byte) ((byte) << 16)
2515#define DRIVER_BYTE(byte) ((byte) << 24)
2516
2517/*
2518 * The following definitions and macros are OS independent interfaces to
2519 * the queue functions:
2520 * REQ - SCSI request structure
2521 * REQP - pointer to SCSI request structure
2522 * REQPTID(reqp) - reqp's target id
2523 * REQPNEXT(reqp) - reqp's next pointer
2524 * REQPNEXTP(reqp) - pointer to reqp's next pointer
2525 * REQPTIME(reqp) - reqp's time stamp value
2526 * REQTIMESTAMP() - system time stamp value
2527 */
27c868c2 2528typedef struct scsi_cmnd REQ, *REQP;
1da177e4
LT
2529#define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
2530#define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
2531#define REQPTID(reqp) ((reqp)->device->id)
2532#define REQPTIME(reqp) ((reqp)->SCp.this_residual)
2533#define REQTIMESTAMP() (jiffies)
2534
2535#define REQTIMESTAT(function, ascq, reqp, tid) \
2536{ \
2537 /*
2538 * If the request time stamp is less than the system time stamp, then \
2539 * maybe the system time stamp wrapped. Set the request time to zero.\
2540 */ \
2541 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
2542 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
2543 } else { \
2544 /* Indicate an error occurred with the assertion. */ \
2545 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
2546 REQPTIME(reqp) = 0; \
2547 } \
2548 /* Handle first minimum time case without external initialization. */ \
2549 if (((ascq)->q_tot_cnt[tid] == 1) || \
2550 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
2551 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
2552 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
2553 (function), (tid), (ascq)->q_min_tim[tid]); \
2554 } \
2555 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
2556 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
2557 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
2558 (function), tid, (ascq)->q_max_tim[tid]); \
2559 } \
2560 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
2561 /* Reset the time stamp field. */ \
2562 REQPTIME(reqp) = 0; \
2563}
2564
2565/* asc_enqueue() flags */
2566#define ASC_FRONT 1
2567#define ASC_BACK 2
2568
2569/* asc_dequeue_list() argument */
2570#define ASC_TID_ALL (-1)
2571
2572/* Return non-zero, if the queue is empty. */
2573#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
2574
1da177e4 2575#ifndef ADVANSYS_STATS
27c868c2
MW
2576#define ASC_STATS(shost, counter)
2577#define ASC_STATS_ADD(shost, counter, count)
1da177e4 2578#else /* ADVANSYS_STATS */
27c868c2
MW
2579#define ASC_STATS(shost, counter) \
2580 (ASC_BOARDP(shost)->asc_stats.counter++)
1da177e4 2581
27c868c2
MW
2582#define ASC_STATS_ADD(shost, counter, count) \
2583 (ASC_BOARDP(shost)->asc_stats.counter += (count))
1da177e4
LT
2584#endif /* ADVANSYS_STATS */
2585
2586#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2587
2588/* If the result wraps when calculating tenths, return 0. */
2589#define ASC_TENTHS(num, den) \
2590 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2591 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2592
2593/*
2594 * Display a message to the console.
2595 */
2596#define ASC_PRINT(s) \
2597 { \
2598 printk("advansys: "); \
2599 printk(s); \
2600 }
2601
2602#define ASC_PRINT1(s, a1) \
2603 { \
2604 printk("advansys: "); \
2605 printk((s), (a1)); \
2606 }
2607
2608#define ASC_PRINT2(s, a1, a2) \
2609 { \
2610 printk("advansys: "); \
2611 printk((s), (a1), (a2)); \
2612 }
2613
2614#define ASC_PRINT3(s, a1, a2, a3) \
2615 { \
2616 printk("advansys: "); \
2617 printk((s), (a1), (a2), (a3)); \
2618 }
2619
2620#define ASC_PRINT4(s, a1, a2, a3, a4) \
2621 { \
2622 printk("advansys: "); \
2623 printk((s), (a1), (a2), (a3), (a4)); \
2624 }
2625
1da177e4
LT
2626#ifndef ADVANSYS_DEBUG
2627
2628#define ASC_DBG(lvl, s)
2629#define ASC_DBG1(lvl, s, a1)
2630#define ASC_DBG2(lvl, s, a1, a2)
2631#define ASC_DBG3(lvl, s, a1, a2, a3)
2632#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2633#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2634#define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2635#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2636#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2637#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2638#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2639#define ASC_DBG_PRT_HEX(lvl, name, start, length)
2640#define ASC_DBG_PRT_CDB(lvl, cdb, len)
2641#define ASC_DBG_PRT_SENSE(lvl, sense, len)
2642#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2643
2644#else /* ADVANSYS_DEBUG */
2645
2646/*
2647 * Debugging Message Levels:
2648 * 0: Errors Only
2649 * 1: High-Level Tracing
2650 * 2-N: Verbose Tracing
2651 */
2652
2653#define ASC_DBG(lvl, s) \
2654 { \
2655 if (asc_dbglvl >= (lvl)) { \
2656 printk(s); \
2657 } \
2658 }
2659
2660#define ASC_DBG1(lvl, s, a1) \
2661 { \
2662 if (asc_dbglvl >= (lvl)) { \
2663 printk((s), (a1)); \
2664 } \
2665 }
2666
2667#define ASC_DBG2(lvl, s, a1, a2) \
2668 { \
2669 if (asc_dbglvl >= (lvl)) { \
2670 printk((s), (a1), (a2)); \
2671 } \
2672 }
2673
2674#define ASC_DBG3(lvl, s, a1, a2, a3) \
2675 { \
2676 if (asc_dbglvl >= (lvl)) { \
2677 printk((s), (a1), (a2), (a3)); \
2678 } \
2679 }
2680
2681#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2682 { \
2683 if (asc_dbglvl >= (lvl)) { \
2684 printk((s), (a1), (a2), (a3), (a4)); \
2685 } \
2686 }
2687
2688#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2689 { \
2690 if (asc_dbglvl >= (lvl)) { \
2691 asc_prt_scsi_host(s); \
2692 } \
2693 }
2694
2695#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2696 { \
2697 if (asc_dbglvl >= (lvl)) { \
2698 asc_prt_scsi_cmnd(s); \
2699 } \
2700 }
2701
2702#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2703 { \
2704 if (asc_dbglvl >= (lvl)) { \
2705 asc_prt_asc_scsi_q(scsiqp); \
2706 } \
2707 }
2708
2709#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2710 { \
2711 if (asc_dbglvl >= (lvl)) { \
2712 asc_prt_asc_qdone_info(qdone); \
2713 } \
2714 }
2715
2716#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2717 { \
2718 if (asc_dbglvl >= (lvl)) { \
2719 asc_prt_adv_scsi_req_q(scsiqp); \
2720 } \
2721 }
2722
2723#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2724 { \
2725 if (asc_dbglvl >= (lvl)) { \
2726 asc_prt_hex((name), (start), (length)); \
2727 } \
2728 }
2729
2730#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2731 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2732
2733#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2734 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2735
2736#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2737 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2738#endif /* ADVANSYS_DEBUG */
2739
2740#ifndef ADVANSYS_ASSERT
2741#define ASC_ASSERT(a)
2742#else /* ADVANSYS_ASSERT */
2743
2744#define ASC_ASSERT(a) \
2745 { \
2746 if (!(a)) { \
2747 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
2748 __FILE__, __LINE__); \
2749 } \
2750 }
2751
2752#endif /* ADVANSYS_ASSERT */
2753
1da177e4
LT
2754/*
2755 * --- Driver Structures
2756 */
2757
2758#ifdef ADVANSYS_STATS
2759
2760/* Per board statistics structure */
2761struct asc_stats {
27c868c2
MW
2762 /* Driver Entrypoint Statistics */
2763 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
2764 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
2765 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
2766 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
2767 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
2768 ADV_DCNT done; /* # calls to request's scsi_done function */
2769 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
2770 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
2771 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
2772 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2773 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
2774 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
2775 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
2776 ADV_DCNT exe_unknown; /* # unknown returns. */
2777 /* Data Transfer Statistics */
2778 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
2779 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
2780 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
2781 ADV_DCNT sg_elem; /* # scatter-gather elements */
2782 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
1da177e4
LT
2783};
2784#endif /* ADVANSYS_STATS */
2785
2786/*
2787 * Request queuing structure
2788 */
2789typedef struct asc_queue {
27c868c2
MW
2790 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
2791 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
2792 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
1da177e4 2793#ifdef ADVANSYS_STATS
27c868c2
MW
2794 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
2795 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
2796 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
2797 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
2798 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
2799 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
2800#endif /* ADVANSYS_STATS */
1da177e4
LT
2801} asc_queue_t;
2802
2803/*
2804 * Adv Library Request Structures
2805 *
2806 * The following two structures are used to process Wide Board requests.
2807 *
2808 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2809 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2810 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2811 * Mid-Level SCSI request structure.
2812 *
2813 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2814 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2815 * up to 255 scatter-gather elements may be used per request or
2816 * ADV_SCSI_REQ_Q.
2817 *
2818 * Both structures must be 32 byte aligned.
2819 */
2820typedef struct adv_sgblk {
27c868c2
MW
2821 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
2822 uchar align[32]; /* Sgblock structure padding. */
2823 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
1da177e4
LT
2824} adv_sgblk_t;
2825
2826typedef struct adv_req {
27c868c2
MW
2827 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
2828 uchar align[32]; /* Request structure padding. */
2829 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
2830 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
2831 struct adv_req *next_reqp; /* Next Request Structure. */
1da177e4
LT
2832} adv_req_t;
2833
2834/*
2835 * Structure allocated for each board.
2836 *
8dfb5379 2837 * This structure is allocated by scsi_host_alloc() at the end
1da177e4
LT
2838 * of the 'Scsi_Host' structure starting at the 'hostdata'
2839 * field. It is guaranteed to be allocated from DMA-able memory.
2840 */
2841typedef struct asc_board {
394dbf3f 2842 struct device *dev;
27c868c2
MW
2843 int id; /* Board Id */
2844 uint flags; /* Board flags */
2845 union {
2846 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
2847 ADV_DVC_VAR adv_dvc_var; /* Wide board */
2848 } dvc_var;
2849 union {
2850 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
2851 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
2852 } dvc_cfg;
2853 ushort asc_n_io_port; /* Number I/O ports. */
2854 asc_queue_t active; /* Active command queue */
27c868c2
MW
2855 asc_queue_t done; /* Done command queue */
2856 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2857 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
2858 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2859 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
2860 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2861 union {
2862 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
2863 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
2864 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
2865 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
2866 } eep_config;
2867 ulong last_reset; /* Saved last reset time */
2868 spinlock_t lock; /* Board spinlock */
27c868c2
MW
2869 /* /proc/scsi/advansys/[0...] */
2870 char *prtbuf; /* /proc print buffer */
1da177e4 2871#ifdef ADVANSYS_STATS
27c868c2
MW
2872 struct asc_stats asc_stats; /* Board statistics */
2873#endif /* ADVANSYS_STATS */
2874 /*
2875 * The following fields are used only for Narrow Boards.
2876 */
27c868c2
MW
2877 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
2878 /*
2879 * The following fields are used only for Wide Boards.
2880 */
2881 void __iomem *ioremap_addr; /* I/O Memory remap address. */
2882 ushort ioport; /* I/O Port address. */
b2c16f58 2883 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
27c868c2
MW
2884 adv_req_t *orig_reqp; /* adv_req_t memory block. */
2885 adv_req_t *adv_reqp; /* Request structures. */
2886 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
2887 ushort bios_signature; /* BIOS Signature. */
2888 ushort bios_version; /* BIOS Version. */
2889 ushort bios_codeseg; /* BIOS Code Segment. */
2890 ushort bios_codelen; /* BIOS Code Segment Length. */
1da177e4
LT
2891} asc_board_t;
2892
13ac2d9c
MW
2893#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2894 dvc_var.adv_dvc_var)
2895#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2896
1da177e4 2897/* Number of boards detected in system. */
78e77d8b
MW
2898static int asc_board_count;
2899
1da177e4 2900/* Overrun buffer used by all narrow boards. */
27c868c2 2901static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
1da177e4
LT
2902
2903/*
2904 * Global structures required to issue a command.
2905 */
27c868c2
MW
2906static ASC_SCSI_Q asc_scsi_q = { {0} };
2907static ASC_SG_HEAD asc_sg_head = { 0 };
1da177e4 2908
1da177e4 2909#ifdef ADVANSYS_DEBUG
27c868c2 2910static int asc_dbglvl = 3;
1da177e4
LT
2911#endif /* ADVANSYS_DEBUG */
2912
1da177e4
LT
2913/*
2914 * --- Driver Function Prototypes
1da177e4
LT
2915 */
2916
27c868c2
MW
2917static int advansys_slave_configure(struct scsi_device *);
2918static void asc_scsi_done_list(struct scsi_cmnd *);
2919static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
2920static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
2921static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
2922static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
27c868c2 2923static void asc_enqueue(asc_queue_t *, REQP, int);
27c868c2
MW
2924static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
2925static int asc_rmqueue(asc_queue_t *, REQP);
1da177e4 2926#ifdef CONFIG_PROC_FS
27c868c2
MW
2927static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
2928static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
2929static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
2930static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
2931static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
2932static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
2933static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
2934static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
2935static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
2936static int asc_prt_line(char *, int, char *fmt, ...);
1da177e4
LT
2937#endif /* CONFIG_PROC_FS */
2938
1da177e4
LT
2939/* Statistics function prototypes. */
2940#ifdef ADVANSYS_STATS
2941#ifdef CONFIG_PROC_FS
27c868c2
MW
2942static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
2943static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
1da177e4
LT
2944#endif /* CONFIG_PROC_FS */
2945#endif /* ADVANSYS_STATS */
2946
2947/* Debug function prototypes. */
2948#ifdef ADVANSYS_DEBUG
27c868c2
MW
2949static void asc_prt_scsi_host(struct Scsi_Host *);
2950static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
2951static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
2952static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
2953static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
2954static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
2955static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
2956static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
2957static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
2958static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
2959static void asc_prt_hex(char *f, uchar *, int);
1da177e4
LT
2960#endif /* ADVANSYS_DEBUG */
2961
1da177e4
LT
2962#ifdef CONFIG_PROC_FS
2963/*
c304ec94 2964 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
1da177e4
LT
2965 *
2966 * *buffer: I/O buffer
2967 * **start: if inout == FALSE pointer into buffer where user read should start
2968 * offset: current offset into a /proc/scsi/advansys/[0...] file
2969 * length: length of buffer
2970 * hostno: Scsi_Host host_no
2971 * inout: TRUE - user is writing; FALSE - user is reading
2972 *
2973 * Return the number of bytes read from or written to a
2974 * /proc/scsi/advansys/[0...] file.
2975 *
2976 * Note: This function uses the per board buffer 'prtbuf' which is
2977 * allocated when the board is initialized in advansys_detect(). The
2978 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
2979 * used to write to the buffer. The way asc_proc_copy() is written
2980 * if 'prtbuf' is too small it will not be overwritten. Instead the
2981 * user just won't get all the available statistics.
2982 */
70c8d897 2983static int
1da177e4 2984advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
27c868c2 2985 off_t offset, int length, int inout)
1da177e4 2986{
27c868c2 2987 asc_board_t *boardp;
27c868c2
MW
2988 char *cp;
2989 int cplen;
2990 int cnt;
2991 int totcnt;
2992 int leftlen;
2993 char *curbuf;
2994 off_t advoffset;
1da177e4 2995#ifdef ADVANSYS_STATS
27c868c2 2996 int tgt_id;
1da177e4
LT
2997#endif /* ADVANSYS_STATS */
2998
27c868c2 2999 ASC_DBG(1, "advansys_proc_info: begin\n");
1da177e4 3000
27c868c2
MW
3001 /*
3002 * User write not supported.
3003 */
3004 if (inout == TRUE) {
3005 return (-ENOSYS);
3006 }
1da177e4 3007
27c868c2
MW
3008 /*
3009 * User read of /proc/scsi/advansys/[0...] file.
3010 */
1da177e4 3011
2a437959 3012 boardp = ASC_BOARDP(shost);
27c868c2
MW
3013
3014 /* Copy read data starting at the beginning of the buffer. */
3015 *start = buffer;
3016 curbuf = buffer;
3017 advoffset = 0;
3018 totcnt = 0;
3019 leftlen = length;
3020
3021 /*
3022 * Get board configuration information.
3023 *
3024 * advansys_info() returns the board string from its own static buffer.
3025 */
2a437959 3026 cp = (char *)advansys_info(shost);
27c868c2
MW
3027 strcat(cp, "\n");
3028 cplen = strlen(cp);
3029 /* Copy board information. */
3030 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3031 totcnt += cnt;
3032 leftlen -= cnt;
3033 if (leftlen == 0) {
3034 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3035 return totcnt;
3036 }
3037 advoffset += cplen;
3038 curbuf += cnt;
3039
3040 /*
3041 * Display Wide Board BIOS Information.
3042 */
3043 if (ASC_WIDE_BOARD(boardp)) {
3044 cp = boardp->prtbuf;
2a437959 3045 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3046 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
ecec1947 3047 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
27c868c2
MW
3048 cplen);
3049 totcnt += cnt;
3050 leftlen -= cnt;
3051 if (leftlen == 0) {
3052 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3053 return totcnt;
3054 }
3055 advoffset += cplen;
3056 curbuf += cnt;
3057 }
1da177e4 3058
27c868c2
MW
3059 /*
3060 * Display driver information for each device attached to the board.
3061 */
3062 cp = boardp->prtbuf;
2a437959 3063 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3064 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3065 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3066 totcnt += cnt;
3067 leftlen -= cnt;
3068 if (leftlen == 0) {
3069 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3070 return totcnt;
3071 }
3072 advoffset += cplen;
3073 curbuf += cnt;
3074
3075 /*
3076 * Display EEPROM configuration for the board.
3077 */
3078 cp = boardp->prtbuf;
3079 if (ASC_NARROW_BOARD(boardp)) {
2a437959 3080 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3081 } else {
2a437959 3082 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3083 }
3084 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3085 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3086 totcnt += cnt;
3087 leftlen -= cnt;
3088 if (leftlen == 0) {
3089 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3090 return totcnt;
3091 }
3092 advoffset += cplen;
3093 curbuf += cnt;
3094
3095 /*
3096 * Display driver configuration and information for the board.
3097 */
3098 cp = boardp->prtbuf;
2a437959 3099 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3100 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3101 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3102 totcnt += cnt;
3103 leftlen -= cnt;
3104 if (leftlen == 0) {
3105 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3106 return totcnt;
3107 }
3108 advoffset += cplen;
3109 curbuf += cnt;
1da177e4
LT
3110
3111#ifdef ADVANSYS_STATS
27c868c2
MW
3112 /*
3113 * Display driver statistics for the board.
3114 */
3115 cp = boardp->prtbuf;
2a437959 3116 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3117 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3118 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3119 totcnt += cnt;
3120 leftlen -= cnt;
3121 if (leftlen == 0) {
3122 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3123 return totcnt;
3124 }
3125 advoffset += cplen;
3126 curbuf += cnt;
3127
3128 /*
3129 * Display driver statistics for each target.
3130 */
3131 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
3132 cp = boardp->prtbuf;
2a437959 3133 cplen = asc_prt_target_stats(shost, tgt_id, cp,
ecec1947 3134 ASC_PRTBUF_SIZE);
27c868c2 3135 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
ecec1947
MW
3136 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3137 cplen);
27c868c2
MW
3138 totcnt += cnt;
3139 leftlen -= cnt;
3140 if (leftlen == 0) {
3141 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3142 return totcnt;
3143 }
3144 advoffset += cplen;
3145 curbuf += cnt;
3146 }
1da177e4
LT
3147#endif /* ADVANSYS_STATS */
3148
27c868c2
MW
3149 /*
3150 * Display Asc Library dynamic configuration information
3151 * for the board.
3152 */
3153 cp = boardp->prtbuf;
3154 if (ASC_NARROW_BOARD(boardp)) {
2a437959 3155 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2 3156 } else {
2a437959 3157 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
27c868c2
MW
3158 }
3159 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3160 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3161 totcnt += cnt;
3162 leftlen -= cnt;
3163 if (leftlen == 0) {
3164 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3165 return totcnt;
3166 }
3167 advoffset += cplen;
3168 curbuf += cnt;
1da177e4 3169
27c868c2 3170 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
1da177e4 3171
27c868c2 3172 return totcnt;
1da177e4 3173}
1da177e4 3174#endif /* CONFIG_PROC_FS */
1da177e4
LT
3175
3176/*
3177 * advansys_info()
3178 *
3179 * Return suitable for printing on the console with the argument
3180 * adapter's configuration information.
3181 *
3182 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3183 * otherwise the static 'info' array will be overrun.
3184 */
27c868c2 3185static const char *advansys_info(struct Scsi_Host *shost)
1da177e4 3186{
27c868c2
MW
3187 static char info[ASC_INFO_SIZE];
3188 asc_board_t *boardp;
3189 ASC_DVC_VAR *asc_dvc_varp;
3190 ADV_DVC_VAR *adv_dvc_varp;
3191 char *busname;
27c868c2
MW
3192 char *widename = NULL;
3193
3194 boardp = ASC_BOARDP(shost);
3195 if (ASC_NARROW_BOARD(boardp)) {
3196 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3197 ASC_DBG(1, "advansys_info: begin\n");
3198 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3199 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3200 ASC_IS_ISAPNP) {
3201 busname = "ISA PnP";
3202 } else {
3203 busname = "ISA";
3204 }
27c868c2
MW
3205 sprintf(info,
3206 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3207 ASC_VERSION, busname,
3208 (ulong)shost->io_port,
4a2d31c8
MW
3209 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3210 shost->irq, shost->dma_channel);
27c868c2
MW
3211 } else {
3212 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3213 busname = "VL";
3214 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3215 busname = "EISA";
3216 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3217 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3218 == ASC_IS_PCI_ULTRA) {
3219 busname = "PCI Ultra";
3220 } else {
3221 busname = "PCI";
3222 }
3223 } else {
3224 busname = "?";
ecec1947
MW
3225 ASC_PRINT2("advansys_info: board %d: unknown "
3226 "bus type %d\n", boardp->id,
3227 asc_dvc_varp->bus_type);
27c868c2 3228 }
27c868c2
MW
3229 sprintf(info,
3230 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
ecec1947 3231 ASC_VERSION, busname, (ulong)shost->io_port,
4a2d31c8
MW
3232 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3233 shost->irq);
27c868c2
MW
3234 }
3235 } else {
3236 /*
3237 * Wide Adapter Information
3238 *
3239 * Memory-mapped I/O is used instead of I/O space to access
3240 * the adapter, but display the I/O Port range. The Memory
3241 * I/O address is displayed through the driver /proc file.
3242 */
3243 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3244 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
27c868c2
MW
3245 widename = "Ultra-Wide";
3246 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
27c868c2
MW
3247 widename = "Ultra2-Wide";
3248 } else {
27c868c2
MW
3249 widename = "Ultra3-Wide";
3250 }
3251 sprintf(info,
3252 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3253 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4a2d31c8 3254 (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
27c868c2
MW
3255 }
3256 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
3257 ASC_DBG(1, "advansys_info: end\n");
3258 return info;
1da177e4
LT
3259}
3260
3261/*
3262 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
3263 *
3264 * This function always returns 0. Command return status is saved
3265 * in the 'scp' result field.
3266 */
70c8d897 3267static int
27c868c2 3268advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
1da177e4 3269{
27c868c2
MW
3270 struct Scsi_Host *shost;
3271 asc_board_t *boardp;
3272 ulong flags;
3273 struct scsi_cmnd *done_scp;
b6622925 3274 int asc_res, result = 0;
1da177e4 3275
27c868c2
MW
3276 shost = scp->device->host;
3277 boardp = ASC_BOARDP(shost);
3278 ASC_STATS(shost, queuecommand);
1da177e4 3279
27c868c2
MW
3280 /* host_lock taken by mid-level prior to call but need to protect */
3281 /* against own ISR */
3282 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 3283
27c868c2 3284 scp->scsi_done = done;
b6622925
MW
3285 asc_res = asc_execute_scsi_cmnd(scp);
3286 switch (asc_res) {
27c868c2
MW
3287 case ASC_NOERROR:
3288 break;
3289 case ASC_BUSY:
b6622925 3290 result = SCSI_MLQUEUE_HOST_BUSY;
27c868c2
MW
3291 break;
3292 case ASC_ERROR:
3293 default:
3294 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
3295 /* Interrupts could be enabled here. */
3296 asc_scsi_done_list(done_scp);
3297 break;
3298 }
3299 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3300
b6622925 3301 return result;
1da177e4
LT
3302}
3303
3304/*
3305 * advansys_reset()
3306 *
3307 * Reset the bus associated with the command 'scp'.
3308 *
3309 * This function runs its own thread. Interrupts must be blocked but
3310 * sleeping is allowed and no locking other than for host structures is
3311 * required. Returns SUCCESS or FAILED.
3312 */
27c868c2 3313static int advansys_reset(struct scsi_cmnd *scp)
1da177e4 3314{
27c868c2
MW
3315 struct Scsi_Host *shost;
3316 asc_board_t *boardp;
3317 ASC_DVC_VAR *asc_dvc_varp;
3318 ADV_DVC_VAR *adv_dvc_varp;
3319 ulong flags;
3320 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
3321 struct scsi_cmnd *tscp, *new_last_scp;
3322 int status;
3323 int ret = SUCCESS;
3324
3325 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
1da177e4
LT
3326
3327#ifdef ADVANSYS_STATS
27c868c2
MW
3328 if (scp->device->host != NULL) {
3329 ASC_STATS(scp->device->host, reset);
3330 }
1da177e4
LT
3331#endif /* ADVANSYS_STATS */
3332
27c868c2
MW
3333 if ((shost = scp->device->host) == NULL) {
3334 scp->result = HOST_BYTE(DID_ERROR);
3335 return FAILED;
3336 }
1da177e4 3337
27c868c2 3338 boardp = ASC_BOARDP(shost);
1da177e4 3339
27c868c2
MW
3340 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
3341 boardp->id);
3342 /*
3343 * Check for re-entrancy.
3344 */
1da177e4 3345 spin_lock_irqsave(&boardp->lock, flags);
27c868c2
MW
3346 if (boardp->flags & ASC_HOST_IN_RESET) {
3347 spin_unlock_irqrestore(&boardp->lock, flags);
3348 return FAILED;
3349 }
3350 boardp->flags |= ASC_HOST_IN_RESET;
3351 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3352
27c868c2
MW
3353 if (ASC_NARROW_BOARD(boardp)) {
3354 /*
3355 * Narrow Board
3356 */
3357 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
1da177e4 3358
27c868c2
MW
3359 /*
3360 * Reset the chip and SCSI bus.
3361 */
3362 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
3363 status = AscInitAsc1000Driver(asc_dvc_varp);
3364
3365 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
3366 if (asc_dvc_varp->err_code) {
ecec1947
MW
3367 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3368 "error: 0x%x\n", boardp->id,
3369 asc_dvc_varp->err_code);
27c868c2
MW
3370 ret = FAILED;
3371 } else if (status) {
ecec1947
MW
3372 ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3373 "warning: 0x%x\n", boardp->id, status);
27c868c2 3374 } else {
ecec1947
MW
3375 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3376 "successful.\n", boardp->id);
27c868c2
MW
3377 }
3378
3379 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
3380 spin_lock_irqsave(&boardp->lock, flags);
1da177e4 3381
27c868c2
MW
3382 } else {
3383 /*
3384 * Wide Board
3385 *
3386 * If the suggest reset bus flags are set, then reset the bus.
3387 * Otherwise only reset the device.
3388 */
3389 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
1da177e4 3390
27c868c2
MW
3391 /*
3392 * Reset the target's SCSI bus.
3393 */
3394 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
3395 switch (AdvResetChipAndSB(adv_dvc_varp)) {
3396 case ASC_TRUE:
ecec1947
MW
3397 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3398 "successful.\n", boardp->id);
27c868c2
MW
3399 break;
3400 case ASC_FALSE:
3401 default:
ecec1947
MW
3402 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3403 "error.\n", boardp->id);
27c868c2
MW
3404 ret = FAILED;
3405 break;
3406 }
3407 spin_lock_irqsave(&boardp->lock, flags);
3408 (void)AdvISR(adv_dvc_varp);
3409 }
3410 /* Board lock is held. */
3411
3412 /*
3413 * Dequeue all board 'done' requests. A pointer to the last request
3414 * is returned in 'last_scp'.
3415 */
3416 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
3417
3418 /*
3419 * Dequeue all board 'active' requests for all devices and set
3420 * the request status to DID_RESET. A pointer to the last request
3421 * is returned in 'last_scp'.
3422 */
3423 if (done_scp == NULL) {
ecec1947
MW
3424 done_scp = asc_dequeue_list(&boardp->active, &last_scp,
3425 ASC_TID_ALL);
27c868c2
MW
3426 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
3427 tscp->result = HOST_BYTE(DID_RESET);
3428 }
3429 } else {
3430 /* Append to 'done_scp' at the end with 'last_scp'. */
3431 ASC_ASSERT(last_scp != NULL);
3432 last_scp->host_scribble =
3433 (unsigned char *)asc_dequeue_list(&boardp->active,
3434 &new_last_scp,
3435 ASC_TID_ALL);
3436 if (new_last_scp != NULL) {
3437 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
3438 for (tscp = REQPNEXT(last_scp); tscp;
3439 tscp = REQPNEXT(tscp)) {
3440 tscp->result = HOST_BYTE(DID_RESET);
3441 }
3442 last_scp = new_last_scp;
3443 }
3444 }
1da177e4 3445
27c868c2
MW
3446 /* Save the time of the most recently completed reset. */
3447 boardp->last_reset = jiffies;
1da177e4 3448
27c868c2
MW
3449 /* Clear reset flag. */
3450 boardp->flags &= ~ASC_HOST_IN_RESET;
3451 spin_unlock_irqrestore(&boardp->lock, flags);
3452
3453 /*
3454 * Complete all the 'done_scp' requests.
3455 */
ecec1947 3456 if (done_scp)
27c868c2 3457 asc_scsi_done_list(done_scp);
1da177e4 3458
27c868c2 3459 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
1da177e4 3460
27c868c2 3461 return ret;
1da177e4
LT
3462}
3463
3464/*
3465 * advansys_biosparam()
3466 *
3467 * Translate disk drive geometry if the "BIOS greater than 1 GB"
3468 * support is enabled for a drive.
3469 *
3470 * ip (information pointer) is an int array with the following definition:
3471 * ip[0]: heads
3472 * ip[1]: sectors
3473 * ip[2]: cylinders
3474 */
70c8d897 3475static int
1da177e4 3476advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
27c868c2 3477 sector_t capacity, int ip[])
1da177e4 3478{
27c868c2
MW
3479 asc_board_t *boardp;
3480
3481 ASC_DBG(1, "advansys_biosparam: begin\n");
3482 ASC_STATS(sdev->host, biosparam);
3483 boardp = ASC_BOARDP(sdev->host);
3484 if (ASC_NARROW_BOARD(boardp)) {
3485 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
3486 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
3487 ip[0] = 255;
3488 ip[1] = 63;
3489 } else {
3490 ip[0] = 64;
3491 ip[1] = 32;
3492 }
3493 } else {
3494 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
3495 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
3496 ip[0] = 255;
3497 ip[1] = 63;
3498 } else {
3499 ip[0] = 64;
3500 ip[1] = 32;
3501 }
3502 }
3503 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
3504 ASC_DBG(1, "advansys_biosparam: end\n");
3505 return 0;
1da177e4
LT
3506}
3507
8dfb5379 3508static struct scsi_host_template advansys_template = {
27c868c2 3509 .proc_name = "advansys",
1da177e4 3510#ifdef CONFIG_PROC_FS
27c868c2 3511 .proc_info = advansys_proc_info,
1da177e4 3512#endif
27c868c2 3513 .name = "advansys",
27c868c2
MW
3514 .info = advansys_info,
3515 .queuecommand = advansys_queuecommand,
3516 .eh_bus_reset_handler = advansys_reset,
3517 .bios_param = advansys_biosparam,
3518 .slave_configure = advansys_slave_configure,
3519 /*
3520 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
8dfb5379
MW
3521 * must be set. The flag will be cleared in advansys_board_found
3522 * for non-ISA adapters.
27c868c2
MW
3523 */
3524 .unchecked_isa_dma = 1,
3525 /*
3526 * All adapters controlled by this driver are capable of large
3527 * scatter-gather lists. According to the mid-level SCSI documentation
3528 * this obviates any performance gain provided by setting
3529 * 'use_clustering'. But empirically while CPU utilization is increased
3530 * by enabling clustering, I/O throughput increases as well.
3531 */
3532 .use_clustering = ENABLE_CLUSTERING,
1da177e4 3533};
1da177e4 3534
1da177e4
LT
3535/*
3536 * --- Miscellaneous Driver Functions
3537 */
3538
3539/*
3540 * First-level interrupt handler.
3541 *
3542 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
3543 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
3544 * is not referenced. 'dev_id' could be used to identify an interrupt passed
3545 * to the AdvanSys driver which is for a device sharing an interrupt with
3546 * an AdvanSys adapter.
3547 */
27c868c2 3548static irqreturn_t advansys_interrupt(int irq, void *dev_id)
1da177e4 3549{
074c8fe4 3550 unsigned long flags;
27c868c2
MW
3551 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
3552 struct scsi_cmnd *new_last_scp;
074c8fe4
MW
3553 struct Scsi_Host *shost = dev_id;
3554 asc_board_t *boardp = ASC_BOARDP(shost);
3555 irqreturn_t result = IRQ_NONE;
27c868c2 3556
074c8fe4
MW
3557 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
3558 spin_lock_irqsave(&boardp->lock, flags);
3559 if (ASC_NARROW_BOARD(boardp)) {
3560 /*
3561 * Narrow Board
3562 */
3563 if (AscIsIntPending(shost->io_port)) {
3564 result = IRQ_HANDLED;
3565 ASC_STATS(shost, interrupt);
3566 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
3567 AscISR(&boardp->dvc_var.asc_dvc_var);
3568 }
3569 } else {
3570 /*
3571 * Wide Board
3572 */
3573 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
3574 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
3575 result = IRQ_HANDLED;
3576 ASC_STATS(shost, interrupt);
3577 }
3578 }
27c868c2
MW
3579
3580 /*
b6622925 3581 * Create a list of completed requests.
074c8fe4
MW
3582 *
3583 * If a reset request is being performed for the board, the reset
3584 * handler will complete pending requests after it has completed.
3585 */
3586 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
3587 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
3588 "last_scp 0x%p\n", done_scp, last_scp);
3589
27c868c2 3590 /*
074c8fe4 3591 * Add to the list of requests that must be completed.
27c868c2 3592 *
074c8fe4
MW
3593 * 'done_scp' will always be NULL on the first iteration of
3594 * this loop. 'last_scp' is set at the same time as 'done_scp'.
27c868c2 3595 */
074c8fe4
MW
3596 if (done_scp == NULL) {
3597 done_scp = asc_dequeue_list(&boardp->done,
3598 &last_scp, ASC_TID_ALL);
3599 } else {
3600 ASC_ASSERT(last_scp != NULL);
3601 last_scp->host_scribble =
3602 (unsigned char *)asc_dequeue_list(&boardp->
3603 done,
3604 &new_last_scp,
3605 ASC_TID_ALL);
3606 if (new_last_scp != NULL) {
3607 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
3608 last_scp = new_last_scp;
27c868c2
MW
3609 }
3610 }
27c868c2 3611 }
074c8fe4 3612 spin_unlock_irqrestore(&boardp->lock, flags);
1da177e4 3613
27c868c2
MW
3614 /*
3615 * If interrupts were enabled on entry, then they
3616 * are now enabled here.
3617 *
3618 * Complete all requests on the done list.
3619 */
1da177e4 3620
27c868c2 3621 asc_scsi_done_list(done_scp);
1da177e4 3622
27c868c2 3623 ASC_DBG(1, "advansys_interrupt: end\n");
074c8fe4 3624 return result;
1da177e4
LT
3625}
3626
47d853cc
MW
3627static void
3628advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
3629{
3630 ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
3631 ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
3632
3633 if (sdev->lun == 0) {
3634 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
3635 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
3636 asc_dvc->init_sdtr |= tid_bit;
3637 } else {
3638 asc_dvc->init_sdtr &= ~tid_bit;
3639 }
3640
3641 if (orig_init_sdtr != asc_dvc->init_sdtr)
3642 AscAsyncFix(asc_dvc, sdev);
3643 }
3644
3645 if (sdev->tagged_supported) {
3646 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
3647 if (sdev->lun == 0) {
3648 asc_dvc->cfg->can_tagged_qng |= tid_bit;
3649 asc_dvc->use_tagged_qng |= tid_bit;
3650 }
3651 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3652 asc_dvc->max_dvc_qng[sdev->id]);
3653 }
3654 } else {
3655 if (sdev->lun == 0) {
3656 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
3657 asc_dvc->use_tagged_qng &= ~tid_bit;
3658 }
3659 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
3660 }
3661
3662 if ((sdev->lun == 0) &&
3663 (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
3664 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
3665 asc_dvc->cfg->disc_enable);
3666 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
3667 asc_dvc->use_tagged_qng);
3668 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
3669 asc_dvc->cfg->can_tagged_qng);
3670
3671 asc_dvc->max_dvc_qng[sdev->id] =
3672 asc_dvc->cfg->max_tag_qng[sdev->id];
3673 AscWriteLramByte(asc_dvc->iop_base,
3674 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
3675 asc_dvc->max_dvc_qng[sdev->id]);
3676 }
3677}
3678
1da177e4 3679/*
47d853cc
MW
3680 * Wide Transfers
3681 *
3682 * If the EEPROM enabled WDTR for the device and the device supports wide
3683 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
3684 * write the new value to the microcode.
1da177e4 3685 */
47d853cc
MW
3686static void
3687advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
1da177e4 3688{
47d853cc
MW
3689 unsigned short cfg_word;
3690 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
3691 if ((cfg_word & tidmask) != 0)
3692 return;
3693
3694 cfg_word |= tidmask;
3695 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
1da177e4 3696
27c868c2 3697 /*
47d853cc
MW
3698 * Clear the microcode SDTR and WDTR negotiation done indicators for
3699 * the target to cause it to negotiate with the new setting set above.
3700 * WDTR when accepted causes the target to enter asynchronous mode, so
3701 * SDTR must be negotiated.
27c868c2 3702 */
47d853cc
MW
3703 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3704 cfg_word &= ~tidmask;
3705 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3706 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3707 cfg_word &= ~tidmask;
3708 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3709}
3710
3711/*
3712 * Synchronous Transfers
3713 *
3714 * If the EEPROM enabled SDTR for the device and the device
3715 * supports synchronous transfers, then turn on the device's
3716 * 'sdtr_able' bit. Write the new value to the microcode.
3717 */
3718static void
3719advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
3720{
3721 unsigned short cfg_word;
3722 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3723 if ((cfg_word & tidmask) != 0)
3724 return;
3725
3726 cfg_word |= tidmask;
3727 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3728
3729 /*
3730 * Clear the microcode "SDTR negotiation" done indicator for the
3731 * target to cause it to negotiate with the new setting set above.
3732 */
3733 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3734 cfg_word &= ~tidmask;
3735 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3736}
3737
3738/*
3739 * PPR (Parallel Protocol Request) Capable
3740 *
3741 * If the device supports DT mode, then it must be PPR capable.
3742 * The PPR message will be used in place of the SDTR and WDTR
3743 * messages to negotiate synchronous speed and offset, transfer
3744 * width, and protocol options.
3745 */
3746static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
3747 AdvPortAddr iop_base, unsigned short tidmask)
3748{
3749 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3750 adv_dvc->ppr_able |= tidmask;
3751 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3752}
3753
3754static void
3755advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
3756{
3757 AdvPortAddr iop_base = adv_dvc->iop_base;
3758 unsigned short tidmask = 1 << sdev->id;
3759
3760 if (sdev->lun == 0) {
3761 /*
3762 * Handle WDTR, SDTR, and Tag Queuing. If the feature
3763 * is enabled in the EEPROM and the device supports the
3764 * feature, then enable it in the microcode.
3765 */
3766
3767 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
3768 advansys_wide_enable_wdtr(iop_base, tidmask);
3769 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
3770 advansys_wide_enable_sdtr(iop_base, tidmask);
3771 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
3772 advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
3773
3774 /*
3775 * Tag Queuing is disabled for the BIOS which runs in polled
3776 * mode and would see no benefit from Tag Queuing. Also by
3777 * disabling Tag Queuing in the BIOS devices with Tag Queuing
3778 * bugs will at least work with the BIOS.
3779 */
3780 if ((adv_dvc->tagqng_able & tidmask) &&
3781 sdev->tagged_supported) {
3782 unsigned short cfg_word;
3783 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
3784 cfg_word |= tidmask;
3785 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
3786 cfg_word);
3787 AdvWriteByteLram(iop_base,
3788 ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
3789 adv_dvc->max_dvc_qng);
27c868c2 3790 }
47d853cc
MW
3791 }
3792
3793 if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
3794 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3795 adv_dvc->max_dvc_qng);
27c868c2 3796 } else {
47d853cc 3797 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
27c868c2 3798 }
47d853cc
MW
3799}
3800
3801/*
3802 * Set the number of commands to queue per device for the
3803 * specified host adapter.
3804 */
3805static int advansys_slave_configure(struct scsi_device *sdev)
3806{
3807 asc_board_t *boardp = ASC_BOARDP(sdev->host);
3808 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
3809
3810 /*
3811 * Save a pointer to the sdev and set its initial/maximum
3812 * queue depth. Only save the pointer for a lun0 dev though.
3813 */
3814 if (sdev->lun == 0)
3815 boardp->device[sdev->id] = sdev;
3816
3817 if (ASC_NARROW_BOARD(boardp))
3818 advansys_narrow_slave_configure(sdev,
3819 &boardp->dvc_var.asc_dvc_var);
3820 else
3821 advansys_wide_slave_configure(sdev,
3822 &boardp->dvc_var.adv_dvc_var);
3823
27c868c2 3824 return 0;
1da177e4
LT
3825}
3826
3827/*
3828 * Complete all requests on the singly linked list pointed
3829 * to by 'scp'.
3830 *
3831 * Interrupts can be enabled on entry.
3832 */
27c868c2 3833static void asc_scsi_done_list(struct scsi_cmnd *scp)
1da177e4 3834{
27c868c2 3835 struct scsi_cmnd *tscp;
1da177e4 3836
27c868c2
MW
3837 ASC_DBG(2, "asc_scsi_done_list: begin\n");
3838 while (scp != NULL) {
3839 asc_board_t *boardp;
1da177e4 3840
27c868c2
MW
3841 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
3842 tscp = REQPNEXT(scp);
3843 scp->host_scribble = NULL;
1da177e4 3844
27c868c2 3845 boardp = ASC_BOARDP(scp->device->host);
1da177e4 3846
27c868c2 3847 if (scp->use_sg)
394dbf3f 3848 dma_unmap_sg(boardp->dev,
27c868c2
MW
3849 (struct scatterlist *)scp->request_buffer,
3850 scp->use_sg, scp->sc_data_direction);
3851 else if (scp->request_bufflen)
394dbf3f 3852 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
27c868c2
MW
3853 scp->request_bufflen,
3854 scp->sc_data_direction);
1da177e4 3855
27c868c2
MW
3856 ASC_STATS(scp->device->host, done);
3857 ASC_ASSERT(scp->scsi_done != NULL);
1da177e4 3858
27c868c2 3859 scp->scsi_done(scp);
1da177e4 3860
27c868c2
MW
3861 scp = tscp;
3862 }
3863 ASC_DBG(2, "asc_scsi_done_list: done\n");
3864 return;
1da177e4
LT
3865}
3866
3867/*
3868 * Execute a single 'Scsi_Cmnd'.
3869 *
3870 * The function 'done' is called when the request has been completed.
3871 *
3872 * Scsi_Cmnd:
3873 *
3874 * host - board controlling device
3875 * device - device to send command
3876 * target - target of device
3877 * lun - lun of device
3878 * cmd_len - length of SCSI CDB
3879 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
3880 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
3881 *
3882 * if (use_sg == 0) {
3883 * request_buffer - buffer address for request
3884 * request_bufflen - length of request buffer
3885 * } else {
3886 * request_buffer - pointer to scatterlist structure
3887 * }
3888 *
3889 * sense_buffer - sense command buffer
3890 *
3891 * result (4 bytes of an int):
3892 * Byte Meaning
3893 * 0 SCSI Status Byte Code
3894 * 1 SCSI One Byte Message Code
3895 * 2 Host Error Code
3896 * 3 Mid-Level Error Code
3897 *
3898 * host driver fields:
3899 * SCp - Scsi_Pointer used for command processing status
3900 * scsi_done - used to save caller's done function
3901 * host_scribble - used for pointer to another struct scsi_cmnd
3902 *
3903 * If this function returns ASC_NOERROR the request has been enqueued
3904 * on the board's 'active' queue and will be completed from the
3905 * interrupt handler.
3906 *
3907 * If this function returns ASC_NOERROR the request has been enqueued
3908 * on the board's 'done' queue and must be completed by the caller.
3909 *
b6622925
MW
3910 * If ASC_BUSY is returned the request will be returned to the midlayer
3911 * and re-tried later.
1da177e4 3912 */
27c868c2 3913static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
1da177e4 3914{
27c868c2
MW
3915 asc_board_t *boardp;
3916 ASC_DVC_VAR *asc_dvc_varp;
3917 ADV_DVC_VAR *adv_dvc_varp;
3918 ADV_SCSI_REQ_Q *adv_scsiqp;
3919 struct scsi_device *device;
3920 int ret;
3921
3922 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
3923 (ulong)scp, (ulong)scp->scsi_done);
3924
3925 boardp = ASC_BOARDP(scp->device->host);
3926 device = boardp->device[scp->device->id];
3927
3928 if (ASC_NARROW_BOARD(boardp)) {
3929 /*
3930 * Build and execute Narrow Board request.
3931 */
3932
3933 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3934
3935 /*
3936 * Build Asc Library request structure using the
3937 * global structures 'asc_scsi_req' and 'asc_sg_head'.
3938 *
3939 * If an error is returned, then the request has been
3940 * queued on the board done queue. It will be completed
3941 * by the caller.
3942 *
3943 * asc_build_req() can not return ASC_BUSY.
3944 */
3945 if (asc_build_req(boardp, scp) == ASC_ERROR) {
3946 ASC_STATS(scp->device->host, build_error);
3947 return ASC_ERROR;
3948 }
3949
3950 /*
3951 * Execute the command. If there is no error, add the command
3952 * to the active queue.
3953 */
3954 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
3955 case ASC_NOERROR:
3956 ASC_STATS(scp->device->host, exe_noerror);
3957 /*
ecec1947
MW
3958 * Increment monotonically increasing per device
3959 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
3960 */
3961 boardp->reqcnt[scp->device->id]++;
3962 asc_enqueue(&boardp->active, scp, ASC_BACK);
ecec1947
MW
3963 ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
3964 "ASC_NOERROR\n");
27c868c2
MW
3965 break;
3966 case ASC_BUSY:
27c868c2
MW
3967 ASC_STATS(scp->device->host, exe_busy);
3968 break;
3969 case ASC_ERROR:
ecec1947
MW
3970 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3971 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
3972 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3973 ASC_STATS(scp->device->host, exe_error);
3974 scp->result = HOST_BYTE(DID_ERROR);
3975 asc_enqueue(&boardp->done, scp, ASC_BACK);
3976 break;
3977 default:
ecec1947
MW
3978 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
3979 "AscExeScsiQueue() unknown, err_code 0x%x\n",
3980 boardp->id, asc_dvc_varp->err_code);
27c868c2
MW
3981 ASC_STATS(scp->device->host, exe_unknown);
3982 scp->result = HOST_BYTE(DID_ERROR);
3983 asc_enqueue(&boardp->done, scp, ASC_BACK);
3984 break;
3985 }
3986 } else {
3987 /*
3988 * Build and execute Wide Board request.
3989 */
3990 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3991
3992 /*
3993 * Build and get a pointer to an Adv Library request structure.
3994 *
3995 * If the request is successfully built then send it below,
3996 * otherwise return with an error.
3997 */
3998 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
3999 case ASC_NOERROR:
ecec1947
MW
4000 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
4001 "ASC_NOERROR\n");
27c868c2
MW
4002 break;
4003 case ASC_BUSY:
ecec1947
MW
4004 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4005 "ASC_BUSY\n");
27c868c2 4006 /*
ecec1947
MW
4007 * The asc_stats fields 'adv_build_noreq' and
4008 * 'adv_build_nosg' count wide board busy conditions.
4009 * They are updated in adv_build_req and
4010 * adv_get_sglist, respectively.
27c868c2
MW
4011 */
4012 return ASC_BUSY;
4013 case ASC_ERROR:
4014 /*
4015 * If an error is returned, then the request has been
4016 * queued on the board done queue. It will be completed
4017 * by the caller.
4018 */
4019 default:
ecec1947
MW
4020 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4021 "ASC_ERROR\n");
27c868c2
MW
4022 ASC_STATS(scp->device->host, build_error);
4023 return ASC_ERROR;
4024 }
1da177e4 4025
27c868c2
MW
4026 /*
4027 * Execute the command. If there is no error, add the command
4028 * to the active queue.
4029 */
4030 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4031 case ASC_NOERROR:
4032 ASC_STATS(scp->device->host, exe_noerror);
4033 /*
ecec1947
MW
4034 * Increment monotonically increasing per device
4035 * successful request counter. Wrapping doesn't matter.
27c868c2
MW
4036 */
4037 boardp->reqcnt[scp->device->id]++;
4038 asc_enqueue(&boardp->active, scp, ASC_BACK);
ecec1947
MW
4039 ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
4040 "ASC_NOERROR\n");
27c868c2
MW
4041 break;
4042 case ASC_BUSY:
27c868c2
MW
4043 ASC_STATS(scp->device->host, exe_busy);
4044 break;
4045 case ASC_ERROR:
ecec1947
MW
4046 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4047 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4048 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
4049 ASC_STATS(scp->device->host, exe_error);
4050 scp->result = HOST_BYTE(DID_ERROR);
4051 asc_enqueue(&boardp->done, scp, ASC_BACK);
4052 break;
4053 default:
ecec1947
MW
4054 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4055 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
4056 boardp->id, adv_dvc_varp->err_code);
27c868c2
MW
4057 ASC_STATS(scp->device->host, exe_unknown);
4058 scp->result = HOST_BYTE(DID_ERROR);
4059 asc_enqueue(&boardp->done, scp, ASC_BACK);
4060 break;
4061 }
4062 }
4063
4064 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4065 return ret;
1da177e4
LT
4066}
4067
4068/*
4069 * Build a request structure for the Asc Library (Narrow Board).
4070 *
4071 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4072 * used to build the request.
4073 *
4074 * If an error occurs, then queue the request on the board done
4075 * queue and return ASC_ERROR.
4076 */
27c868c2 4077static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
1da177e4 4078{
27c868c2
MW
4079 /*
4080 * Mutually exclusive access is required to 'asc_scsi_q' and
4081 * 'asc_sg_head' until after the request is started.
4082 */
4083 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4084
4085 /*
4086 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4087 */
4088 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4089
4090 /*
4091 * Build the ASC_SCSI_Q request.
4092 *
4093 * For narrow boards a CDB length maximum of 12 bytes
4094 * is supported.
4095 */
4096 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
ecec1947
MW
4097 ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
4098 "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
4099 ASC_MAX_CDB_LEN);
27c868c2
MW
4100 scp->result = HOST_BYTE(DID_ERROR);
4101 asc_enqueue(&boardp->done, scp, ASC_BACK);
4102 return ASC_ERROR;
4103 }
4104 asc_scsi_q.cdbptr = &scp->cmnd[0];
4105 asc_scsi_q.q2.cdb_len = scp->cmd_len;
4106 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4107 asc_scsi_q.q1.target_lun = scp->device->lun;
4108 asc_scsi_q.q2.target_ix =
4109 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4110 asc_scsi_q.q1.sense_addr =
4111 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4112 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4113
4114 /*
4115 * If there are any outstanding requests for the current target,
4116 * then every 255th request send an ORDERED request. This heuristic
4117 * tries to retain the benefit of request sorting while preventing
4118 * request starvation. 255 is the max number of tags or pending commands
4119 * a device may have outstanding.
4120 *
4121 * The request count is incremented below for every successfully
4122 * started request.
4123 *
4124 */
4125 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
4126 (boardp->reqcnt[scp->device->id] % 255) == 0) {
4127 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
4128 } else {
4129 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
4130 }
1da177e4 4131
27c868c2
MW
4132 /*
4133 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
4134 * buffer command.
4135 */
4136 if (scp->use_sg == 0) {
4137 /*
4138 * CDB request of single contiguous buffer.
4139 */
4140 ASC_STATS(scp->device->host, cont_cnt);
4141 scp->SCp.dma_handle = scp->request_bufflen ?
394dbf3f 4142 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
4143 scp->request_bufflen,
4144 scp->sc_data_direction) : 0;
4145 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
4146 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
4147 ASC_STATS_ADD(scp->device->host, cont_xfer,
4148 ASC_CEILING(scp->request_bufflen, 512));
4149 asc_scsi_q.q1.sg_queue_cnt = 0;
4150 asc_scsi_q.sg_head = NULL;
4151 } else {
4152 /*
4153 * CDB scatter-gather request list.
4154 */
4155 int sgcnt;
4156 int use_sg;
4157 struct scatterlist *slp;
4158
4159 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
4160 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4161 scp->sc_data_direction);
27c868c2
MW
4162
4163 if (use_sg > scp->device->host->sg_tablesize) {
394dbf3f
MW
4164 ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
4165 "sg_tablesize %d\n", boardp->id, use_sg,
4166 scp->device->host->sg_tablesize);
4167 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
4168 scp->sc_data_direction);
4169 scp->result = HOST_BYTE(DID_ERROR);
4170 asc_enqueue(&boardp->done, scp, ASC_BACK);
4171 return ASC_ERROR;
4172 }
4173
4174 ASC_STATS(scp->device->host, sg_cnt);
1da177e4 4175
27c868c2
MW
4176 /*
4177 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
4178 * structure to point to it.
4179 */
4180 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
4181
4182 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
4183 asc_scsi_q.sg_head = &asc_sg_head;
4184 asc_scsi_q.q1.data_cnt = 0;
4185 asc_scsi_q.q1.data_addr = 0;
4186 /* This is a byte value, otherwise it would need to be swapped. */
4187 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
4188 ASC_STATS_ADD(scp->device->host, sg_elem,
4189 asc_sg_head.entry_cnt);
1da177e4 4190
27c868c2
MW
4191 /*
4192 * Convert scatter-gather list into ASC_SG_HEAD list.
4193 */
4194 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
4195 asc_sg_head.sg_list[sgcnt].addr =
4196 cpu_to_le32(sg_dma_address(slp));
4197 asc_sg_head.sg_list[sgcnt].bytes =
4198 cpu_to_le32(sg_dma_len(slp));
4199 ASC_STATS_ADD(scp->device->host, sg_xfer,
4200 ASC_CEILING(sg_dma_len(slp), 512));
4201 }
4202 }
1da177e4 4203
27c868c2
MW
4204 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
4205 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 4206
27c868c2 4207 return ASC_NOERROR;
1da177e4
LT
4208}
4209
4210/*
4211 * Build a request structure for the Adv Library (Wide Board).
4212 *
4213 * If an adv_req_t can not be allocated to issue the request,
4214 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
4215 *
4216 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
4217 * microcode for DMA addresses or math operations are byte swapped
4218 * to little-endian order.
4219 */
27c868c2 4220static int
1da177e4 4221adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
27c868c2 4222 ADV_SCSI_REQ_Q **adv_scsiqpp)
1da177e4 4223{
27c868c2
MW
4224 adv_req_t *reqp;
4225 ADV_SCSI_REQ_Q *scsiqp;
4226 int i;
4227 int ret;
27c868c2
MW
4228
4229 /*
4230 * Allocate an adv_req_t structure from the board to execute
4231 * the command.
4232 */
4233 if (boardp->adv_reqp == NULL) {
4234 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
4235 ASC_STATS(scp->device->host, adv_build_noreq);
4236 return ASC_BUSY;
4237 } else {
4238 reqp = boardp->adv_reqp;
4239 boardp->adv_reqp = reqp->next_reqp;
4240 reqp->next_reqp = NULL;
4241 }
1da177e4 4242
27c868c2
MW
4243 /*
4244 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
4245 */
4246 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
4247
4248 /*
4249 * Initialize the structure.
4250 */
4251 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
4252
4253 /*
4254 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
4255 */
4256 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
4257
4258 /*
4259 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
4260 */
4261 reqp->cmndp = scp;
4262
4263 /*
4264 * Build the ADV_SCSI_REQ_Q request.
4265 */
4266
4267 /*
4268 * Set CDB length and copy it to the request structure.
4269 * For wide boards a CDB length maximum of 16 bytes
4270 * is supported.
4271 */
4272 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
4273 ASC_PRINT3
4274 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
4275 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
4276 scp->result = HOST_BYTE(DID_ERROR);
4277 asc_enqueue(&boardp->done, scp, ASC_BACK);
4278 return ASC_ERROR;
4279 }
4280 scsiqp->cdb_len = scp->cmd_len;
4281 /* Copy first 12 CDB bytes to cdb[]. */
4282 for (i = 0; i < scp->cmd_len && i < 12; i++) {
4283 scsiqp->cdb[i] = scp->cmnd[i];
4284 }
4285 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
4286 for (; i < scp->cmd_len; i++) {
4287 scsiqp->cdb16[i - 12] = scp->cmnd[i];
4288 }
1da177e4 4289
27c868c2
MW
4290 scsiqp->target_id = scp->device->id;
4291 scsiqp->target_lun = scp->device->lun;
1da177e4 4292
27c868c2
MW
4293 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4294 scsiqp->sense_len = sizeof(scp->sense_buffer);
1da177e4 4295
27c868c2
MW
4296 /*
4297 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
4298 * buffer command.
4299 */
1da177e4 4300
1da177e4 4301 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
27c868c2
MW
4302 scsiqp->vdata_addr = scp->request_buffer;
4303 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
1da177e4 4304
27c868c2
MW
4305 if (scp->use_sg == 0) {
4306 /*
4307 * CDB request of single contiguous buffer.
4308 */
4309 reqp->sgblkp = NULL;
4310 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
4311 if (scp->request_bufflen) {
4312 scsiqp->vdata_addr = scp->request_buffer;
4313 scp->SCp.dma_handle =
394dbf3f 4314 dma_map_single(boardp->dev, scp->request_buffer,
27c868c2
MW
4315 scp->request_bufflen,
4316 scp->sc_data_direction);
4317 } else {
4318 scsiqp->vdata_addr = NULL;
4319 scp->SCp.dma_handle = 0;
4320 }
4321 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
4322 scsiqp->sg_list_ptr = NULL;
4323 scsiqp->sg_real_addr = 0;
4324 ASC_STATS(scp->device->host, cont_cnt);
4325 ASC_STATS_ADD(scp->device->host, cont_xfer,
4326 ASC_CEILING(scp->request_bufflen, 512));
4327 } else {
4328 /*
4329 * CDB scatter-gather request list.
4330 */
4331 struct scatterlist *slp;
4332 int use_sg;
4333
4334 slp = (struct scatterlist *)scp->request_buffer;
394dbf3f
MW
4335 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4336 scp->sc_data_direction);
27c868c2
MW
4337
4338 if (use_sg > ADV_MAX_SG_LIST) {
394dbf3f
MW
4339 ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
4340 "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
4341 scp->device->host->sg_tablesize);
4342 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
27c868c2
MW
4343 scp->sc_data_direction);
4344 scp->result = HOST_BYTE(DID_ERROR);
4345 asc_enqueue(&boardp->done, scp, ASC_BACK);
4346
4347 /*
394dbf3f
MW
4348 * Free the 'adv_req_t' structure by adding it back
4349 * to the board free list.
27c868c2
MW
4350 */
4351 reqp->next_reqp = boardp->adv_reqp;
4352 boardp->adv_reqp = reqp;
4353
4354 return ASC_ERROR;
4355 }
4356
394dbf3f
MW
4357 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
4358 if (ret != ADV_SUCCESS) {
27c868c2 4359 /*
394dbf3f
MW
4360 * Free the adv_req_t structure by adding it back to
4361 * the board free list.
27c868c2
MW
4362 */
4363 reqp->next_reqp = boardp->adv_reqp;
4364 boardp->adv_reqp = reqp;
4365
4366 return ret;
4367 }
4368
4369 ASC_STATS(scp->device->host, sg_cnt);
4370 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
4371 }
1da177e4 4372
27c868c2
MW
4373 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4374 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
1da177e4 4375
27c868c2 4376 *adv_scsiqpp = scsiqp;
1da177e4 4377
27c868c2 4378 return ASC_NOERROR;
1da177e4
LT
4379}
4380
4381/*
4382 * Build scatter-gather list for Adv Library (Wide Board).
4383 *
4384 * Additional ADV_SG_BLOCK structures will need to be allocated
4385 * if the total number of scatter-gather elements exceeds
4386 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
4387 * assumed to be physically contiguous.
4388 *
4389 * Return:
4390 * ADV_SUCCESS(1) - SG List successfully created
4391 * ADV_ERROR(-1) - SG List creation failed
4392 */
27c868c2
MW
4393static int
4394adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
4395 int use_sg)
1da177e4 4396{
27c868c2
MW
4397 adv_sgblk_t *sgblkp;
4398 ADV_SCSI_REQ_Q *scsiqp;
4399 struct scatterlist *slp;
4400 int sg_elem_cnt;
4401 ADV_SG_BLOCK *sg_block, *prev_sg_block;
4402 ADV_PADDR sg_block_paddr;
4403 int i;
4404
4405 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
4406 slp = (struct scatterlist *)scp->request_buffer;
4407 sg_elem_cnt = use_sg;
4408 prev_sg_block = NULL;
4409 reqp->sgblkp = NULL;
4410
4411 do {
4412 /*
4413 * Allocate a 'adv_sgblk_t' structure from the board free
4414 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
4415 * (15) scatter-gather elements.
4416 */
4417 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
4418 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
4419 ASC_STATS(scp->device->host, adv_build_nosg);
4420
4421 /*
4422 * Allocation failed. Free 'adv_sgblk_t' structures already
4423 * allocated for the request.
4424 */
4425 while ((sgblkp = reqp->sgblkp) != NULL) {
4426 /* Remove 'sgblkp' from the request list. */
4427 reqp->sgblkp = sgblkp->next_sgblkp;
4428
4429 /* Add 'sgblkp' to the board free list. */
4430 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4431 boardp->adv_sgblkp = sgblkp;
4432 }
4433 return ASC_BUSY;
4434 } else {
4435 /* Complete 'adv_sgblk_t' board allocation. */
4436 boardp->adv_sgblkp = sgblkp->next_sgblkp;
4437 sgblkp->next_sgblkp = NULL;
4438
4439 /*
4440 * Get 8 byte aligned virtual and physical addresses for
4441 * the allocated ADV_SG_BLOCK structure.
4442 */
4443 sg_block =
4444 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
4445 sg_block_paddr = virt_to_bus(sg_block);
4446
4447 /*
4448 * Check if this is the first 'adv_sgblk_t' for the request.
4449 */
4450 if (reqp->sgblkp == NULL) {
4451 /* Request's first scatter-gather block. */
4452 reqp->sgblkp = sgblkp;
4453
4454 /*
4455 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
4456 * address pointers.
4457 */
4458 scsiqp->sg_list_ptr = sg_block;
4459 scsiqp->sg_real_addr =
4460 cpu_to_le32(sg_block_paddr);
4461 } else {
4462 /* Request's second or later scatter-gather block. */
4463 sgblkp->next_sgblkp = reqp->sgblkp;
4464 reqp->sgblkp = sgblkp;
4465
4466 /*
4467 * Point the previous ADV_SG_BLOCK structure to
4468 * the newly allocated ADV_SG_BLOCK structure.
4469 */
4470 ASC_ASSERT(prev_sg_block != NULL);
4471 prev_sg_block->sg_ptr =
4472 cpu_to_le32(sg_block_paddr);
4473 }
4474 }
4475
4476 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
4477 sg_block->sg_list[i].sg_addr =
4478 cpu_to_le32(sg_dma_address(slp));
4479 sg_block->sg_list[i].sg_count =
4480 cpu_to_le32(sg_dma_len(slp));
4481 ASC_STATS_ADD(scp->device->host, sg_xfer,
4482 ASC_CEILING(sg_dma_len(slp), 512));
4483
4484 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
4485 sg_block->sg_cnt = i + 1;
4486 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
4487 return ADV_SUCCESS;
4488 }
4489 slp++;
4490 }
4491 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
4492 prev_sg_block = sg_block;
4493 }
4494 while (1);
4495 /* NOTREACHED */
1da177e4
LT
4496}
4497
4498/*
4499 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
4500 *
4501 * Interrupt callback function for the Narrow SCSI Asc Library.
4502 */
27c868c2 4503static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
1da177e4 4504{
27c868c2
MW
4505 asc_board_t *boardp;
4506 struct scsi_cmnd *scp;
4507 struct Scsi_Host *shost;
27c868c2
MW
4508
4509 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
4510 (ulong)asc_dvc_varp, (ulong)qdonep);
4511 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
4512
4513 /*
4514 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4515 * command that has been completed.
4516 */
4517 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
4518 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
4519
4520 if (scp == NULL) {
4521 ASC_PRINT("asc_isr_callback: scp is NULL\n");
4522 return;
4523 }
4524 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4525
27c868c2 4526 shost = scp->device->host;
27c868c2
MW
4527 ASC_STATS(shost, callback);
4528 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
4529
4530 /*
4531 * If the request isn't found on the active queue, it may
4532 * have been removed to handle a reset request.
4533 * Display a message and return.
4534 */
4535 boardp = ASC_BOARDP(shost);
4536 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
4537 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
4538 ASC_PRINT2
4539 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
4540 boardp->id, (ulong)scp);
4541 return;
4542 }
1da177e4 4543
27c868c2
MW
4544 /*
4545 * 'qdonep' contains the command's ending status.
4546 */
4547 switch (qdonep->d3.done_stat) {
4548 case QD_NO_ERROR:
4549 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
4550 scp->result = 0;
1da177e4 4551
27c868c2
MW
4552 /*
4553 * Check for an underrun condition.
4554 *
4555 * If there was no error and an underrun condition, then
47d853cc 4556 * return the number of underrun bytes.
27c868c2
MW
4557 */
4558 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
4559 qdonep->remain_bytes <= scp->request_bufflen) {
4560 ASC_DBG1(1,
4561 "asc_isr_callback: underrun condition %u bytes\n",
4562 (unsigned)qdonep->remain_bytes);
4563 scp->resid = qdonep->remain_bytes;
4564 }
4565 break;
4566
4567 case QD_WITH_ERROR:
4568 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
4569 switch (qdonep->d3.host_stat) {
4570 case QHSTA_NO_ERROR:
4571 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
4572 ASC_DBG(2,
4573 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4574 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4575 sizeof(scp->sense_buffer));
4576 /*
4577 * Note: The 'status_byte()' macro used by target drivers
4578 * defined in scsi.h shifts the status byte returned by
4579 * host drivers right by 1 bit. This is why target drivers
4580 * also use right shifted status byte definitions. For
4581 * instance target drivers use CHECK_CONDITION, defined to
4582 * 0x1, instead of the SCSI defined check condition value
4583 * of 0x2. Host drivers are supposed to return the status
4584 * byte as it is defined by SCSI.
4585 */
4586 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4587 STATUS_BYTE(qdonep->d3.scsi_stat);
4588 } else {
4589 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
4590 }
4591 break;
4592
4593 default:
4594 /* QHSTA error occurred */
4595 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
4596 qdonep->d3.host_stat);
4597 scp->result = HOST_BYTE(DID_BAD_TARGET);
4598 break;
4599 }
4600 break;
4601
4602 case QD_ABORTED_BY_HOST:
4603 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
4604 scp->result =
4605 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
4606 scsi_msg) |
4607 STATUS_BYTE(qdonep->d3.scsi_stat);
4608 break;
4609
4610 default:
4611 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
4612 qdonep->d3.done_stat);
4613 scp->result =
4614 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
4615 scsi_msg) |
4616 STATUS_BYTE(qdonep->d3.scsi_stat);
4617 break;
4618 }
1da177e4 4619
27c868c2
MW
4620 /*
4621 * If the 'init_tidmask' bit isn't already set for the target and the
4622 * current request finished normally, then set the bit for the target
4623 * to indicate that a device is present.
4624 */
4625 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4626 qdonep->d3.done_stat == QD_NO_ERROR &&
4627 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
4628 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4629 }
1da177e4 4630
27c868c2
MW
4631 /*
4632 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
4633 * function, add the command to the end of the board's done queue.
4634 * The done function for the command will be called from
4635 * advansys_interrupt().
4636 */
4637 asc_enqueue(&boardp->done, scp, ASC_BACK);
1da177e4 4638
27c868c2 4639 return;
1da177e4
LT
4640}
4641
4642/*
4643 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
4644 *
4645 * Callback function for the Wide SCSI Adv Library.
4646 */
27c868c2 4647static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
1da177e4 4648{
27c868c2
MW
4649 asc_board_t *boardp;
4650 adv_req_t *reqp;
4651 adv_sgblk_t *sgblkp;
4652 struct scsi_cmnd *scp;
4653 struct Scsi_Host *shost;
27c868c2
MW
4654 ADV_DCNT resid_cnt;
4655
4656 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
4657 (ulong)adv_dvc_varp, (ulong)scsiqp);
4658 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4659
4660 /*
4661 * Get the adv_req_t structure for the command that has been
4662 * completed. The adv_req_t structure actually contains the
4663 * completed ADV_SCSI_REQ_Q structure.
4664 */
4665 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
4666 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
4667 if (reqp == NULL) {
4668 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
4669 return;
4670 }
1da177e4 4671
27c868c2
MW
4672 /*
4673 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4674 * command that has been completed.
4675 *
4676 * Note: The adv_req_t request structure and adv_sgblk_t structure,
4677 * if any, are dropped, because a board structure pointer can not be
4678 * determined.
4679 */
4680 scp = reqp->cmndp;
4681 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
4682 if (scp == NULL) {
4683 ASC_PRINT
4684 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
4685 return;
4686 }
4687 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4688
27c868c2 4689 shost = scp->device->host;
27c868c2
MW
4690 ASC_STATS(shost, callback);
4691 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
4692
4693 /*
4694 * If the request isn't found on the active queue, it may have been
4695 * removed to handle a reset request. Display a message and return.
4696 *
4697 * Note: Because the structure may still be in use don't attempt
4698 * to free the adv_req_t and adv_sgblk_t, if any, structures.
4699 */
4700 boardp = ASC_BOARDP(shost);
4701 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
4702 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
4703 ASC_PRINT2
4704 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
4705 boardp->id, (ulong)scp);
4706 return;
4707 }
1da177e4 4708
27c868c2
MW
4709 /*
4710 * 'done_status' contains the command's ending status.
4711 */
4712 switch (scsiqp->done_status) {
4713 case QD_NO_ERROR:
4714 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
4715 scp->result = 0;
1da177e4 4716
27c868c2
MW
4717 /*
4718 * Check for an underrun condition.
4719 *
4720 * If there was no error and an underrun condition, then
4721 * then return the number of underrun bytes.
4722 */
4723 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
4724 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
4725 resid_cnt <= scp->request_bufflen) {
4726 ASC_DBG1(1,
4727 "adv_isr_callback: underrun condition %lu bytes\n",
4728 (ulong)resid_cnt);
4729 scp->resid = resid_cnt;
4730 }
4731 break;
4732
4733 case QD_WITH_ERROR:
4734 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
4735 switch (scsiqp->host_status) {
4736 case QHSTA_NO_ERROR:
4737 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
4738 ASC_DBG(2,
4739 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4740 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4741 sizeof(scp->sense_buffer));
4742 /*
4743 * Note: The 'status_byte()' macro used by target drivers
4744 * defined in scsi.h shifts the status byte returned by
4745 * host drivers right by 1 bit. This is why target drivers
4746 * also use right shifted status byte definitions. For
4747 * instance target drivers use CHECK_CONDITION, defined to
4748 * 0x1, instead of the SCSI defined check condition value
4749 * of 0x2. Host drivers are supposed to return the status
4750 * byte as it is defined by SCSI.
4751 */
4752 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4753 STATUS_BYTE(scsiqp->scsi_status);
4754 } else {
4755 scp->result = STATUS_BYTE(scsiqp->scsi_status);
4756 }
4757 break;
4758
4759 default:
4760 /* Some other QHSTA error occurred. */
4761 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
4762 scsiqp->host_status);
4763 scp->result = HOST_BYTE(DID_BAD_TARGET);
4764 break;
4765 }
4766 break;
4767
4768 case QD_ABORTED_BY_HOST:
4769 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
4770 scp->result =
4771 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
4772 break;
4773
4774 default:
4775 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
4776 scsiqp->done_status);
4777 scp->result =
4778 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
4779 break;
4780 }
1da177e4 4781
27c868c2
MW
4782 /*
4783 * If the 'init_tidmask' bit isn't already set for the target and the
4784 * current request finished normally, then set the bit for the target
4785 * to indicate that a device is present.
4786 */
4787 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4788 scsiqp->done_status == QD_NO_ERROR &&
4789 scsiqp->host_status == QHSTA_NO_ERROR) {
4790 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4791 }
1da177e4 4792
27c868c2
MW
4793 /*
4794 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
4795 * function, add the command to the end of the board's done queue.
4796 * The done function for the command will be called from
4797 * advansys_interrupt().
4798 */
4799 asc_enqueue(&boardp->done, scp, ASC_BACK);
4800
4801 /*
4802 * Free all 'adv_sgblk_t' structures allocated for the request.
4803 */
4804 while ((sgblkp = reqp->sgblkp) != NULL) {
4805 /* Remove 'sgblkp' from the request list. */
4806 reqp->sgblkp = sgblkp->next_sgblkp;
4807
4808 /* Add 'sgblkp' to the board free list. */
4809 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4810 boardp->adv_sgblkp = sgblkp;
4811 }
1da177e4 4812
27c868c2
MW
4813 /*
4814 * Free the adv_req_t structure used with the command by adding
4815 * it back to the board free list.
4816 */
4817 reqp->next_reqp = boardp->adv_reqp;
4818 boardp->adv_reqp = reqp;
1da177e4 4819
27c868c2 4820 ASC_DBG(1, "adv_isr_callback: done\n");
1da177e4 4821
27c868c2 4822 return;
1da177e4
LT
4823}
4824
4825/*
4826 * adv_async_callback() - Adv Library asynchronous event callback function.
4827 */
27c868c2 4828static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
1da177e4 4829{
27c868c2
MW
4830 switch (code) {
4831 case ADV_ASYNC_SCSI_BUS_RESET_DET:
4832 /*
4833 * The firmware detected a SCSI Bus reset.
4834 */
4835 ASC_DBG(0,
4836 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
4837 break;
4838
4839 case ADV_ASYNC_RDMA_FAILURE:
4840 /*
4841 * Handle RDMA failure by resetting the SCSI Bus and
4842 * possibly the chip if it is unresponsive. Log the error
4843 * with a unique code.
4844 */
4845 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
4846 AdvResetChipAndSB(adv_dvc_varp);
4847 break;
4848
4849 case ADV_HOST_SCSI_BUS_RESET:
4850 /*
4851 * Host generated SCSI bus reset occurred.
4852 */
4853 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
4854 break;
4855
4856 default:
4857 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
4858 break;
4859 }
1da177e4
LT
4860}
4861
4862/*
4863 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
4864 * to indicate a command is queued for the device.
4865 *
4866 * 'flag' may be either ASC_FRONT or ASC_BACK.
4867 *
4868 * 'REQPNEXT(reqp)' returns reqp's next pointer.
4869 */
27c868c2 4870static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
1da177e4 4871{
27c868c2
MW
4872 int tid;
4873
4874 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
4875 (ulong)ascq, (ulong)reqp, flag);
4876 ASC_ASSERT(reqp != NULL);
4877 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
4878 tid = REQPTID(reqp);
4879 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
4880 if (flag == ASC_FRONT) {
4881 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
4882 ascq->q_first[tid] = reqp;
4883 /* If the queue was empty, set the last pointer. */
4884 if (ascq->q_last[tid] == NULL) {
4885 ascq->q_last[tid] = reqp;
4886 }
4887 } else { /* ASC_BACK */
4888 if (ascq->q_last[tid] != NULL) {
4889 ascq->q_last[tid]->host_scribble =
4890 (unsigned char *)reqp;
4891 }
4892 ascq->q_last[tid] = reqp;
4893 reqp->host_scribble = NULL;
4894 /* If the queue was empty, set the first pointer. */
4895 if (ascq->q_first[tid] == NULL) {
4896 ascq->q_first[tid] = reqp;
4897 }
4898 }
4899 /* The queue has at least one entry, set its bit. */
4900 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
1da177e4 4901#ifdef ADVANSYS_STATS
27c868c2
MW
4902 /* Maintain request queue statistics. */
4903 ascq->q_tot_cnt[tid]++;
4904 ascq->q_cur_cnt[tid]++;
4905 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
4906 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
4907 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
4908 tid, ascq->q_max_cnt[tid]);
4909 }
4910 REQPTIME(reqp) = REQTIMESTAMP();
1da177e4 4911#endif /* ADVANSYS_STATS */
27c868c2
MW
4912 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
4913 return;
1da177e4
LT
4914}
4915
1da177e4
LT
4916/*
4917 * Return a pointer to a singly linked list of all the requests queued
4918 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
4919 *
4920 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
4921 * the last request returned in the singly linked list.
4922 *
4923 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
4924 * then all queued requests are concatenated into one list and
4925 * returned.
4926 *
4927 * Note: If 'lastpp' is used to append a new list to the end of
4928 * an old list, only change the old list last pointer if '*lastpp'
4929 * (or the function return value) is not NULL, i.e. use a temporary
4930 * variable for 'lastpp' and check its value after the function return
4931 * before assigning it to the list last pointer.
4932 *
4933 * Unfortunately collecting queuing time statistics adds overhead to
4934 * the function that isn't inherent to the function's algorithm.
4935 */
27c868c2 4936static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
1da177e4 4937{
27c868c2
MW
4938 REQP firstp, lastp;
4939 int i;
4940
4941 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
4942 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
4943
4944 /*
4945 * If 'tid' is not ASC_TID_ALL, return requests only for
4946 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
4947 * requests for all tids.
4948 */
4949 if (tid != ASC_TID_ALL) {
4950 /* Return all requests for the specified 'tid'. */
4951 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
4952 /* List is empty; Set first and last return pointers to NULL. */
4953 firstp = lastp = NULL;
4954 } else {
4955 firstp = ascq->q_first[tid];
4956 lastp = ascq->q_last[tid];
4957 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
4958 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
1da177e4 4959#ifdef ADVANSYS_STATS
27c868c2
MW
4960 {
4961 REQP reqp;
4962 ascq->q_cur_cnt[tid] = 0;
4963 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
4964 REQTIMESTAT("asc_dequeue_list", ascq,
4965 reqp, tid);
4966 }
4967 }
1da177e4 4968#endif /* ADVANSYS_STATS */
27c868c2
MW
4969 }
4970 } else {
4971 /* Return all requests for all tids. */
4972 firstp = lastp = NULL;
4973 for (i = 0; i <= ADV_MAX_TID; i++) {
4974 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
4975 if (firstp == NULL) {
4976 firstp = ascq->q_first[i];
4977 lastp = ascq->q_last[i];
4978 } else {
4979 ASC_ASSERT(lastp != NULL);
4980 lastp->host_scribble =
4981 (unsigned char *)ascq->q_first[i];
4982 lastp = ascq->q_last[i];
4983 }
4984 ascq->q_first[i] = ascq->q_last[i] = NULL;
4985 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
1da177e4 4986#ifdef ADVANSYS_STATS
27c868c2 4987 ascq->q_cur_cnt[i] = 0;
1da177e4 4988#endif /* ADVANSYS_STATS */
27c868c2
MW
4989 }
4990 }
1da177e4 4991#ifdef ADVANSYS_STATS
27c868c2
MW
4992 {
4993 REQP reqp;
4994 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
4995 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
4996 reqp->device->id);
4997 }
4998 }
1da177e4 4999#endif /* ADVANSYS_STATS */
27c868c2
MW
5000 }
5001 if (lastpp) {
5002 *lastpp = lastp;
5003 }
5004 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5005 return firstp;
1da177e4
LT
5006}
5007
5008/*
5009 * Remove the specified 'REQP' from the specified queue for
5010 * the specified target device. Clear the 'tidmask' bit for the
5011 * device if no more commands are left queued for it.
5012 *
5013 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5014 *
5015 * Return ASC_TRUE if the command was found and removed,
5016 * otherwise return ASC_FALSE.
5017 */
27c868c2 5018static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
1da177e4 5019{
27c868c2
MW
5020 REQP currp, prevp;
5021 int tid;
5022 int ret = ASC_FALSE;
5023
5024 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5025 (ulong)ascq, (ulong)reqp);
5026 ASC_ASSERT(reqp != NULL);
5027
5028 tid = REQPTID(reqp);
5029 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5030
5031 /*
5032 * Handle the common case of 'reqp' being the first
5033 * entry on the queue.
5034 */
5035 if (reqp == ascq->q_first[tid]) {
5036 ret = ASC_TRUE;
5037 ascq->q_first[tid] = REQPNEXT(reqp);
5038 /* If the queue is now empty, clear its bit and the last pointer. */
5039 if (ascq->q_first[tid] == NULL) {
5040 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5041 ASC_ASSERT(ascq->q_last[tid] == reqp);
5042 ascq->q_last[tid] = NULL;
5043 }
5044 } else if (ascq->q_first[tid] != NULL) {
5045 ASC_ASSERT(ascq->q_last[tid] != NULL);
5046 /*
5047 * Because the case of 'reqp' being the first entry has been
5048 * handled above and it is known the queue is not empty, if
5049 * 'reqp' is found on the queue it is guaranteed the queue will
5050 * not become empty and that 'q_first[tid]' will not be changed.
5051 *
5052 * Set 'prevp' to the first entry, 'currp' to the second entry,
5053 * and search for 'reqp'.
5054 */
5055 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5056 currp; prevp = currp, currp = REQPNEXT(currp)) {
5057 if (currp == reqp) {
5058 ret = ASC_TRUE;
5059 prevp->host_scribble =
5060 (unsigned char *)REQPNEXT(currp);
5061 reqp->host_scribble = NULL;
5062 if (ascq->q_last[tid] == reqp) {
5063 ascq->q_last[tid] = prevp;
5064 }
5065 break;
5066 }
5067 }
5068 }
1da177e4 5069#ifdef ADVANSYS_STATS
27c868c2
MW
5070 /* Maintain request queue statistics. */
5071 if (ret == ASC_TRUE) {
5072 ascq->q_cur_cnt[tid]--;
5073 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5074 }
5075 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
1da177e4 5076#endif /* ADVANSYS_STATS */
27c868c2
MW
5077 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
5078 return ret;
1da177e4
LT
5079}
5080
1da177e4
LT
5081#ifdef CONFIG_PROC_FS
5082/*
5083 * asc_prt_board_devices()
5084 *
5085 * Print driver information for devices attached to the board.
5086 *
5087 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5088 * cf. asc_prt_line().
5089 *
5090 * Return the number of characters copied into 'cp'. No more than
5091 * 'cplen' characters will be copied to 'cp'.
5092 */
27c868c2 5093static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5094{
27c868c2
MW
5095 asc_board_t *boardp;
5096 int leftlen;
5097 int totlen;
5098 int len;
5099 int chip_scsi_id;
5100 int i;
5101
5102 boardp = ASC_BOARDP(shost);
5103 leftlen = cplen;
5104 totlen = len = 0;
5105
5106 len = asc_prt_line(cp, leftlen,
5107 "\nDevice Information for AdvanSys SCSI Host %d:\n",
5108 shost->host_no);
5109 ASC_PRT_NEXT();
5110
5111 if (ASC_NARROW_BOARD(boardp)) {
5112 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
5113 } else {
5114 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
5115 }
1da177e4 5116
27c868c2
MW
5117 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
5118 ASC_PRT_NEXT();
5119 for (i = 0; i <= ADV_MAX_TID; i++) {
5120 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
5121 len = asc_prt_line(cp, leftlen, " %X,", i);
5122 ASC_PRT_NEXT();
5123 }
5124 }
5125 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
5126 ASC_PRT_NEXT();
1da177e4 5127
27c868c2 5128 return totlen;
1da177e4
LT
5129}
5130
5131/*
5132 * Display Wide Board BIOS Information.
5133 */
27c868c2 5134static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5135{
27c868c2
MW
5136 asc_board_t *boardp;
5137 int leftlen;
5138 int totlen;
5139 int len;
5140 ushort major, minor, letter;
5141
5142 boardp = ASC_BOARDP(shost);
5143 leftlen = cplen;
5144 totlen = len = 0;
5145
5146 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
5147 ASC_PRT_NEXT();
5148
5149 /*
5150 * If the BIOS saved a valid signature, then fill in
5151 * the BIOS code segment base address.
5152 */
5153 if (boardp->bios_signature != 0x55AA) {
5154 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
5155 ASC_PRT_NEXT();
5156 len = asc_prt_line(cp, leftlen,
5157 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
5158 ASC_PRT_NEXT();
5159 len = asc_prt_line(cp, leftlen,
5160 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
5161 ASC_PRT_NEXT();
5162 } else {
5163 major = (boardp->bios_version >> 12) & 0xF;
5164 minor = (boardp->bios_version >> 8) & 0xF;
5165 letter = (boardp->bios_version & 0xFF);
1da177e4 5166
27c868c2
MW
5167 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
5168 major, minor,
5169 letter >= 26 ? '?' : letter + 'A');
5170 ASC_PRT_NEXT();
1da177e4 5171
27c868c2
MW
5172 /*
5173 * Current available ROM BIOS release is 3.1I for UW
5174 * and 3.2I for U2W. This code doesn't differentiate
5175 * UW and U2W boards.
5176 */
5177 if (major < 3 || (major <= 3 && minor < 1) ||
5178 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
5179 len = asc_prt_line(cp, leftlen,
5180 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
5181 ASC_PRT_NEXT();
5182 len = asc_prt_line(cp, leftlen,
5183 "ftp://ftp.connectcom.net/pub\n");
5184 ASC_PRT_NEXT();
5185 }
5186 }
1da177e4 5187
27c868c2 5188 return totlen;
1da177e4
LT
5189}
5190
5191/*
5192 * Add serial number to information bar if signature AAh
5193 * is found in at bit 15-9 (7 bits) of word 1.
5194 *
5195 * Serial Number consists fo 12 alpha-numeric digits.
5196 *
5197 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
5198 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
5199 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
5200 * 5 - Product revision (A-J) Word0: " "
5201 *
5202 * Signature Word1: 15-9 (7 bits)
5203 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
5204 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
5205 *
5206 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
5207 *
5208 * Note 1: Only production cards will have a serial number.
5209 *
5210 * Note 2: Signature is most significant 7 bits (0xFE).
5211 *
5212 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
5213 */
27c868c2 5214static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
1da177e4 5215{
27c868c2
MW
5216 ushort w, num;
5217
5218 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
5219 return ASC_FALSE;
5220 } else {
5221 /*
5222 * First word - 6 digits.
5223 */
5224 w = serialnum[0];
5225
5226 /* Product type - 1st digit. */
5227 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
5228 /* Product type is P=Prototype */
5229 *cp += 0x8;
5230 }
5231 cp++;
5232
5233 /* Manufacturing location - 2nd digit. */
5234 *cp++ = 'A' + ((w & 0x1C00) >> 10);
5235
5236 /* Product ID - 3rd, 4th digits. */
5237 num = w & 0x3FF;
5238 *cp++ = '0' + (num / 100);
5239 num %= 100;
5240 *cp++ = '0' + (num / 10);
5241
5242 /* Product revision - 5th digit. */
5243 *cp++ = 'A' + (num % 10);
5244
5245 /*
5246 * Second word
5247 */
5248 w = serialnum[1];
5249
5250 /*
5251 * Year - 6th digit.
5252 *
5253 * If bit 15 of third word is set, then the
5254 * last digit of the year is greater than 7.
5255 */
5256 if (serialnum[2] & 0x8000) {
5257 *cp++ = '8' + ((w & 0x1C0) >> 6);
5258 } else {
5259 *cp++ = '0' + ((w & 0x1C0) >> 6);
5260 }
5261
5262 /* Week of year - 7th, 8th digits. */
5263 num = w & 0x003F;
5264 *cp++ = '0' + num / 10;
5265 num %= 10;
5266 *cp++ = '0' + num;
5267
5268 /*
5269 * Third word
5270 */
5271 w = serialnum[2] & 0x7FFF;
5272
5273 /* Serial number - 9th digit. */
5274 *cp++ = 'A' + (w / 1000);
5275
5276 /* 10th, 11th, 12th digits. */
5277 num = w % 1000;
5278 *cp++ = '0' + num / 100;
5279 num %= 100;
5280 *cp++ = '0' + num / 10;
5281 num %= 10;
5282 *cp++ = '0' + num;
5283
5284 *cp = '\0'; /* Null Terminate the string. */
5285 return ASC_TRUE;
5286 }
1da177e4
LT
5287}
5288
5289/*
5290 * asc_prt_asc_board_eeprom()
5291 *
5292 * Print board EEPROM configuration.
5293 *
5294 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5295 * cf. asc_prt_line().
5296 *
5297 * Return the number of characters copied into 'cp'. No more than
5298 * 'cplen' characters will be copied to 'cp'.
5299 */
27c868c2 5300static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5301{
27c868c2
MW
5302 asc_board_t *boardp;
5303 ASC_DVC_VAR *asc_dvc_varp;
5304 int leftlen;
5305 int totlen;
5306 int len;
5307 ASCEEP_CONFIG *ep;
5308 int i;
1da177e4 5309#ifdef CONFIG_ISA
27c868c2 5310 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
1da177e4 5311#endif /* CONFIG_ISA */
27c868c2
MW
5312 uchar serialstr[13];
5313
5314 boardp = ASC_BOARDP(shost);
5315 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5316 ep = &boardp->eep_config.asc_eep;
5317
5318 leftlen = cplen;
5319 totlen = len = 0;
5320
5321 len = asc_prt_line(cp, leftlen,
5322 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
5323 shost->host_no);
5324 ASC_PRT_NEXT();
5325
5326 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
5327 == ASC_TRUE) {
5328 len =
5329 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
5330 serialstr);
5331 ASC_PRT_NEXT();
5332 } else {
5333 if (ep->adapter_info[5] == 0xBB) {
5334 len = asc_prt_line(cp, leftlen,
5335 " Default Settings Used for EEPROM-less Adapter.\n");
5336 ASC_PRT_NEXT();
5337 } else {
5338 len = asc_prt_line(cp, leftlen,
5339 " Serial Number Signature Not Present.\n");
5340 ASC_PRT_NEXT();
5341 }
5342 }
1da177e4 5343
27c868c2
MW
5344 len = asc_prt_line(cp, leftlen,
5345 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5346 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
5347 ep->max_tag_qng);
5348 ASC_PRT_NEXT();
5349
5350 len = asc_prt_line(cp, leftlen,
5351 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
5352 ASC_PRT_NEXT();
5353
5354 len = asc_prt_line(cp, leftlen, " Target ID: ");
5355 ASC_PRT_NEXT();
5356 for (i = 0; i <= ASC_MAX_TID; i++) {
5357 len = asc_prt_line(cp, leftlen, " %d", i);
5358 ASC_PRT_NEXT();
5359 }
5360 len = asc_prt_line(cp, leftlen, "\n");
5361 ASC_PRT_NEXT();
5362
5363 len = asc_prt_line(cp, leftlen, " Disconnects: ");
5364 ASC_PRT_NEXT();
5365 for (i = 0; i <= ASC_MAX_TID; i++) {
5366 len = asc_prt_line(cp, leftlen, " %c",
5367 (ep->
5368 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5369 'N');
5370 ASC_PRT_NEXT();
5371 }
5372 len = asc_prt_line(cp, leftlen, "\n");
5373 ASC_PRT_NEXT();
5374
5375 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
5376 ASC_PRT_NEXT();
5377 for (i = 0; i <= ASC_MAX_TID; i++) {
5378 len = asc_prt_line(cp, leftlen, " %c",
5379 (ep->
5380 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5381 'N');
5382 ASC_PRT_NEXT();
5383 }
5384 len = asc_prt_line(cp, leftlen, "\n");
5385 ASC_PRT_NEXT();
5386
5387 len = asc_prt_line(cp, leftlen, " Start Motor: ");
5388 ASC_PRT_NEXT();
5389 for (i = 0; i <= ASC_MAX_TID; i++) {
5390 len = asc_prt_line(cp, leftlen, " %c",
5391 (ep->
5392 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5393 'N');
5394 ASC_PRT_NEXT();
5395 }
5396 len = asc_prt_line(cp, leftlen, "\n");
5397 ASC_PRT_NEXT();
5398
5399 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5400 ASC_PRT_NEXT();
5401 for (i = 0; i <= ASC_MAX_TID; i++) {
5402 len = asc_prt_line(cp, leftlen, " %c",
5403 (ep->
5404 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5405 'N');
5406 ASC_PRT_NEXT();
5407 }
5408 len = asc_prt_line(cp, leftlen, "\n");
5409 ASC_PRT_NEXT();
1da177e4
LT
5410
5411#ifdef CONFIG_ISA
27c868c2
MW
5412 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5413 len = asc_prt_line(cp, leftlen,
5414 " Host ISA DMA speed: %d MB/S\n",
5415 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
5416 ASC_PRT_NEXT();
5417 }
1da177e4
LT
5418#endif /* CONFIG_ISA */
5419
27c868c2 5420 return totlen;
1da177e4
LT
5421}
5422
5423/*
5424 * asc_prt_adv_board_eeprom()
5425 *
5426 * Print board EEPROM configuration.
5427 *
5428 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5429 * cf. asc_prt_line().
5430 *
5431 * Return the number of characters copied into 'cp'. No more than
5432 * 'cplen' characters will be copied to 'cp'.
5433 */
27c868c2 5434static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5435{
27c868c2
MW
5436 asc_board_t *boardp;
5437 ADV_DVC_VAR *adv_dvc_varp;
5438 int leftlen;
5439 int totlen;
5440 int len;
5441 int i;
5442 char *termstr;
5443 uchar serialstr[13];
5444 ADVEEP_3550_CONFIG *ep_3550 = NULL;
5445 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
5446 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
5447 ushort word;
5448 ushort *wordp;
5449 ushort sdtr_speed = 0;
5450
5451 boardp = ASC_BOARDP(shost);
5452 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5453 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5454 ep_3550 = &boardp->eep_config.adv_3550_eep;
5455 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5456 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
5457 } else {
5458 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
5459 }
1da177e4 5460
27c868c2
MW
5461 leftlen = cplen;
5462 totlen = len = 0;
1da177e4 5463
27c868c2
MW
5464 len = asc_prt_line(cp, leftlen,
5465 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
5466 shost->host_no);
5467 ASC_PRT_NEXT();
1da177e4 5468
27c868c2
MW
5469 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5470 wordp = &ep_3550->serial_number_word1;
5471 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5472 wordp = &ep_38C0800->serial_number_word1;
5473 } else {
5474 wordp = &ep_38C1600->serial_number_word1;
5475 }
1da177e4 5476
27c868c2
MW
5477 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
5478 len =
5479 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
5480 serialstr);
5481 ASC_PRT_NEXT();
5482 } else {
5483 len = asc_prt_line(cp, leftlen,
5484 " Serial Number Signature Not Present.\n");
5485 ASC_PRT_NEXT();
5486 }
1da177e4 5487
27c868c2
MW
5488 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5489 len = asc_prt_line(cp, leftlen,
5490 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5491 ep_3550->adapter_scsi_id,
5492 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
5493 ASC_PRT_NEXT();
5494 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5495 len = asc_prt_line(cp, leftlen,
5496 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5497 ep_38C0800->adapter_scsi_id,
5498 ep_38C0800->max_host_qng,
5499 ep_38C0800->max_dvc_qng);
5500 ASC_PRT_NEXT();
5501 } else {
5502 len = asc_prt_line(cp, leftlen,
5503 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5504 ep_38C1600->adapter_scsi_id,
5505 ep_38C1600->max_host_qng,
5506 ep_38C1600->max_dvc_qng);
5507 ASC_PRT_NEXT();
5508 }
5509 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5510 word = ep_3550->termination;
5511 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5512 word = ep_38C0800->termination_lvd;
5513 } else {
5514 word = ep_38C1600->termination_lvd;
5515 }
5516 switch (word) {
5517 case 1:
5518 termstr = "Low Off/High Off";
5519 break;
5520 case 2:
5521 termstr = "Low Off/High On";
5522 break;
5523 case 3:
5524 termstr = "Low On/High On";
5525 break;
5526 default:
5527 case 0:
5528 termstr = "Automatic";
5529 break;
5530 }
1da177e4 5531
27c868c2
MW
5532 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5533 len = asc_prt_line(cp, leftlen,
5534 " termination: %u (%s), bios_ctrl: 0x%x\n",
5535 ep_3550->termination, termstr,
5536 ep_3550->bios_ctrl);
5537 ASC_PRT_NEXT();
5538 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5539 len = asc_prt_line(cp, leftlen,
5540 " termination: %u (%s), bios_ctrl: 0x%x\n",
5541 ep_38C0800->termination_lvd, termstr,
5542 ep_38C0800->bios_ctrl);
5543 ASC_PRT_NEXT();
5544 } else {
5545 len = asc_prt_line(cp, leftlen,
5546 " termination: %u (%s), bios_ctrl: 0x%x\n",
5547 ep_38C1600->termination_lvd, termstr,
5548 ep_38C1600->bios_ctrl);
5549 ASC_PRT_NEXT();
5550 }
1da177e4 5551
27c868c2
MW
5552 len = asc_prt_line(cp, leftlen, " Target ID: ");
5553 ASC_PRT_NEXT();
5554 for (i = 0; i <= ADV_MAX_TID; i++) {
5555 len = asc_prt_line(cp, leftlen, " %X", i);
5556 ASC_PRT_NEXT();
5557 }
5558 len = asc_prt_line(cp, leftlen, "\n");
5559 ASC_PRT_NEXT();
1da177e4 5560
27c868c2
MW
5561 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5562 word = ep_3550->disc_enable;
5563 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5564 word = ep_38C0800->disc_enable;
5565 } else {
5566 word = ep_38C1600->disc_enable;
5567 }
5568 len = asc_prt_line(cp, leftlen, " Disconnects: ");
5569 ASC_PRT_NEXT();
5570 for (i = 0; i <= ADV_MAX_TID; i++) {
5571 len = asc_prt_line(cp, leftlen, " %c",
5572 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5573 ASC_PRT_NEXT();
5574 }
5575 len = asc_prt_line(cp, leftlen, "\n");
5576 ASC_PRT_NEXT();
1da177e4 5577
27c868c2
MW
5578 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5579 word = ep_3550->tagqng_able;
5580 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5581 word = ep_38C0800->tagqng_able;
5582 } else {
5583 word = ep_38C1600->tagqng_able;
5584 }
5585 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
5586 ASC_PRT_NEXT();
5587 for (i = 0; i <= ADV_MAX_TID; i++) {
5588 len = asc_prt_line(cp, leftlen, " %c",
5589 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5590 ASC_PRT_NEXT();
5591 }
5592 len = asc_prt_line(cp, leftlen, "\n");
5593 ASC_PRT_NEXT();
5594
5595 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5596 word = ep_3550->start_motor;
5597 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5598 word = ep_38C0800->start_motor;
5599 } else {
5600 word = ep_38C1600->start_motor;
5601 }
5602 len = asc_prt_line(cp, leftlen, " Start Motor: ");
5603 ASC_PRT_NEXT();
5604 for (i = 0; i <= ADV_MAX_TID; i++) {
5605 len = asc_prt_line(cp, leftlen, " %c",
5606 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5607 ASC_PRT_NEXT();
5608 }
5609 len = asc_prt_line(cp, leftlen, "\n");
5610 ASC_PRT_NEXT();
5611
5612 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5613 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5614 ASC_PRT_NEXT();
5615 for (i = 0; i <= ADV_MAX_TID; i++) {
5616 len = asc_prt_line(cp, leftlen, " %c",
5617 (ep_3550->
5618 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
5619 'Y' : 'N');
5620 ASC_PRT_NEXT();
5621 }
5622 len = asc_prt_line(cp, leftlen, "\n");
5623 ASC_PRT_NEXT();
5624 }
5625
5626 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5627 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
5628 ASC_PRT_NEXT();
5629 for (i = 0; i <= ADV_MAX_TID; i++) {
5630 len = asc_prt_line(cp, leftlen, " %c",
5631 (ep_3550->
5632 ultra_able & ADV_TID_TO_TIDMASK(i))
5633 ? 'Y' : 'N');
5634 ASC_PRT_NEXT();
5635 }
5636 len = asc_prt_line(cp, leftlen, "\n");
5637 ASC_PRT_NEXT();
5638 }
5639
5640 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5641 word = ep_3550->wdtr_able;
5642 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5643 word = ep_38C0800->wdtr_able;
5644 } else {
5645 word = ep_38C1600->wdtr_able;
5646 }
5647 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
5648 ASC_PRT_NEXT();
5649 for (i = 0; i <= ADV_MAX_TID; i++) {
5650 len = asc_prt_line(cp, leftlen, " %c",
5651 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5652 ASC_PRT_NEXT();
5653 }
5654 len = asc_prt_line(cp, leftlen, "\n");
5655 ASC_PRT_NEXT();
5656
5657 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
5658 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
5659 len = asc_prt_line(cp, leftlen,
5660 " Synchronous Transfer Speed (Mhz):\n ");
5661 ASC_PRT_NEXT();
5662 for (i = 0; i <= ADV_MAX_TID; i++) {
5663 char *speed_str;
5664
5665 if (i == 0) {
5666 sdtr_speed = adv_dvc_varp->sdtr_speed1;
5667 } else if (i == 4) {
5668 sdtr_speed = adv_dvc_varp->sdtr_speed2;
5669 } else if (i == 8) {
5670 sdtr_speed = adv_dvc_varp->sdtr_speed3;
5671 } else if (i == 12) {
5672 sdtr_speed = adv_dvc_varp->sdtr_speed4;
5673 }
5674 switch (sdtr_speed & ADV_MAX_TID) {
5675 case 0:
5676 speed_str = "Off";
5677 break;
5678 case 1:
5679 speed_str = " 5";
5680 break;
5681 case 2:
5682 speed_str = " 10";
5683 break;
5684 case 3:
5685 speed_str = " 20";
5686 break;
5687 case 4:
5688 speed_str = " 40";
5689 break;
5690 case 5:
5691 speed_str = " 80";
5692 break;
5693 default:
5694 speed_str = "Unk";
5695 break;
5696 }
5697 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
5698 ASC_PRT_NEXT();
5699 if (i == 7) {
5700 len = asc_prt_line(cp, leftlen, "\n ");
5701 ASC_PRT_NEXT();
5702 }
5703 sdtr_speed >>= 4;
5704 }
5705 len = asc_prt_line(cp, leftlen, "\n");
5706 ASC_PRT_NEXT();
5707 }
5708
5709 return totlen;
5710}
5711
5712/*
5713 * asc_prt_driver_conf()
5714 *
5715 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5716 * cf. asc_prt_line().
1da177e4
LT
5717 *
5718 * Return the number of characters copied into 'cp'. No more than
5719 * 'cplen' characters will be copied to 'cp'.
5720 */
27c868c2 5721static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5722{
27c868c2
MW
5723 asc_board_t *boardp;
5724 int leftlen;
5725 int totlen;
5726 int len;
5727 int chip_scsi_id;
5728
5729 boardp = ASC_BOARDP(shost);
5730
5731 leftlen = cplen;
5732 totlen = len = 0;
5733
5734 len = asc_prt_line(cp, leftlen,
5735 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
5736 shost->host_no);
5737 ASC_PRT_NEXT();
5738
5739 len = asc_prt_line(cp, leftlen,
5740 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
5741 shost->host_busy, shost->last_reset, shost->max_id,
5742 shost->max_lun, shost->max_channel);
5743 ASC_PRT_NEXT();
5744
5745 len = asc_prt_line(cp, leftlen,
5746 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
5747 shost->unique_id, shost->can_queue, shost->this_id,
5748 shost->sg_tablesize, shost->cmd_per_lun);
5749 ASC_PRT_NEXT();
5750
5751 len = asc_prt_line(cp, leftlen,
5752 " unchecked_isa_dma %d, use_clustering %d\n",
5753 shost->unchecked_isa_dma, shost->use_clustering);
5754 ASC_PRT_NEXT();
5755
5756 len = asc_prt_line(cp, leftlen,
5757 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
5758 boardp->flags, boardp->last_reset, jiffies,
5759 boardp->asc_n_io_port);
5760 ASC_PRT_NEXT();
5761
4a2d31c8 5762 len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
27c868c2
MW
5763 ASC_PRT_NEXT();
5764
5765 if (ASC_NARROW_BOARD(boardp)) {
5766 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
5767 } else {
5768 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
5769 }
1da177e4 5770
27c868c2 5771 return totlen;
1da177e4
LT
5772}
5773
5774/*
5775 * asc_prt_asc_board_info()
5776 *
5777 * Print dynamic board configuration information.
5778 *
5779 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5780 * cf. asc_prt_line().
5781 *
5782 * Return the number of characters copied into 'cp'. No more than
5783 * 'cplen' characters will be copied to 'cp'.
5784 */
27c868c2 5785static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5786{
27c868c2
MW
5787 asc_board_t *boardp;
5788 int chip_scsi_id;
5789 int leftlen;
5790 int totlen;
5791 int len;
5792 ASC_DVC_VAR *v;
5793 ASC_DVC_CFG *c;
5794 int i;
5795 int renegotiate = 0;
5796
5797 boardp = ASC_BOARDP(shost);
5798 v = &boardp->dvc_var.asc_dvc_var;
5799 c = &boardp->dvc_cfg.asc_dvc_cfg;
5800 chip_scsi_id = c->chip_scsi_id;
5801
5802 leftlen = cplen;
5803 totlen = len = 0;
5804
5805 len = asc_prt_line(cp, leftlen,
5806 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5807 shost->host_no);
5808 ASC_PRT_NEXT();
5809
5810 len = asc_prt_line(cp, leftlen,
5811 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
5812 c->chip_version, c->lib_version, c->lib_serial_no,
5813 c->mcode_date);
5814 ASC_PRT_NEXT();
5815
5816 len = asc_prt_line(cp, leftlen,
5817 " mcode_version 0x%x, err_code %u\n",
5818 c->mcode_version, v->err_code);
5819 ASC_PRT_NEXT();
5820
5821 /* Current number of commands waiting for the host. */
5822 len = asc_prt_line(cp, leftlen,
5823 " Total Command Pending: %d\n", v->cur_total_qng);
5824 ASC_PRT_NEXT();
5825
5826 len = asc_prt_line(cp, leftlen, " Command Queuing:");
5827 ASC_PRT_NEXT();
5828 for (i = 0; i <= ASC_MAX_TID; i++) {
5829 if ((chip_scsi_id == i) ||
5830 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5831 continue;
5832 }
5833 len = asc_prt_line(cp, leftlen, " %X:%c",
5834 i,
5835 (v->
5836 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
5837 'Y' : 'N');
5838 ASC_PRT_NEXT();
5839 }
5840 len = asc_prt_line(cp, leftlen, "\n");
5841 ASC_PRT_NEXT();
5842
5843 /* Current number of commands waiting for a device. */
5844 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
5845 ASC_PRT_NEXT();
5846 for (i = 0; i <= ASC_MAX_TID; i++) {
5847 if ((chip_scsi_id == i) ||
5848 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5849 continue;
5850 }
5851 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
5852 ASC_PRT_NEXT();
5853 }
5854 len = asc_prt_line(cp, leftlen, "\n");
5855 ASC_PRT_NEXT();
5856
5857 /* Current limit on number of commands that can be sent to a device. */
5858 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
5859 ASC_PRT_NEXT();
5860 for (i = 0; i <= ASC_MAX_TID; i++) {
5861 if ((chip_scsi_id == i) ||
5862 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5863 continue;
5864 }
5865 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
5866 ASC_PRT_NEXT();
5867 }
5868 len = asc_prt_line(cp, leftlen, "\n");
5869 ASC_PRT_NEXT();
5870
5871 /* Indicate whether the device has returned queue full status. */
5872 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
5873 ASC_PRT_NEXT();
5874 for (i = 0; i <= ASC_MAX_TID; i++) {
5875 if ((chip_scsi_id == i) ||
5876 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5877 continue;
5878 }
5879 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
5880 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
5881 i, boardp->queue_full_cnt[i]);
5882 } else {
5883 len = asc_prt_line(cp, leftlen, " %X:N", i);
5884 }
5885 ASC_PRT_NEXT();
5886 }
5887 len = asc_prt_line(cp, leftlen, "\n");
5888 ASC_PRT_NEXT();
5889
5890 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5891 ASC_PRT_NEXT();
5892 for (i = 0; i <= ASC_MAX_TID; i++) {
5893 if ((chip_scsi_id == i) ||
5894 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5895 continue;
5896 }
5897 len = asc_prt_line(cp, leftlen, " %X:%c",
5898 i,
5899 (v->
5900 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5901 'N');
5902 ASC_PRT_NEXT();
5903 }
5904 len = asc_prt_line(cp, leftlen, "\n");
5905 ASC_PRT_NEXT();
5906
5907 for (i = 0; i <= ASC_MAX_TID; i++) {
5908 uchar syn_period_ix;
5909
5910 if ((chip_scsi_id == i) ||
5911 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
5912 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
5913 continue;
5914 }
5915
5916 len = asc_prt_line(cp, leftlen, " %X:", i);
5917 ASC_PRT_NEXT();
5918
5919 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
5920 len = asc_prt_line(cp, leftlen, " Asynchronous");
5921 ASC_PRT_NEXT();
5922 } else {
5923 syn_period_ix =
5924 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
5925 1);
5926
5927 len = asc_prt_line(cp, leftlen,
5928 " Transfer Period Factor: %d (%d.%d Mhz),",
5929 v->sdtr_period_tbl[syn_period_ix],
5930 250 /
5931 v->sdtr_period_tbl[syn_period_ix],
5932 ASC_TENTHS(250,
5933 v->
5934 sdtr_period_tbl
5935 [syn_period_ix]));
5936 ASC_PRT_NEXT();
5937
5938 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
5939 boardp->
5940 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
5941 ASC_PRT_NEXT();
5942 }
5943
5944 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
5945 len = asc_prt_line(cp, leftlen, "*\n");
5946 renegotiate = 1;
5947 } else {
5948 len = asc_prt_line(cp, leftlen, "\n");
5949 }
5950 ASC_PRT_NEXT();
5951 }
1da177e4 5952
27c868c2
MW
5953 if (renegotiate) {
5954 len = asc_prt_line(cp, leftlen,
5955 " * = Re-negotiation pending before next command.\n");
5956 ASC_PRT_NEXT();
5957 }
1da177e4 5958
27c868c2 5959 return totlen;
1da177e4
LT
5960}
5961
5962/*
5963 * asc_prt_adv_board_info()
5964 *
5965 * Print dynamic board configuration information.
5966 *
5967 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5968 * cf. asc_prt_line().
5969 *
5970 * Return the number of characters copied into 'cp'. No more than
5971 * 'cplen' characters will be copied to 'cp'.
5972 */
27c868c2 5973static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 5974{
27c868c2
MW
5975 asc_board_t *boardp;
5976 int leftlen;
5977 int totlen;
5978 int len;
5979 int i;
5980 ADV_DVC_VAR *v;
5981 ADV_DVC_CFG *c;
5982 AdvPortAddr iop_base;
5983 ushort chip_scsi_id;
5984 ushort lramword;
5985 uchar lrambyte;
5986 ushort tagqng_able;
5987 ushort sdtr_able, wdtr_able;
5988 ushort wdtr_done, sdtr_done;
5989 ushort period = 0;
5990 int renegotiate = 0;
5991
5992 boardp = ASC_BOARDP(shost);
5993 v = &boardp->dvc_var.adv_dvc_var;
5994 c = &boardp->dvc_cfg.adv_dvc_cfg;
5995 iop_base = v->iop_base;
5996 chip_scsi_id = v->chip_scsi_id;
5997
5998 leftlen = cplen;
5999 totlen = len = 0;
6000
6001 len = asc_prt_line(cp, leftlen,
6002 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6003 shost->host_no);
6004 ASC_PRT_NEXT();
6005
6006 len = asc_prt_line(cp, leftlen,
6007 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6008 v->iop_base,
6009 AdvReadWordRegister(iop_base,
6010 IOPW_SCSI_CFG1) & CABLE_DETECT,
6011 v->err_code);
6012 ASC_PRT_NEXT();
6013
6014 len = asc_prt_line(cp, leftlen,
6015 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6016 c->chip_version, c->lib_version, c->mcode_date,
6017 c->mcode_version);
6018 ASC_PRT_NEXT();
6019
6020 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6021 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6022 ASC_PRT_NEXT();
6023 for (i = 0; i <= ADV_MAX_TID; i++) {
6024 if ((chip_scsi_id == i) ||
6025 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6026 continue;
6027 }
6028
6029 len = asc_prt_line(cp, leftlen, " %X:%c",
6030 i,
6031 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6032 'N');
6033 ASC_PRT_NEXT();
6034 }
6035 len = asc_prt_line(cp, leftlen, "\n");
6036 ASC_PRT_NEXT();
6037
6038 len = asc_prt_line(cp, leftlen, " Queue Limit:");
6039 ASC_PRT_NEXT();
6040 for (i = 0; i <= ADV_MAX_TID; i++) {
6041 if ((chip_scsi_id == i) ||
6042 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6043 continue;
6044 }
6045
6046 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
6047 lrambyte);
6048
6049 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6050 ASC_PRT_NEXT();
6051 }
6052 len = asc_prt_line(cp, leftlen, "\n");
6053 ASC_PRT_NEXT();
6054
6055 len = asc_prt_line(cp, leftlen, " Command Pending:");
6056 ASC_PRT_NEXT();
6057 for (i = 0; i <= ADV_MAX_TID; i++) {
6058 if ((chip_scsi_id == i) ||
6059 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6060 continue;
6061 }
6062
6063 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
6064 lrambyte);
6065
6066 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6067 ASC_PRT_NEXT();
6068 }
6069 len = asc_prt_line(cp, leftlen, "\n");
6070 ASC_PRT_NEXT();
6071
6072 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6073 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
6074 ASC_PRT_NEXT();
6075 for (i = 0; i <= ADV_MAX_TID; i++) {
6076 if ((chip_scsi_id == i) ||
6077 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6078 continue;
6079 }
6080
6081 len = asc_prt_line(cp, leftlen, " %X:%c",
6082 i,
6083 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6084 'N');
6085 ASC_PRT_NEXT();
6086 }
6087 len = asc_prt_line(cp, leftlen, "\n");
6088 ASC_PRT_NEXT();
6089
6090 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
6091 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
6092 ASC_PRT_NEXT();
6093 for (i = 0; i <= ADV_MAX_TID; i++) {
6094 if ((chip_scsi_id == i) ||
6095 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6096 continue;
6097 }
6098
6099 AdvReadWordLram(iop_base,
6100 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
6101 lramword);
6102
6103 len = asc_prt_line(cp, leftlen, " %X:%d",
6104 i, (lramword & 0x8000) ? 16 : 8);
6105 ASC_PRT_NEXT();
6106
6107 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
6108 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6109 len = asc_prt_line(cp, leftlen, "*");
6110 ASC_PRT_NEXT();
6111 renegotiate = 1;
6112 }
6113 }
6114 len = asc_prt_line(cp, leftlen, "\n");
6115 ASC_PRT_NEXT();
6116
6117 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6118 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
6119 ASC_PRT_NEXT();
6120 for (i = 0; i <= ADV_MAX_TID; i++) {
6121 if ((chip_scsi_id == i) ||
6122 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6123 continue;
6124 }
6125
6126 len = asc_prt_line(cp, leftlen, " %X:%c",
6127 i,
6128 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6129 'N');
6130 ASC_PRT_NEXT();
6131 }
6132 len = asc_prt_line(cp, leftlen, "\n");
6133 ASC_PRT_NEXT();
6134
6135 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
6136 for (i = 0; i <= ADV_MAX_TID; i++) {
6137
6138 AdvReadWordLram(iop_base,
6139 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
6140 lramword);
6141 lramword &= ~0x8000;
6142
6143 if ((chip_scsi_id == i) ||
6144 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6145 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
6146 continue;
6147 }
6148
6149 len = asc_prt_line(cp, leftlen, " %X:", i);
6150 ASC_PRT_NEXT();
6151
6152 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
6153 len = asc_prt_line(cp, leftlen, " Asynchronous");
6154 ASC_PRT_NEXT();
6155 } else {
6156 len =
6157 asc_prt_line(cp, leftlen,
6158 " Transfer Period Factor: ");
6159 ASC_PRT_NEXT();
6160
6161 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
6162 len =
6163 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
6164 ASC_PRT_NEXT();
6165 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
6166 len =
6167 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
6168 ASC_PRT_NEXT();
6169 } else { /* 20 Mhz or below. */
6170
6171 period = (((lramword >> 8) * 25) + 50) / 4;
6172
6173 if (period == 0) { /* Should never happen. */
6174 len =
6175 asc_prt_line(cp, leftlen,
6176 "%d (? Mhz), ");
6177 ASC_PRT_NEXT();
6178 } else {
6179 len = asc_prt_line(cp, leftlen,
6180 "%d (%d.%d Mhz),",
6181 period, 250 / period,
6182 ASC_TENTHS(250,
6183 period));
6184 ASC_PRT_NEXT();
6185 }
6186 }
6187
6188 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6189 lramword & 0x1F);
6190 ASC_PRT_NEXT();
6191 }
6192
6193 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6194 len = asc_prt_line(cp, leftlen, "*\n");
6195 renegotiate = 1;
6196 } else {
6197 len = asc_prt_line(cp, leftlen, "\n");
6198 }
6199 ASC_PRT_NEXT();
6200 }
1da177e4 6201
27c868c2
MW
6202 if (renegotiate) {
6203 len = asc_prt_line(cp, leftlen,
6204 " * = Re-negotiation pending before next command.\n");
6205 ASC_PRT_NEXT();
6206 }
1da177e4 6207
27c868c2 6208 return totlen;
1da177e4
LT
6209}
6210
6211/*
6212 * asc_proc_copy()
6213 *
6214 * Copy proc information to a read buffer taking into account the current
6215 * read offset in the file and the remaining space in the read buffer.
6216 */
27c868c2 6217static int
1da177e4 6218asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
27c868c2 6219 char *cp, int cplen)
1da177e4 6220{
27c868c2
MW
6221 int cnt = 0;
6222
6223 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
6224 (unsigned)offset, (unsigned)advoffset, cplen);
6225 if (offset <= advoffset) {
6226 /* Read offset below current offset, copy everything. */
6227 cnt = min(cplen, leftlen);
6228 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
6229 (ulong)curbuf, (ulong)cp, cnt);
6230 memcpy(curbuf, cp, cnt);
6231 } else if (offset < advoffset + cplen) {
6232 /* Read offset within current range, partial copy. */
6233 cnt = (advoffset + cplen) - offset;
6234 cp = (cp + cplen) - cnt;
6235 cnt = min(cnt, leftlen);
6236 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
6237 (ulong)curbuf, (ulong)cp, cnt);
6238 memcpy(curbuf, cp, cnt);
6239 }
6240 return cnt;
1da177e4
LT
6241}
6242
6243/*
6244 * asc_prt_line()
6245 *
6246 * If 'cp' is NULL print to the console, otherwise print to a buffer.
6247 *
6248 * Return 0 if printing to the console, otherwise return the number of
6249 * bytes written to the buffer.
6250 *
6251 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
6252 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
6253 */
27c868c2 6254static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
1da177e4 6255{
27c868c2
MW
6256 va_list args;
6257 int ret;
6258 char s[ASC_PRTLINE_SIZE];
6259
6260 va_start(args, fmt);
6261 ret = vsprintf(s, fmt, args);
6262 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
6263 if (buf == NULL) {
6264 (void)printk(s);
6265 ret = 0;
6266 } else {
6267 ret = min(buflen, ret);
6268 memcpy(buf, s, ret);
6269 }
6270 va_end(args);
6271 return ret;
1da177e4
LT
6272}
6273#endif /* CONFIG_PROC_FS */
6274
1da177e4
LT
6275/*
6276 * --- Functions Required by the Asc Library
6277 */
6278
6279/*
6280 * Delay for 'n' milliseconds. Don't use the 'jiffies'
6281 * global variable which is incremented once every 5 ms
6282 * from a timer interrupt, because this function may be
6283 * called when interrupts are disabled.
6284 */
27c868c2 6285static void DvcSleepMilliSecond(ADV_DCNT n)
1da177e4 6286{
27c868c2
MW
6287 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
6288 mdelay(n);
1da177e4
LT
6289}
6290
6291/*
6292 * Currently and inline noop but leave as a placeholder.
6293 * Leave DvcEnterCritical() as a noop placeholder.
6294 */
27c868c2 6295static inline ulong DvcEnterCritical(void)
1da177e4 6296{
27c868c2 6297 return 0;
1da177e4
LT
6298}
6299
6300/*
6301 * Critical sections are all protected by the board spinlock.
6302 * Leave DvcLeaveCritical() as a noop placeholder.
6303 */
27c868c2 6304static inline void DvcLeaveCritical(ulong flags)
1da177e4 6305{
27c868c2 6306 return;
1da177e4
LT
6307}
6308
6309/*
6310 * void
6311 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
6312 *
6313 * Calling/Exit State:
6314 * none
6315 *
6316 * Description:
6317 * Output an ASC_SCSI_Q structure to the chip
6318 */
27c868c2 6319static void
1da177e4
LT
6320DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
6321{
27c868c2
MW
6322 int i;
6323
6324 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
6325 AscSetChipLramAddr(iop_base, s_addr);
6326 for (i = 0; i < 2 * words; i += 2) {
6327 if (i == 4 || i == 20) {
6328 continue;
6329 }
6330 outpw(iop_base + IOP_RAM_DATA,
6331 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
6332 }
1da177e4
LT
6333}
6334
6335/*
6336 * void
6337 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
6338 *
6339 * Calling/Exit State:
6340 * none
6341 *
6342 * Description:
6343 * Input an ASC_QDONE_INFO structure from the chip
6344 */
27c868c2 6345static void
1da177e4
LT
6346DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
6347{
27c868c2
MW
6348 int i;
6349 ushort word;
6350
6351 AscSetChipLramAddr(iop_base, s_addr);
6352 for (i = 0; i < 2 * words; i += 2) {
6353 if (i == 10) {
6354 continue;
6355 }
6356 word = inpw(iop_base + IOP_RAM_DATA);
6357 inbuf[i] = word & 0xff;
6358 inbuf[i + 1] = (word >> 8) & 0xff;
6359 }
6360 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
1da177e4
LT
6361}
6362
1da177e4
LT
6363/*
6364 * Return the BIOS address of the adapter at the specified
6365 * I/O port and with the specified bus type.
6366 */
ecec1947
MW
6367static unsigned short __devinit
6368AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
1da177e4 6369{
ecec1947
MW
6370 unsigned short cfg_lsw;
6371 unsigned short bios_addr;
27c868c2
MW
6372
6373 /*
6374 * The PCI BIOS is re-located by the motherboard BIOS. Because
6375 * of this the driver can not determine where a PCI BIOS is
6376 * loaded and executes.
6377 */
ecec1947
MW
6378 if (bus_type & ASC_IS_PCI)
6379 return 0;
6380
1da177e4 6381#ifdef CONFIG_ISA
27c868c2
MW
6382 if ((bus_type & ASC_IS_EISA) != 0) {
6383 cfg_lsw = AscGetEisaChipCfg(iop_base);
6384 cfg_lsw &= 0x000F;
ecec1947
MW
6385 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
6386 return bios_addr;
6387 }
1da177e4
LT
6388#endif /* CONFIG_ISA */
6389
27c868c2 6390 cfg_lsw = AscGetChipCfgLsw(iop_base);
1da177e4 6391
27c868c2
MW
6392 /*
6393 * ISA PnP uses the top bit as the 32K BIOS flag
6394 */
ecec1947 6395 if (bus_type == ASC_IS_ISAPNP)
27c868c2 6396 cfg_lsw &= 0x7FFF;
ecec1947
MW
6397 bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
6398 return bios_addr;
1da177e4
LT
6399}
6400
1da177e4
LT
6401/*
6402 * --- Functions Required by the Adv Library
6403 */
6404
6405/*
6406 * DvcGetPhyAddr()
6407 *
6408 * Return the physical address of 'vaddr' and set '*lenp' to the
6409 * number of physically contiguous bytes that follow 'vaddr'.
6410 * 'flag' indicates the type of structure whose physical address
6411 * is being translated.
6412 *
6413 * Note: Because Linux currently doesn't page the kernel and all
6414 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6415 */
6416ADV_PADDR
6417DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
27c868c2 6418 uchar *vaddr, ADV_SDCNT *lenp, int flag)
1da177e4 6419{
27c868c2 6420 ADV_PADDR paddr;
1da177e4 6421
27c868c2 6422 paddr = virt_to_bus(vaddr);
1da177e4 6423
27c868c2
MW
6424 ASC_DBG4(4,
6425 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
6426 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
6427 (ulong)paddr);
1da177e4 6428
27c868c2 6429 return paddr;
1da177e4
LT
6430}
6431
1da177e4
LT
6432/*
6433 * --- Tracing and Debugging Functions
6434 */
6435
6436#ifdef ADVANSYS_STATS
6437#ifdef CONFIG_PROC_FS
6438/*
6439 * asc_prt_board_stats()
6440 *
6441 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6442 * cf. asc_prt_line().
6443 *
6444 * Return the number of characters copied into 'cp'. No more than
6445 * 'cplen' characters will be copied to 'cp'.
6446 */
27c868c2 6447static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
1da177e4 6448{
27c868c2
MW
6449 int leftlen;
6450 int totlen;
6451 int len;
6452 struct asc_stats *s;
6453 asc_board_t *boardp;
1da177e4 6454
27c868c2
MW
6455 leftlen = cplen;
6456 totlen = len = 0;
6457
6458 boardp = ASC_BOARDP(shost);
6459 s = &boardp->asc_stats;
6460
6461 len = asc_prt_line(cp, leftlen,
6462 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
6463 shost->host_no);
6464 ASC_PRT_NEXT();
6465
6466 len = asc_prt_line(cp, leftlen,
6467 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
6468 s->queuecommand, s->reset, s->biosparam,
6469 s->interrupt);
6470 ASC_PRT_NEXT();
6471
6472 len = asc_prt_line(cp, leftlen,
6473 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
6474 s->callback, s->done, s->build_error,
6475 s->adv_build_noreq, s->adv_build_nosg);
6476 ASC_PRT_NEXT();
6477
6478 len = asc_prt_line(cp, leftlen,
6479 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
6480 s->exe_noerror, s->exe_busy, s->exe_error,
6481 s->exe_unknown);
6482 ASC_PRT_NEXT();
6483
6484 /*
6485 * Display data transfer statistics.
6486 */
6487 if (s->cont_cnt > 0) {
6488 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
6489 ASC_PRT_NEXT();
6490
6491 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
6492 s->cont_xfer / 2,
6493 ASC_TENTHS(s->cont_xfer, 2));
6494 ASC_PRT_NEXT();
6495
6496 /* Contiguous transfer average size */
6497 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
6498 (s->cont_xfer / 2) / s->cont_cnt,
6499 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
6500 ASC_PRT_NEXT();
6501 }
1da177e4 6502
27c868c2 6503 if (s->sg_cnt > 0) {
1da177e4 6504
27c868c2
MW
6505 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
6506 s->sg_cnt, s->sg_elem);
6507 ASC_PRT_NEXT();
1da177e4 6508
27c868c2
MW
6509 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
6510 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
6511 ASC_PRT_NEXT();
1da177e4 6512
27c868c2
MW
6513 /* Scatter gather transfer statistics */
6514 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
6515 s->sg_elem / s->sg_cnt,
6516 ASC_TENTHS(s->sg_elem, s->sg_cnt));
6517 ASC_PRT_NEXT();
1da177e4 6518
27c868c2
MW
6519 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
6520 (s->sg_xfer / 2) / s->sg_elem,
6521 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
6522 ASC_PRT_NEXT();
1da177e4 6523
27c868c2
MW
6524 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
6525 (s->sg_xfer / 2) / s->sg_cnt,
6526 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
6527 ASC_PRT_NEXT();
6528 }
1da177e4 6529
27c868c2
MW
6530 /*
6531 * Display request queuing statistics.
6532 */
6533 len = asc_prt_line(cp, leftlen,
6534 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
6535 HZ);
6536 ASC_PRT_NEXT();
1da177e4 6537
27c868c2 6538 return totlen;
1da177e4
LT
6539}
6540
6541/*
6542 * asc_prt_target_stats()
6543 *
6544 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6545 * cf. asc_prt_line().
6546 *
6547 * This is separated from asc_prt_board_stats because a full set
6548 * of targets will overflow ASC_PRTBUF_SIZE.
6549 *
6550 * Return the number of characters copied into 'cp'. No more than
6551 * 'cplen' characters will be copied to 'cp'.
6552 */
27c868c2
MW
6553static int
6554asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
1da177e4 6555{
27c868c2
MW
6556 int leftlen;
6557 int totlen;
6558 int len;
6559 struct asc_stats *s;
6560 ushort chip_scsi_id;
6561 asc_board_t *boardp;
6562 asc_queue_t *active;
1da177e4 6563
27c868c2
MW
6564 leftlen = cplen;
6565 totlen = len = 0;
6566
6567 boardp = ASC_BOARDP(shost);
6568 s = &boardp->asc_stats;
6569
6570 active = &ASC_BOARDP(shost)->active;
27c868c2
MW
6571
6572 if (ASC_NARROW_BOARD(boardp)) {
6573 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6574 } else {
6575 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6576 }
6577
6578 if ((chip_scsi_id == tgt_id) ||
6579 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
6580 return 0;
6581 }
1da177e4 6582
27c868c2 6583 do {
b6622925 6584 if (active->q_tot_cnt[tgt_id] > 0) {
27c868c2
MW
6585 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
6586 ASC_PRT_NEXT();
6587
6588 len = asc_prt_line(cp, leftlen,
6589 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
6590 active->q_cur_cnt[tgt_id],
6591 active->q_max_cnt[tgt_id],
6592 active->q_tot_cnt[tgt_id],
6593 active->q_min_tim[tgt_id],
6594 active->q_max_tim[tgt_id],
6595 (active->q_tot_cnt[tgt_id] ==
6596 0) ? 0 : (active->
6597 q_tot_tim[tgt_id] /
6598 active->
6599 q_tot_cnt[tgt_id]),
6600 (active->q_tot_cnt[tgt_id] ==
6601 0) ? 0 : ASC_TENTHS(active->
6602 q_tot_tim
6603 [tgt_id],
6604 active->
6605 q_tot_cnt
6606 [tgt_id]));
6607 ASC_PRT_NEXT();
27c868c2
MW
6608 }
6609 } while (0);
6610
6611 return totlen;
1da177e4
LT
6612}
6613#endif /* CONFIG_PROC_FS */
6614#endif /* ADVANSYS_STATS */
6615
6616#ifdef ADVANSYS_DEBUG
6617/*
6618 * asc_prt_scsi_host()
6619 */
27c868c2 6620static void asc_prt_scsi_host(struct Scsi_Host *s)
1da177e4 6621{
27c868c2
MW
6622 asc_board_t *boardp;
6623
6624 boardp = ASC_BOARDP(s);
6625
6626 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
6627 printk(" host_busy %u, host_no %d, last_reset %d,\n",
6628 s->host_busy, s->host_no, (unsigned)s->last_reset);
6629
4a2d31c8
MW
6630 printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
6631 (ulong)s->base, (ulong)s->io_port, s->irq);
27c868c2
MW
6632
6633 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
6634 s->dma_channel, s->this_id, s->can_queue);
6635
6636 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
6637 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
6638
6639 if (ASC_NARROW_BOARD(boardp)) {
6640 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
6641 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
6642 } else {
6643 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
6644 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
6645 }
1da177e4
LT
6646}
6647
6648/*
6649 * asc_prt_scsi_cmnd()
6650 */
27c868c2 6651static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
1da177e4 6652{
27c868c2 6653 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
1da177e4 6654
27c868c2
MW
6655 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
6656 (ulong)s->device->host, (ulong)s->device, s->device->id,
6657 s->device->lun, s->device->channel);
1da177e4 6658
27c868c2 6659 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
1da177e4 6660
27c868c2
MW
6661 printk("sc_data_direction %u, resid %d\n",
6662 s->sc_data_direction, s->resid);
1da177e4 6663
27c868c2 6664 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
1da177e4 6665
27c868c2
MW
6666 printk(" serial_number 0x%x, retries %d, allowed %d\n",
6667 (unsigned)s->serial_number, s->retries, s->allowed);
1da177e4 6668
27c868c2 6669 printk(" timeout_per_command %d\n", s->timeout_per_command);
1da177e4 6670
ecec1947
MW
6671 printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
6672 s->scsi_done, s->done, s->host_scribble, s->result);
1da177e4 6673
27c868c2 6674 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
1da177e4
LT
6675}
6676
6677/*
6678 * asc_prt_asc_dvc_var()
6679 */
27c868c2 6680static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
1da177e4 6681{
27c868c2
MW
6682 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
6683
ecec1947
MW
6684 printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
6685 "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
27c868c2 6686
895d6b4c
MW
6687 printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
6688 (unsigned)h->init_sdtr);
27c868c2 6689
ecec1947
MW
6690 printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
6691 "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
6692 (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
6693 (unsigned)h->chip_no);
27c868c2 6694
ecec1947
MW
6695 printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
6696 "%u,\n", (unsigned)h->queue_full_or_busy,
6697 (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
27c868c2 6698
ecec1947
MW
6699 printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
6700 "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
6701 (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
6702 (unsigned)h->in_critical_cnt);
27c868c2 6703
ecec1947
MW
6704 printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
6705 "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
6706 (unsigned)h->init_state, (unsigned)h->no_scam,
6707 (unsigned)h->pci_fix_asyn_xfer);
27c868c2
MW
6708
6709 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
1da177e4
LT
6710}
6711
6712/*
6713 * asc_prt_asc_dvc_cfg()
6714 */
27c868c2 6715static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
1da177e4 6716{
27c868c2
MW
6717 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
6718
6719 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
6720 h->can_tagged_qng, h->cmd_qng_enabled);
6721 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
6722 h->disc_enable, h->sdtr_enable);
6723
6724 printk
6725 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
6726 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
6727 h->chip_version);
6728
6729 printk
6730 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
6731 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
6732 h->mcode_date);
6733
6734 printk(" mcode_version %d, overrun_buf 0x%lx\n",
6735 h->mcode_version, (ulong)h->overrun_buf);
1da177e4
LT
6736}
6737
6738/*
6739 * asc_prt_asc_scsi_q()
6740 */
27c868c2 6741static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
1da177e4 6742{
27c868c2
MW
6743 ASC_SG_HEAD *sgp;
6744 int i;
6745
6746 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
6747
6748 printk
6749 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
6750 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
6751 q->q2.tag_code);
6752
6753 printk
6754 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6755 (ulong)le32_to_cpu(q->q1.data_addr),
6756 (ulong)le32_to_cpu(q->q1.data_cnt),
6757 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
6758
6759 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
6760 (ulong)q->cdbptr, q->q2.cdb_len,
6761 (ulong)q->sg_head, q->q1.sg_queue_cnt);
6762
6763 if (q->sg_head) {
6764 sgp = q->sg_head;
6765 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
6766 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
6767 sgp->queue_cnt);
6768 for (i = 0; i < sgp->entry_cnt; i++) {
6769 printk(" [%u]: addr 0x%lx, bytes %lu\n",
6770 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
6771 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
6772 }
1da177e4 6773
27c868c2 6774 }
1da177e4
LT
6775}
6776
6777/*
6778 * asc_prt_asc_qdone_info()
6779 */
27c868c2 6780static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
1da177e4 6781{
27c868c2
MW
6782 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
6783 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
6784 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
6785 q->d2.tag_code);
6786 printk
6787 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
6788 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
1da177e4
LT
6789}
6790
6791/*
6792 * asc_prt_adv_dvc_var()
6793 *
6794 * Display an ADV_DVC_VAR structure.
6795 */
27c868c2 6796static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
1da177e4 6797{
27c868c2
MW
6798 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
6799
6800 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
6801 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
6802
6803 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
6804 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
6805 (unsigned)h->wdtr_able);
6806
6807 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
6808 (unsigned)h->start_motor,
6809 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
6810
6811 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
6812 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
6813 (ulong)h->carr_freelist);
6814
6815 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
6816 (ulong)h->icq_sp, (ulong)h->irq_sp);
6817
6818 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
6819 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
6820
6821 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
6822 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
1da177e4
LT
6823}
6824
6825/*
6826 * asc_prt_adv_dvc_cfg()
6827 *
6828 * Display an ADV_DVC_CFG structure.
6829 */
27c868c2 6830static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
1da177e4 6831{
27c868c2 6832 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
1da177e4 6833
27c868c2
MW
6834 printk(" disc_enable 0x%x, termination 0x%x\n",
6835 h->disc_enable, h->termination);
1da177e4 6836
27c868c2
MW
6837 printk(" chip_version 0x%x, mcode_date 0x%x\n",
6838 h->chip_version, h->mcode_date);
1da177e4 6839
27c868c2
MW
6840 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
6841 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
1da177e4 6842
13ac2d9c 6843 printk(" control_flag 0x%x\n", h->control_flag);
1da177e4
LT
6844}
6845
6846/*
6847 * asc_prt_adv_scsi_req_q()
6848 *
6849 * Display an ADV_SCSI_REQ_Q structure.
6850 */
27c868c2 6851static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
1da177e4 6852{
27c868c2
MW
6853 int sg_blk_cnt;
6854 struct asc_sg_block *sg_ptr;
6855
6856 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
6857
6858 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
6859 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
6860
6861 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
6862 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
6863
6864 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6865 (ulong)le32_to_cpu(q->data_cnt),
6866 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
6867
6868 printk
6869 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
6870 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
6871
6872 printk(" sg_working_ix 0x%x, target_cmd %u\n",
6873 q->sg_working_ix, q->target_cmd);
6874
6875 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
6876 (ulong)le32_to_cpu(q->scsiq_rptr),
6877 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
6878
6879 /* Display the request's ADV_SG_BLOCK structures. */
6880 if (q->sg_list_ptr != NULL) {
6881 sg_blk_cnt = 0;
6882 while (1) {
6883 /*
6884 * 'sg_ptr' is a physical address. Convert it to a virtual
6885 * address by indexing 'sg_blk_cnt' into the virtual address
6886 * array 'sg_list_ptr'.
6887 *
6888 * XXX - Assumes all SG physical blocks are virtually contiguous.
6889 */
6890 sg_ptr =
6891 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
6892 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
6893 if (sg_ptr->sg_ptr == 0) {
6894 break;
6895 }
6896 sg_blk_cnt++;
6897 }
6898 }
1da177e4
LT
6899}
6900
6901/*
6902 * asc_prt_adv_sgblock()
6903 *
6904 * Display an ADV_SG_BLOCK structure.
6905 */
27c868c2 6906static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
1da177e4 6907{
27c868c2
MW
6908 int i;
6909
6910 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
6911 (ulong)b, sgblockno);
6912 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
6913 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
6914 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
6915 if (b->sg_ptr != 0) {
6916 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
6917 }
6918 for (i = 0; i < b->sg_cnt; i++) {
6919 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
6920 i, (ulong)b->sg_list[i].sg_addr,
6921 (ulong)b->sg_list[i].sg_count);
6922 }
1da177e4
LT
6923}
6924
6925/*
6926 * asc_prt_hex()
6927 *
6928 * Print hexadecimal output in 4 byte groupings 32 bytes
6929 * or 8 double-words per line.
6930 */
27c868c2 6931static void asc_prt_hex(char *f, uchar *s, int l)
1da177e4 6932{
27c868c2
MW
6933 int i;
6934 int j;
6935 int k;
6936 int m;
6937
6938 printk("%s: (%d bytes)\n", f, l);
6939
6940 for (i = 0; i < l; i += 32) {
6941
6942 /* Display a maximum of 8 double-words per line. */
6943 if ((k = (l - i) / 4) >= 8) {
6944 k = 8;
6945 m = 0;
6946 } else {
6947 m = (l - i) % 4;
6948 }
6949
6950 for (j = 0; j < k; j++) {
6951 printk(" %2.2X%2.2X%2.2X%2.2X",
6952 (unsigned)s[i + (j * 4)],
6953 (unsigned)s[i + (j * 4) + 1],
6954 (unsigned)s[i + (j * 4) + 2],
6955 (unsigned)s[i + (j * 4) + 3]);
6956 }
6957
6958 switch (m) {
6959 case 0:
6960 default:
6961 break;
6962 case 1:
6963 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
6964 break;
6965 case 2:
6966 printk(" %2.2X%2.2X",
6967 (unsigned)s[i + (j * 4)],
6968 (unsigned)s[i + (j * 4) + 1]);
6969 break;
6970 case 3:
6971 printk(" %2.2X%2.2X%2.2X",
6972 (unsigned)s[i + (j * 4) + 1],
6973 (unsigned)s[i + (j * 4) + 2],
6974 (unsigned)s[i + (j * 4) + 3]);
6975 break;
6976 }
6977
6978 printk("\n");
6979 }
1da177e4
LT
6980}
6981#endif /* ADVANSYS_DEBUG */
6982
6983/*
6984 * --- Asc Library Functions
6985 */
6986
78e77d8b 6987static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
1da177e4 6988{
27c868c2 6989 PortAddr eisa_cfg_iop;
1da177e4 6990
27c868c2
MW
6991 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
6992 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
6993 return (inpw(eisa_cfg_iop));
1da177e4
LT
6994}
6995
78e77d8b 6996static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
1da177e4 6997{
27c868c2 6998 ushort cfg_lsw;
1da177e4 6999
27c868c2
MW
7000 if (AscGetChipScsiID(iop_base) == new_host_id) {
7001 return (new_host_id);
7002 }
7003 cfg_lsw = AscGetChipCfgLsw(iop_base);
7004 cfg_lsw &= 0xF8FF;
7005 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
7006 AscSetChipCfgLsw(iop_base, cfg_lsw);
7007 return (AscGetChipScsiID(iop_base));
1da177e4
LT
7008}
7009
ecec1947 7010static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
1da177e4 7011{
ecec1947 7012 unsigned char sc;
1da177e4 7013
27c868c2
MW
7014 AscSetBank(iop_base, 1);
7015 sc = inp(iop_base + IOP_REG_SC);
7016 AscSetBank(iop_base, 0);
ecec1947 7017 return sc;
1da177e4
LT
7018}
7019
ecec1947
MW
7020static unsigned char __devinit
7021AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
1da177e4 7022{
ecec1947 7023 if (bus_type & ASC_IS_EISA) {
27c868c2 7024 PortAddr eisa_iop;
ecec1947 7025 unsigned char revision;
27c868c2
MW
7026 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7027 (PortAddr) ASC_EISA_REV_IOP_MASK;
7028 revision = inp(eisa_iop);
ecec1947 7029 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
27c868c2 7030 }
ecec1947 7031 return AscGetChipVerNo(iop_base);
1da177e4
LT
7032}
7033
27c868c2
MW
7034static ASC_DCNT
7035AscLoadMicroCode(PortAddr iop_base,
7036 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
1da177e4 7037{
27c868c2
MW
7038 ASC_DCNT chksum;
7039 ushort mcode_word_size;
7040 ushort mcode_chksum;
7041
7042 /* Write the microcode buffer starting at LRAM address 0. */
7043 mcode_word_size = (ushort)(mcode_size >> 1);
7044 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
7045 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
7046
7047 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
7048 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
7049 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
7050 (ushort)ASC_CODE_SEC_BEG,
7051 (ushort)((mcode_size -
7052 s_addr - (ushort)
7053 ASC_CODE_SEC_BEG) /
7054 2));
7055 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
7056 (ulong)mcode_chksum);
7057 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
7058 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
7059 return (chksum);
1da177e4
LT
7060}
7061
27c868c2 7062static int AscFindSignature(PortAddr iop_base)
1da177e4 7063{
27c868c2
MW
7064 ushort sig_word;
7065
7066 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
7067 iop_base, AscGetChipSignatureByte(iop_base));
7068 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
7069 ASC_DBG2(1,
7070 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
7071 iop_base, AscGetChipSignatureWord(iop_base));
7072 sig_word = AscGetChipSignatureWord(iop_base);
7073 if ((sig_word == (ushort)ASC_1000_ID0W) ||
7074 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
7075 return (1);
7076 }
7077 }
7078 return (0);
1da177e4
LT
7079}
7080
78e77d8b 7081static void __devinit AscToggleIRQAct(PortAddr iop_base)
1da177e4 7082{
27c868c2
MW
7083 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
7084 AscSetChipStatus(iop_base, 0);
7085 return;
1da177e4
LT
7086}
7087
78e77d8b 7088static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
1da177e4 7089{
27c868c2
MW
7090 ushort cfg_lsw;
7091 uchar chip_irq;
7092
7093 if ((bus_type & ASC_IS_EISA) != 0) {
7094 cfg_lsw = AscGetEisaChipCfg(iop_base);
7095 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
7096 if ((chip_irq == 13) || (chip_irq > 15)) {
7097 return (0);
7098 }
7099 return (chip_irq);
7100 }
7101 if ((bus_type & ASC_IS_VL) != 0) {
7102 cfg_lsw = AscGetChipCfgLsw(iop_base);
7103 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
7104 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
7105 return (0);
7106 }
7107 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
7108 }
7109 cfg_lsw = AscGetChipCfgLsw(iop_base);
7110 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
7111 if (chip_irq == 3)
7112 chip_irq += (uchar)2;
7113 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
1da177e4
LT
7114}
7115
78e77d8b 7116static uchar __devinit
27c868c2 7117AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
1da177e4 7118{
27c868c2
MW
7119 ushort cfg_lsw;
7120
7121 if ((bus_type & ASC_IS_VL) != 0) {
7122 if (irq_no != 0) {
7123 if ((irq_no < ASC_MIN_IRQ_NO)
7124 || (irq_no > ASC_MAX_IRQ_NO)) {
7125 irq_no = 0;
7126 } else {
7127 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
7128 }
7129 }
7130 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
7131 cfg_lsw |= (ushort)0x0010;
7132 AscSetChipCfgLsw(iop_base, cfg_lsw);
7133 AscToggleIRQAct(iop_base);
7134 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
7135 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
7136 AscSetChipCfgLsw(iop_base, cfg_lsw);
7137 AscToggleIRQAct(iop_base);
7138 return (AscGetChipIRQ(iop_base, bus_type));
7139 }
7140 if ((bus_type & (ASC_IS_ISA)) != 0) {
7141 if (irq_no == 15)
7142 irq_no -= (uchar)2;
7143 irq_no -= (uchar)ASC_MIN_IRQ_NO;
7144 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
7145 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
7146 AscSetChipCfgLsw(iop_base, cfg_lsw);
7147 return (AscGetChipIRQ(iop_base, bus_type));
7148 }
7149 return (0);
1da177e4
LT
7150}
7151
7152#ifdef CONFIG_ISA
78e77d8b 7153static void __devinit AscEnableIsaDma(uchar dma_channel)
1da177e4 7154{
27c868c2
MW
7155 if (dma_channel < 4) {
7156 outp(0x000B, (ushort)(0xC0 | dma_channel));
7157 outp(0x000A, dma_channel);
7158 } else if (dma_channel < 8) {
7159 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
7160 outp(0x00D4, (ushort)(dma_channel - 4));
7161 }
7162 return;
1da177e4
LT
7163}
7164#endif /* CONFIG_ISA */
7165
27c868c2 7166static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
1da177e4 7167{
27c868c2
MW
7168 EXT_MSG ext_msg;
7169 EXT_MSG out_msg;
7170 ushort halt_q_addr;
7171 int sdtr_accept;
7172 ushort int_halt_code;
7173 ASC_SCSI_BIT_ID_TYPE scsi_busy;
7174 ASC_SCSI_BIT_ID_TYPE target_id;
7175 PortAddr iop_base;
7176 uchar tag_code;
7177 uchar q_status;
7178 uchar halt_qp;
7179 uchar sdtr_data;
7180 uchar target_ix;
7181 uchar q_cntl, tid_no;
7182 uchar cur_dvc_qng;
7183 uchar asyn_sdtr;
7184 uchar scsi_status;
7185 asc_board_t *boardp;
7186
7187 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
7188 boardp = asc_dvc->drv_ptr;
7189
7190 iop_base = asc_dvc->iop_base;
7191 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
7192
7193 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
7194 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
7195 target_ix = AscReadLramByte(iop_base,
7196 (ushort)(halt_q_addr +
7197 (ushort)ASC_SCSIQ_B_TARGET_IX));
7198 q_cntl =
7199 AscReadLramByte(iop_base,
7200 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
7201 tid_no = ASC_TIX_TO_TID(target_ix);
7202 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
7203 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
7204 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
7205 } else {
7206 asyn_sdtr = 0;
7207 }
7208 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
7209 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
7210 AscSetChipSDTR(iop_base, 0, tid_no);
7211 boardp->sdtr_data[tid_no] = 0;
7212 }
7213 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7214 return (0);
7215 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
7216 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
7217 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
7218 boardp->sdtr_data[tid_no] = asyn_sdtr;
7219 }
7220 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7221 return (0);
7222 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
7223
7224 AscMemWordCopyPtrFromLram(iop_base,
7225 ASCV_MSGIN_BEG,
7226 (uchar *)&ext_msg,
7227 sizeof(EXT_MSG) >> 1);
7228
47d853cc
MW
7229 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
7230 ext_msg.msg_req == EXTENDED_SDTR &&
27c868c2
MW
7231 ext_msg.msg_len == MS_SDTR_LEN) {
7232 sdtr_accept = TRUE;
7233 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
7234
7235 sdtr_accept = FALSE;
7236 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
7237 }
7238 if ((ext_msg.xfer_period <
7239 asc_dvc->sdtr_period_tbl[asc_dvc->
7240 host_init_sdtr_index])
7241 || (ext_msg.xfer_period >
7242 asc_dvc->sdtr_period_tbl[asc_dvc->
7243 max_sdtr_index])) {
7244 sdtr_accept = FALSE;
7245 ext_msg.xfer_period =
7246 asc_dvc->sdtr_period_tbl[asc_dvc->
7247 host_init_sdtr_index];
7248 }
7249 if (sdtr_accept) {
7250 sdtr_data =
7251 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
7252 ext_msg.req_ack_offset);
7253 if ((sdtr_data == 0xFF)) {
7254
7255 q_cntl |= QC_MSG_OUT;
7256 asc_dvc->init_sdtr &= ~target_id;
7257 asc_dvc->sdtr_done &= ~target_id;
7258 AscSetChipSDTR(iop_base, asyn_sdtr,
7259 tid_no);
7260 boardp->sdtr_data[tid_no] = asyn_sdtr;
7261 }
7262 }
7263 if (ext_msg.req_ack_offset == 0) {
7264
7265 q_cntl &= ~QC_MSG_OUT;
7266 asc_dvc->init_sdtr &= ~target_id;
7267 asc_dvc->sdtr_done &= ~target_id;
7268 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
7269 } else {
7270 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
7271
7272 q_cntl &= ~QC_MSG_OUT;
7273 asc_dvc->sdtr_done |= target_id;
7274 asc_dvc->init_sdtr |= target_id;
7275 asc_dvc->pci_fix_asyn_xfer &=
7276 ~target_id;
7277 sdtr_data =
7278 AscCalSDTRData(asc_dvc,
7279 ext_msg.xfer_period,
7280 ext_msg.
7281 req_ack_offset);
7282 AscSetChipSDTR(iop_base, sdtr_data,
7283 tid_no);
7284 boardp->sdtr_data[tid_no] = sdtr_data;
7285 } else {
7286
7287 q_cntl |= QC_MSG_OUT;
7288 AscMsgOutSDTR(asc_dvc,
7289 ext_msg.xfer_period,
7290 ext_msg.req_ack_offset);
7291 asc_dvc->pci_fix_asyn_xfer &=
7292 ~target_id;
7293 sdtr_data =
7294 AscCalSDTRData(asc_dvc,
7295 ext_msg.xfer_period,
7296 ext_msg.
7297 req_ack_offset);
7298 AscSetChipSDTR(iop_base, sdtr_data,
7299 tid_no);
7300 boardp->sdtr_data[tid_no] = sdtr_data;
7301 asc_dvc->sdtr_done |= target_id;
7302 asc_dvc->init_sdtr |= target_id;
7303 }
7304 }
7305
7306 AscWriteLramByte(iop_base,
7307 (ushort)(halt_q_addr +
7308 (ushort)ASC_SCSIQ_B_CNTL),
7309 q_cntl);
7310 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7311 return (0);
47d853cc
MW
7312 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
7313 ext_msg.msg_req == EXTENDED_WDTR &&
27c868c2
MW
7314 ext_msg.msg_len == MS_WDTR_LEN) {
7315
7316 ext_msg.wdtr_width = 0;
7317 AscMemWordCopyPtrToLram(iop_base,
7318 ASCV_MSGOUT_BEG,
7319 (uchar *)&ext_msg,
7320 sizeof(EXT_MSG) >> 1);
7321 q_cntl |= QC_MSG_OUT;
7322 AscWriteLramByte(iop_base,
7323 (ushort)(halt_q_addr +
7324 (ushort)ASC_SCSIQ_B_CNTL),
7325 q_cntl);
7326 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7327 return (0);
7328 } else {
7329
7330 ext_msg.msg_type = MESSAGE_REJECT;
7331 AscMemWordCopyPtrToLram(iop_base,
7332 ASCV_MSGOUT_BEG,
7333 (uchar *)&ext_msg,
7334 sizeof(EXT_MSG) >> 1);
7335 q_cntl |= QC_MSG_OUT;
7336 AscWriteLramByte(iop_base,
7337 (ushort)(halt_q_addr +
7338 (ushort)ASC_SCSIQ_B_CNTL),
7339 q_cntl);
7340 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7341 return (0);
7342 }
7343 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
7344
7345 q_cntl |= QC_REQ_SENSE;
7346
7347 if ((asc_dvc->init_sdtr & target_id) != 0) {
7348
7349 asc_dvc->sdtr_done &= ~target_id;
7350
7351 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7352 q_cntl |= QC_MSG_OUT;
7353 AscMsgOutSDTR(asc_dvc,
7354 asc_dvc->
7355 sdtr_period_tbl[(sdtr_data >> 4) &
7356 (uchar)(asc_dvc->
7357 max_sdtr_index -
7358 1)],
7359 (uchar)(sdtr_data & (uchar)
7360 ASC_SYN_MAX_OFFSET));
7361 }
7362
7363 AscWriteLramByte(iop_base,
7364 (ushort)(halt_q_addr +
7365 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
7366
7367 tag_code = AscReadLramByte(iop_base,
7368 (ushort)(halt_q_addr + (ushort)
7369 ASC_SCSIQ_B_TAG_CODE));
7370 tag_code &= 0xDC;
7371 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
7372 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
7373 ) {
7374
7375 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
7376 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
7377
7378 }
7379 AscWriteLramByte(iop_base,
7380 (ushort)(halt_q_addr +
7381 (ushort)ASC_SCSIQ_B_TAG_CODE),
7382 tag_code);
7383
7384 q_status = AscReadLramByte(iop_base,
7385 (ushort)(halt_q_addr + (ushort)
7386 ASC_SCSIQ_B_STATUS));
7387 q_status |= (QS_READY | QS_BUSY);
7388 AscWriteLramByte(iop_base,
7389 (ushort)(halt_q_addr +
7390 (ushort)ASC_SCSIQ_B_STATUS),
7391 q_status);
7392
7393 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
7394 scsi_busy &= ~target_id;
7395 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
7396
7397 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7398 return (0);
7399 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
7400
7401 AscMemWordCopyPtrFromLram(iop_base,
7402 ASCV_MSGOUT_BEG,
7403 (uchar *)&out_msg,
7404 sizeof(EXT_MSG) >> 1);
7405
47d853cc 7406 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
27c868c2 7407 (out_msg.msg_len == MS_SDTR_LEN) &&
47d853cc 7408 (out_msg.msg_req == EXTENDED_SDTR)) {
27c868c2
MW
7409
7410 asc_dvc->init_sdtr &= ~target_id;
7411 asc_dvc->sdtr_done &= ~target_id;
7412 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
7413 boardp->sdtr_data[tid_no] = asyn_sdtr;
7414 }
7415 q_cntl &= ~QC_MSG_OUT;
7416 AscWriteLramByte(iop_base,
7417 (ushort)(halt_q_addr +
7418 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
7419 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7420 return (0);
7421 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
7422
7423 scsi_status = AscReadLramByte(iop_base,
7424 (ushort)((ushort)halt_q_addr +
7425 (ushort)
7426 ASC_SCSIQ_SCSI_STATUS));
7427 cur_dvc_qng =
7428 AscReadLramByte(iop_base,
7429 (ushort)((ushort)ASC_QADR_BEG +
7430 (ushort)target_ix));
7431 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
7432
7433 scsi_busy = AscReadLramByte(iop_base,
7434 (ushort)ASCV_SCSIBUSY_B);
7435 scsi_busy |= target_id;
7436 AscWriteLramByte(iop_base,
7437 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
7438 asc_dvc->queue_full_or_busy |= target_id;
7439
7440 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
7441 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
7442 cur_dvc_qng -= 1;
7443 asc_dvc->max_dvc_qng[tid_no] =
7444 cur_dvc_qng;
7445
7446 AscWriteLramByte(iop_base,
7447 (ushort)((ushort)
7448 ASCV_MAX_DVC_QNG_BEG
7449 + (ushort)
7450 tid_no),
7451 cur_dvc_qng);
7452
7453 /*
7454 * Set the device queue depth to the number of
7455 * active requests when the QUEUE FULL condition
7456 * was encountered.
7457 */
7458 boardp->queue_full |= target_id;
7459 boardp->queue_full_cnt[tid_no] =
7460 cur_dvc_qng;
7461 }
7462 }
7463 }
7464 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7465 return (0);
7466 }
1da177e4 7467#if CC_VERY_LONG_SG_LIST
27c868c2
MW
7468 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
7469 uchar q_no;
7470 ushort q_addr;
7471 uchar sg_wk_q_no;
7472 uchar first_sg_wk_q_no;
7473 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
7474 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
7475 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
7476 ushort sg_list_dwords;
7477 ushort sg_entry_cnt;
7478 uchar next_qp;
7479 int i;
7480
7481 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
7482 if (q_no == ASC_QLINK_END) {
7483 return (0);
7484 }
7485
7486 q_addr = ASC_QNO_TO_QADDR(q_no);
7487
7488 /*
7489 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
7490 * structure pointer using a macro provided by the driver.
7491 * The ASC_SCSI_REQ pointer provides a pointer to the
7492 * host ASC_SG_HEAD structure.
7493 */
7494 /* Read request's SRB pointer. */
7495 scsiq = (ASC_SCSI_Q *)
7496 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
7497 (ushort)
7498 (q_addr +
7499 ASC_SCSIQ_D_SRBPTR))));
7500
7501 /*
7502 * Get request's first and working SG queue.
7503 */
7504 sg_wk_q_no = AscReadLramByte(iop_base,
7505 (ushort)(q_addr +
7506 ASC_SCSIQ_B_SG_WK_QP));
7507
7508 first_sg_wk_q_no = AscReadLramByte(iop_base,
7509 (ushort)(q_addr +
7510 ASC_SCSIQ_B_FIRST_SG_WK_QP));
7511
7512 /*
7513 * Reset request's working SG queue back to the
7514 * first SG queue.
7515 */
7516 AscWriteLramByte(iop_base,
7517 (ushort)(q_addr +
7518 (ushort)ASC_SCSIQ_B_SG_WK_QP),
7519 first_sg_wk_q_no);
7520
7521 sg_head = scsiq->sg_head;
7522
7523 /*
7524 * Set sg_entry_cnt to the number of SG elements
7525 * that will be completed on this interrupt.
7526 *
7527 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
7528 * SG elements. The data_cnt and data_addr fields which
7529 * add 1 to the SG element capacity are not used when
7530 * restarting SG handling after a halt.
7531 */
7532 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
7533 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
7534
7535 /*
7536 * Keep track of remaining number of SG elements that will
7537 * need to be handled on the next interrupt.
7538 */
7539 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
7540 } else {
7541 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
7542 scsiq->remain_sg_entry_cnt = 0;
7543 }
7544
7545 /*
7546 * Copy SG elements into the list of allocated SG queues.
7547 *
7548 * Last index completed is saved in scsiq->next_sg_index.
7549 */
7550 next_qp = first_sg_wk_q_no;
7551 q_addr = ASC_QNO_TO_QADDR(next_qp);
7552 scsi_sg_q.sg_head_qp = q_no;
7553 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
7554 for (i = 0; i < sg_head->queue_cnt; i++) {
7555 scsi_sg_q.seq_no = i + 1;
7556 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
7557 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
7558 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
7559 /*
7560 * After very first SG queue RISC FW uses next
7561 * SG queue first element then checks sg_list_cnt
7562 * against zero and then decrements, so set
7563 * sg_list_cnt 1 less than number of SG elements
7564 * in each SG queue.
7565 */
7566 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
7567 scsi_sg_q.sg_cur_list_cnt =
7568 ASC_SG_LIST_PER_Q - 1;
7569 } else {
7570 /*
7571 * This is the last SG queue in the list of
7572 * allocated SG queues. If there are more
7573 * SG elements than will fit in the allocated
7574 * queues, then set the QCSG_SG_XFER_MORE flag.
7575 */
7576 if (scsiq->remain_sg_entry_cnt != 0) {
7577 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
7578 } else {
7579 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
7580 }
7581 /* equals sg_entry_cnt * 2 */
7582 sg_list_dwords = sg_entry_cnt << 1;
7583 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
7584 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
7585 sg_entry_cnt = 0;
7586 }
7587
7588 scsi_sg_q.q_no = next_qp;
7589 AscMemWordCopyPtrToLram(iop_base,
7590 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
7591 (uchar *)&scsi_sg_q,
7592 sizeof(ASC_SG_LIST_Q) >> 1);
7593
7594 AscMemDWordCopyPtrToLram(iop_base,
7595 q_addr + ASC_SGQ_LIST_BEG,
7596 (uchar *)&sg_head->
7597 sg_list[scsiq->next_sg_index],
7598 sg_list_dwords);
7599
7600 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
7601
7602 /*
7603 * If the just completed SG queue contained the
7604 * last SG element, then no more SG queues need
7605 * to be written.
7606 */
7607 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
7608 break;
7609 }
7610
7611 next_qp = AscReadLramByte(iop_base,
7612 (ushort)(q_addr +
7613 ASC_SCSIQ_B_FWD));
7614 q_addr = ASC_QNO_TO_QADDR(next_qp);
7615 }
7616
7617 /*
7618 * Clear the halt condition so the RISC will be restarted
7619 * after the return.
7620 */
7621 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7622 return (0);
7623 }
1da177e4 7624#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 7625 return (0);
1da177e4
LT
7626}
7627
27c868c2
MW
7628static uchar
7629_AscCopyLramScsiDoneQ(PortAddr iop_base,
7630 ushort q_addr,
7631 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
1da177e4 7632{
27c868c2
MW
7633 ushort _val;
7634 uchar sg_queue_cnt;
7635
7636 DvcGetQinfo(iop_base,
7637 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
7638 (uchar *)scsiq,
7639 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
7640
7641 _val = AscReadLramWord(iop_base,
7642 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
7643 scsiq->q_status = (uchar)_val;
7644 scsiq->q_no = (uchar)(_val >> 8);
7645 _val = AscReadLramWord(iop_base,
7646 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
7647 scsiq->cntl = (uchar)_val;
7648 sg_queue_cnt = (uchar)(_val >> 8);
7649 _val = AscReadLramWord(iop_base,
7650 (ushort)(q_addr +
7651 (ushort)ASC_SCSIQ_B_SENSE_LEN));
7652 scsiq->sense_len = (uchar)_val;
7653 scsiq->extra_bytes = (uchar)(_val >> 8);
7654
7655 /*
7656 * Read high word of remain bytes from alternate location.
7657 */
7658 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
7659 (ushort)(q_addr +
7660 (ushort)
7661 ASC_SCSIQ_W_ALT_DC1)))
7662 << 16);
7663 /*
7664 * Read low word of remain bytes from original location.
7665 */
7666 scsiq->remain_bytes += AscReadLramWord(iop_base,
7667 (ushort)(q_addr + (ushort)
7668 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
7669
7670 scsiq->remain_bytes &= max_dma_count;
7671 return (sg_queue_cnt);
1da177e4
LT
7672}
7673
27c868c2 7674static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
1da177e4 7675{
27c868c2
MW
7676 uchar next_qp;
7677 uchar n_q_used;
7678 uchar sg_list_qp;
7679 uchar sg_queue_cnt;
7680 uchar q_cnt;
7681 uchar done_q_tail;
7682 uchar tid_no;
7683 ASC_SCSI_BIT_ID_TYPE scsi_busy;
7684 ASC_SCSI_BIT_ID_TYPE target_id;
7685 PortAddr iop_base;
7686 ushort q_addr;
7687 ushort sg_q_addr;
7688 uchar cur_target_qng;
7689 ASC_QDONE_INFO scsiq_buf;
7690 ASC_QDONE_INFO *scsiq;
7691 int false_overrun;
27c868c2
MW
7692
7693 iop_base = asc_dvc->iop_base;
27c868c2
MW
7694 n_q_used = 1;
7695 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
7696 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
7697 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
7698 next_qp = AscReadLramByte(iop_base,
7699 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
7700 if (next_qp != ASC_QLINK_END) {
7701 AscPutVarDoneQTail(iop_base, next_qp);
7702 q_addr = ASC_QNO_TO_QADDR(next_qp);
7703 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
7704 asc_dvc->max_dma_count);
7705 AscWriteLramByte(iop_base,
7706 (ushort)(q_addr +
7707 (ushort)ASC_SCSIQ_B_STATUS),
7708 (uchar)(scsiq->
7709 q_status & (uchar)~(QS_READY |
7710 QS_ABORTED)));
7711 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
7712 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
7713 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
7714 sg_q_addr = q_addr;
7715 sg_list_qp = next_qp;
7716 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
7717 sg_list_qp = AscReadLramByte(iop_base,
7718 (ushort)(sg_q_addr
7719 + (ushort)
7720 ASC_SCSIQ_B_FWD));
7721 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
7722 if (sg_list_qp == ASC_QLINK_END) {
7723 AscSetLibErrorCode(asc_dvc,
7724 ASCQ_ERR_SG_Q_LINKS);
7725 scsiq->d3.done_stat = QD_WITH_ERROR;
7726 scsiq->d3.host_stat =
7727 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
7728 goto FATAL_ERR_QDONE;
7729 }
7730 AscWriteLramByte(iop_base,
7731 (ushort)(sg_q_addr + (ushort)
7732 ASC_SCSIQ_B_STATUS),
7733 QS_FREE);
7734 }
7735 n_q_used = sg_queue_cnt + 1;
7736 AscPutVarDoneQTail(iop_base, sg_list_qp);
7737 }
7738 if (asc_dvc->queue_full_or_busy & target_id) {
7739 cur_target_qng = AscReadLramByte(iop_base,
7740 (ushort)((ushort)
7741 ASC_QADR_BEG
7742 + (ushort)
7743 scsiq->d2.
7744 target_ix));
7745 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
7746 scsi_busy = AscReadLramByte(iop_base, (ushort)
7747 ASCV_SCSIBUSY_B);
7748 scsi_busy &= ~target_id;
7749 AscWriteLramByte(iop_base,
7750 (ushort)ASCV_SCSIBUSY_B,
7751 scsi_busy);
7752 asc_dvc->queue_full_or_busy &= ~target_id;
7753 }
7754 }
7755 if (asc_dvc->cur_total_qng >= n_q_used) {
7756 asc_dvc->cur_total_qng -= n_q_used;
7757 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
7758 asc_dvc->cur_dvc_qng[tid_no]--;
7759 }
7760 } else {
7761 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
7762 scsiq->d3.done_stat = QD_WITH_ERROR;
7763 goto FATAL_ERR_QDONE;
7764 }
7765 if ((scsiq->d2.srb_ptr == 0UL) ||
7766 ((scsiq->q_status & QS_ABORTED) != 0)) {
7767 return (0x11);
7768 } else if (scsiq->q_status == QS_DONE) {
7769 false_overrun = FALSE;
7770 if (scsiq->extra_bytes != 0) {
7771 scsiq->remain_bytes +=
7772 (ADV_DCNT)scsiq->extra_bytes;
7773 }
7774 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
7775 if (scsiq->d3.host_stat ==
7776 QHSTA_M_DATA_OVER_RUN) {
7777 if ((scsiq->
7778 cntl & (QC_DATA_IN | QC_DATA_OUT))
7779 == 0) {
7780 scsiq->d3.done_stat =
7781 QD_NO_ERROR;
7782 scsiq->d3.host_stat =
7783 QHSTA_NO_ERROR;
7784 } else if (false_overrun) {
7785 scsiq->d3.done_stat =
7786 QD_NO_ERROR;
7787 scsiq->d3.host_stat =
7788 QHSTA_NO_ERROR;
7789 }
7790 } else if (scsiq->d3.host_stat ==
7791 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
7792 AscStopChip(iop_base);
7793 AscSetChipControl(iop_base,
7794 (uchar)(CC_SCSI_RESET
7795 | CC_HALT));
7796 DvcDelayNanoSecond(asc_dvc, 60000);
7797 AscSetChipControl(iop_base, CC_HALT);
7798 AscSetChipStatus(iop_base,
7799 CIW_CLR_SCSI_RESET_INT);
7800 AscSetChipStatus(iop_base, 0);
7801 AscSetChipControl(iop_base, 0);
7802 }
7803 }
7804 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 7805 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
7806 } else {
7807 if ((AscReadLramByte(iop_base,
7808 (ushort)(q_addr + (ushort)
7809 ASC_SCSIQ_CDB_BEG))
7810 == START_STOP)) {
7811 asc_dvc->unit_not_ready &= ~target_id;
7812 if (scsiq->d3.done_stat != QD_NO_ERROR) {
7813 asc_dvc->start_motor &=
7814 ~target_id;
7815 }
7816 }
7817 }
7818 return (1);
7819 } else {
7820 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
7821 FATAL_ERR_QDONE:
7822 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
895d6b4c 7823 asc_isr_callback(asc_dvc, scsiq);
27c868c2
MW
7824 }
7825 return (0x80);
7826 }
7827 }
7828 return (0);
1da177e4
LT
7829}
7830
27c868c2 7831static int AscISR(ASC_DVC_VAR *asc_dvc)
1da177e4 7832{
27c868c2
MW
7833 ASC_CS_TYPE chipstat;
7834 PortAddr iop_base;
7835 ushort saved_ram_addr;
7836 uchar ctrl_reg;
7837 uchar saved_ctrl_reg;
7838 int int_pending;
7839 int status;
7840 uchar host_flag;
7841
7842 iop_base = asc_dvc->iop_base;
7843 int_pending = FALSE;
7844
7845 if (AscIsIntPending(iop_base) == 0) {
7846 return int_pending;
7847 }
1da177e4 7848
895d6b4c 7849 if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
27c868c2
MW
7850 return (ERR);
7851 }
7852 if (asc_dvc->in_critical_cnt != 0) {
7853 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
7854 return (ERR);
7855 }
7856 if (asc_dvc->is_in_int) {
7857 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
7858 return (ERR);
7859 }
7860 asc_dvc->is_in_int = TRUE;
7861 ctrl_reg = AscGetChipControl(iop_base);
7862 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
7863 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
7864 chipstat = AscGetChipStatus(iop_base);
7865 if (chipstat & CSW_SCSI_RESET_LATCH) {
7866 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
7867 int i = 10;
7868 int_pending = TRUE;
7869 asc_dvc->sdtr_done = 0;
7870 saved_ctrl_reg &= (uchar)(~CC_HALT);
7871 while ((AscGetChipStatus(iop_base) &
7872 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
7873 DvcSleepMilliSecond(100);
7874 }
7875 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
7876 AscSetChipControl(iop_base, CC_HALT);
7877 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
7878 AscSetChipStatus(iop_base, 0);
7879 chipstat = AscGetChipStatus(iop_base);
7880 }
7881 }
7882 saved_ram_addr = AscGetChipLramAddr(iop_base);
7883 host_flag = AscReadLramByte(iop_base,
7884 ASCV_HOST_FLAG_B) &
7885 (uchar)(~ASC_HOST_FLAG_IN_ISR);
7886 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
7887 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
7888 if ((chipstat & CSW_INT_PENDING)
7889 || (int_pending)
7890 ) {
7891 AscAckInterrupt(iop_base);
7892 int_pending = TRUE;
7893 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
7894 if (AscIsrChipHalted(asc_dvc) == ERR) {
7895 goto ISR_REPORT_QDONE_FATAL_ERROR;
7896 } else {
7897 saved_ctrl_reg &= (uchar)(~CC_HALT);
7898 }
7899 } else {
7900 ISR_REPORT_QDONE_FATAL_ERROR:
7901 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
7902 while (((status =
7903 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
7904 }
7905 } else {
7906 do {
7907 if ((status =
7908 AscIsrQDone(asc_dvc)) == 1) {
7909 break;
7910 }
7911 } while (status == 0x11);
7912 }
7913 if ((status & 0x80) != 0)
7914 int_pending = ERR;
7915 }
7916 }
7917 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
7918 AscSetChipLramAddr(iop_base, saved_ram_addr);
7919 AscSetChipControl(iop_base, saved_ctrl_reg);
7920 asc_dvc->is_in_int = FALSE;
7921 return (int_pending);
1da177e4
LT
7922}
7923
7924/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
7925static uchar _asc_mcode_buf[] = {
7926 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d 7927 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
27c868c2 7928 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7929 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629d688d
MW
7930 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7931 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
7932 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7933 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27c868c2 7934 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
629d688d
MW
7935 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
7936 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
7937 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
27c868c2 7938 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
629d688d
MW
7939 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
7940 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
7941 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
27c868c2 7942 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
629d688d
MW
7943 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
7944 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
7945 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
27c868c2 7946 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
629d688d
MW
7947 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
7948 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
7949 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
27c868c2 7950 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
629d688d
MW
7951 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
7952 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
7953 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
27c868c2 7954 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
629d688d
MW
7955 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
7956 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
7957 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
27c868c2 7958 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
629d688d
MW
7959 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
7960 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
7961 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
27c868c2 7962 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
629d688d
MW
7963 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
7964 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
7965 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
27c868c2 7966 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
629d688d
MW
7967 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
7968 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
7969 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
27c868c2 7970 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
629d688d
MW
7971 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
7972 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
7973 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
27c868c2 7974 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
629d688d
MW
7975 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
7976 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
7977 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
27c868c2 7978 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
629d688d
MW
7979 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
7980 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
7981 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
27c868c2 7982 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
629d688d
MW
7983 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
7984 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
7985 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
27c868c2 7986 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
629d688d
MW
7987 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
7988 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
7989 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
27c868c2 7990 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
629d688d
MW
7991 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
7992 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
7993 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
27c868c2 7994 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
629d688d
MW
7995 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
7996 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
7997 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
27c868c2 7998 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
629d688d
MW
7999 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
8000 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
8001 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
27c868c2 8002 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
629d688d
MW
8003 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
8004 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
8005 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
27c868c2 8006 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
629d688d
MW
8007 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
8008 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
8009 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
27c868c2 8010 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
629d688d
MW
8011 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
8012 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
8013 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
27c868c2 8014 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
629d688d
MW
8015 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
8016 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
8017 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
27c868c2 8018 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
629d688d
MW
8019 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
8020 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
8021 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
27c868c2 8022 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
629d688d
MW
8023 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
8024 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
8025 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
27c868c2 8026 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
629d688d
MW
8027 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
8028 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
8029 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
27c868c2 8030 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
629d688d
MW
8031 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
8032 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
8033 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
27c868c2 8034 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
629d688d
MW
8035 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
8036 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
8037 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
27c868c2 8038 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
8039 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
8040 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
8041 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
27c868c2 8042 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
629d688d
MW
8043 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
8044 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
8045 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
27c868c2 8046 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
629d688d
MW
8047 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
8048 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
8049 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
27c868c2 8050 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
629d688d
MW
8051 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
8052 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
8053 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
27c868c2 8054 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
629d688d
MW
8055 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
8056 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
8057 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
27c868c2 8058 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
629d688d
MW
8059 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
8060 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
8061 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
27c868c2 8062 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
629d688d
MW
8063 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
8064 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
8065 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
27c868c2 8066 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
629d688d
MW
8067 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
8068 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
8069 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
27c868c2 8070 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
629d688d
MW
8071 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
8072 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
8073 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
27c868c2 8074 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
629d688d
MW
8075 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
8076 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
8077 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
27c868c2 8078 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
629d688d
MW
8079 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
8080 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
8081 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
27c868c2 8082 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
629d688d
MW
8083 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
8084 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
8085 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
27c868c2 8086 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
629d688d
MW
8087 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
8088 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
8089 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
27c868c2 8090 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
629d688d
MW
8091 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
8092 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
8093 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
27c868c2 8094 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
629d688d
MW
8095 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
8096 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
8097 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
27c868c2 8098 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
629d688d
MW
8099 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
8100 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
8101 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
27c868c2 8102 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
629d688d
MW
8103 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
8104 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
8105 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
27c868c2 8106 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
629d688d
MW
8107 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
8108 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
8109 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
27c868c2 8110 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
629d688d
MW
8111 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
8112 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
8113 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
27c868c2 8114 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
629d688d
MW
8115 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
8116 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
8117 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
1da177e4
LT
8118};
8119
27c868c2
MW
8120static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
8121static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
1da177e4
LT
8122
8123#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
27c868c2
MW
8124static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
8125 INQUIRY,
8126 REQUEST_SENSE,
8127 READ_CAPACITY,
8128 READ_TOC,
8129 MODE_SELECT,
8130 MODE_SENSE,
8131 MODE_SELECT_10,
8132 MODE_SENSE_10,
8133 0xFF,
8134 0xFF,
8135 0xFF,
8136 0xFF,
8137 0xFF,
8138 0xFF,
8139 0xFF,
8140 0xFF
1da177e4
LT
8141};
8142
27c868c2 8143static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
1da177e4 8144{
27c868c2
MW
8145 PortAddr iop_base;
8146 ulong last_int_level;
8147 int sta;
8148 int n_q_required;
8149 int disable_syn_offset_one_fix;
8150 int i;
8151 ASC_PADDR addr;
27c868c2
MW
8152 ushort sg_entry_cnt = 0;
8153 ushort sg_entry_cnt_minus_one = 0;
8154 uchar target_ix;
8155 uchar tid_no;
8156 uchar sdtr_data;
8157 uchar extra_bytes;
8158 uchar scsi_cmd;
8159 uchar disable_cmd;
8160 ASC_SG_HEAD *sg_head;
8161 ASC_DCNT data_cnt;
8162
8163 iop_base = asc_dvc->iop_base;
8164 sg_head = scsiq->sg_head;
27c868c2
MW
8165 if (asc_dvc->err_code != 0)
8166 return (ERR);
8167 if (scsiq == (ASC_SCSI_Q *)0L) {
8168 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
8169 return (ERR);
8170 }
8171 scsiq->q1.q_no = 0;
8172 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
8173 scsiq->q1.extra_bytes = 0;
8174 }
8175 sta = 0;
8176 target_ix = scsiq->q2.target_ix;
8177 tid_no = ASC_TIX_TO_TID(target_ix);
8178 n_q_required = 1;
8179 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
8180 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
8181 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
8182 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8183 AscMsgOutSDTR(asc_dvc,
8184 asc_dvc->
8185 sdtr_period_tbl[(sdtr_data >> 4) &
8186 (uchar)(asc_dvc->
8187 max_sdtr_index -
8188 1)],
8189 (uchar)(sdtr_data & (uchar)
8190 ASC_SYN_MAX_OFFSET));
8191 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
8192 }
8193 }
8194 last_int_level = DvcEnterCritical();
8195 if (asc_dvc->in_critical_cnt != 0) {
8196 DvcLeaveCritical(last_int_level);
8197 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
8198 return (ERR);
8199 }
8200 asc_dvc->in_critical_cnt++;
8201 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8202 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
8203 asc_dvc->in_critical_cnt--;
8204 DvcLeaveCritical(last_int_level);
8205 return (ERR);
8206 }
1da177e4 8207#if !CC_VERY_LONG_SG_LIST
27c868c2
MW
8208 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
8209 asc_dvc->in_critical_cnt--;
8210 DvcLeaveCritical(last_int_level);
8211 return (ERR);
8212 }
1da177e4 8213#endif /* !CC_VERY_LONG_SG_LIST */
27c868c2
MW
8214 if (sg_entry_cnt == 1) {
8215 scsiq->q1.data_addr =
8216 (ADV_PADDR)sg_head->sg_list[0].addr;
8217 scsiq->q1.data_cnt =
8218 (ADV_DCNT)sg_head->sg_list[0].bytes;
8219 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
8220 }
8221 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
8222 }
8223 scsi_cmd = scsiq->cdbptr[0];
8224 disable_syn_offset_one_fix = FALSE;
8225 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
8226 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
8227 if (scsiq->q1.cntl & QC_SG_HEAD) {
8228 data_cnt = 0;
8229 for (i = 0; i < sg_entry_cnt; i++) {
8230 data_cnt +=
8231 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
8232 bytes);
8233 }
8234 } else {
8235 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
8236 }
8237 if (data_cnt != 0UL) {
8238 if (data_cnt < 512UL) {
8239 disable_syn_offset_one_fix = TRUE;
8240 } else {
8241 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
8242 i++) {
8243 disable_cmd =
8244 _syn_offset_one_disable_cmd[i];
8245 if (disable_cmd == 0xFF) {
8246 break;
8247 }
8248 if (scsi_cmd == disable_cmd) {
8249 disable_syn_offset_one_fix =
8250 TRUE;
8251 break;
8252 }
8253 }
8254 }
8255 }
8256 }
8257 if (disable_syn_offset_one_fix) {
8258 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
8259 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
8260 ASC_TAG_FLAG_DISABLE_DISCONNECT);
8261 } else {
8262 scsiq->q2.tag_code &= 0x27;
8263 }
8264 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8265 if (asc_dvc->bug_fix_cntl) {
8266 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8267 if ((scsi_cmd == READ_6) ||
8268 (scsi_cmd == READ_10)) {
8269 addr =
8270 (ADV_PADDR)le32_to_cpu(sg_head->
8271 sg_list
8272 [sg_entry_cnt_minus_one].
8273 addr) +
8274 (ADV_DCNT)le32_to_cpu(sg_head->
8275 sg_list
8276 [sg_entry_cnt_minus_one].
8277 bytes);
8278 extra_bytes =
8279 (uchar)((ushort)addr & 0x0003);
8280 if ((extra_bytes != 0)
8281 &&
8282 ((scsiq->q2.
8283 tag_code &
8284 ASC_TAG_FLAG_EXTRA_BYTES)
8285 == 0)) {
8286 scsiq->q2.tag_code |=
8287 ASC_TAG_FLAG_EXTRA_BYTES;
8288 scsiq->q1.extra_bytes =
8289 extra_bytes;
8290 data_cnt =
8291 le32_to_cpu(sg_head->
8292 sg_list
8293 [sg_entry_cnt_minus_one].
8294 bytes);
8295 data_cnt -=
8296 (ASC_DCNT) extra_bytes;
8297 sg_head->
8298 sg_list
8299 [sg_entry_cnt_minus_one].
8300 bytes =
8301 cpu_to_le32(data_cnt);
8302 }
8303 }
8304 }
8305 }
8306 sg_head->entry_to_copy = sg_head->entry_cnt;
1da177e4 8307#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8308 /*
8309 * Set the sg_entry_cnt to the maximum possible. The rest of
8310 * the SG elements will be copied when the RISC completes the
8311 * SG elements that fit and halts.
8312 */
8313 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
8314 sg_entry_cnt = ASC_MAX_SG_LIST;
8315 }
1da177e4 8316#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
8317 n_q_required = AscSgListToQueue(sg_entry_cnt);
8318 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
8319 (uint) n_q_required)
8320 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8321 if ((sta =
8322 AscSendScsiQueue(asc_dvc, scsiq,
8323 n_q_required)) == 1) {
8324 asc_dvc->in_critical_cnt--;
27c868c2
MW
8325 DvcLeaveCritical(last_int_level);
8326 return (sta);
8327 }
8328 }
8329 } else {
8330 if (asc_dvc->bug_fix_cntl) {
8331 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8332 if ((scsi_cmd == READ_6) ||
8333 (scsi_cmd == READ_10)) {
8334 addr =
8335 le32_to_cpu(scsiq->q1.data_addr) +
8336 le32_to_cpu(scsiq->q1.data_cnt);
8337 extra_bytes =
8338 (uchar)((ushort)addr & 0x0003);
8339 if ((extra_bytes != 0)
8340 &&
8341 ((scsiq->q2.
8342 tag_code &
8343 ASC_TAG_FLAG_EXTRA_BYTES)
8344 == 0)) {
8345 data_cnt =
8346 le32_to_cpu(scsiq->q1.
8347 data_cnt);
8348 if (((ushort)data_cnt & 0x01FF)
8349 == 0) {
8350 scsiq->q2.tag_code |=
8351 ASC_TAG_FLAG_EXTRA_BYTES;
8352 data_cnt -= (ASC_DCNT)
8353 extra_bytes;
8354 scsiq->q1.data_cnt =
8355 cpu_to_le32
8356 (data_cnt);
8357 scsiq->q1.extra_bytes =
8358 extra_bytes;
8359 }
8360 }
8361 }
8362 }
8363 }
8364 n_q_required = 1;
8365 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
8366 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8367 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
8368 n_q_required)) == 1) {
8369 asc_dvc->in_critical_cnt--;
27c868c2
MW
8370 DvcLeaveCritical(last_int_level);
8371 return (sta);
8372 }
8373 }
8374 }
8375 asc_dvc->in_critical_cnt--;
8376 DvcLeaveCritical(last_int_level);
8377 return (sta);
1da177e4
LT
8378}
8379
27c868c2
MW
8380static int
8381AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
1da177e4 8382{
27c868c2
MW
8383 PortAddr iop_base;
8384 uchar free_q_head;
8385 uchar next_qp;
8386 uchar tid_no;
8387 uchar target_ix;
8388 int sta;
8389
8390 iop_base = asc_dvc->iop_base;
8391 target_ix = scsiq->q2.target_ix;
8392 tid_no = ASC_TIX_TO_TID(target_ix);
8393 sta = 0;
8394 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
8395 if (n_q_required > 1) {
8396 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
8397 free_q_head, (uchar)
8398 (n_q_required)))
8399 != (uchar)ASC_QLINK_END) {
8400 asc_dvc->last_q_shortage = 0;
8401 scsiq->sg_head->queue_cnt = n_q_required - 1;
8402 scsiq->q1.q_no = free_q_head;
8403 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
8404 free_q_head)) == 1) {
8405 AscPutVarFreeQHead(iop_base, next_qp);
8406 asc_dvc->cur_total_qng += (uchar)(n_q_required);
8407 asc_dvc->cur_dvc_qng[tid_no]++;
8408 }
8409 return (sta);
8410 }
8411 } else if (n_q_required == 1) {
8412 if ((next_qp = AscAllocFreeQueue(iop_base,
8413 free_q_head)) !=
8414 ASC_QLINK_END) {
8415 scsiq->q1.q_no = free_q_head;
8416 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
8417 free_q_head)) == 1) {
8418 AscPutVarFreeQHead(iop_base, next_qp);
8419 asc_dvc->cur_total_qng++;
8420 asc_dvc->cur_dvc_qng[tid_no]++;
8421 }
8422 return (sta);
8423 }
8424 }
8425 return (sta);
1da177e4
LT
8426}
8427
27c868c2 8428static int AscSgListToQueue(int sg_list)
1da177e4 8429{
27c868c2 8430 int n_sg_list_qs;
1da177e4 8431
27c868c2
MW
8432 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
8433 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
8434 n_sg_list_qs++;
8435 return (n_sg_list_qs + 1);
1da177e4
LT
8436}
8437
27c868c2
MW
8438static uint
8439AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
1da177e4 8440{
27c868c2
MW
8441 uint cur_used_qs;
8442 uint cur_free_qs;
8443 ASC_SCSI_BIT_ID_TYPE target_id;
8444 uchar tid_no;
8445
8446 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
8447 tid_no = ASC_TIX_TO_TID(target_ix);
8448 if ((asc_dvc->unit_not_ready & target_id) ||
8449 (asc_dvc->queue_full_or_busy & target_id)) {
8450 return (0);
8451 }
8452 if (n_qs == 1) {
8453 cur_used_qs = (uint) asc_dvc->cur_total_qng +
8454 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
8455 } else {
8456 cur_used_qs = (uint) asc_dvc->cur_total_qng +
8457 (uint) ASC_MIN_FREE_Q;
8458 }
8459 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
8460 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
8461 if (asc_dvc->cur_dvc_qng[tid_no] >=
8462 asc_dvc->max_dvc_qng[tid_no]) {
8463 return (0);
8464 }
8465 return (cur_free_qs);
8466 }
8467 if (n_qs > 1) {
8468 if ((n_qs > asc_dvc->last_q_shortage)
8469 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
8470 asc_dvc->last_q_shortage = n_qs;
8471 }
8472 }
8473 return (0);
1da177e4
LT
8474}
8475
27c868c2 8476static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 8477{
27c868c2
MW
8478 ushort q_addr;
8479 uchar tid_no;
8480 uchar sdtr_data;
8481 uchar syn_period_ix;
8482 uchar syn_offset;
8483 PortAddr iop_base;
8484
8485 iop_base = asc_dvc->iop_base;
8486 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
8487 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
8488 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
8489 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8490 syn_period_ix =
8491 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
8492 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
8493 AscMsgOutSDTR(asc_dvc,
8494 asc_dvc->sdtr_period_tbl[syn_period_ix],
8495 syn_offset);
8496 scsiq->q1.cntl |= QC_MSG_OUT;
8497 }
8498 q_addr = ASC_QNO_TO_QADDR(q_no);
8499 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
8500 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
8501 }
8502 scsiq->q1.status = QS_FREE;
8503 AscMemWordCopyPtrToLram(iop_base,
8504 q_addr + ASC_SCSIQ_CDB_BEG,
8505 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
8506
8507 DvcPutScsiQ(iop_base,
8508 q_addr + ASC_SCSIQ_CPY_BEG,
8509 (uchar *)&scsiq->q1.cntl,
8510 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
8511 AscWriteLramWord(iop_base,
8512 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
8513 (ushort)(((ushort)scsiq->q1.
8514 q_no << 8) | (ushort)QS_READY));
8515 return (1);
1da177e4
LT
8516}
8517
27c868c2
MW
8518static int
8519AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
1da177e4 8520{
27c868c2
MW
8521 int sta;
8522 int i;
8523 ASC_SG_HEAD *sg_head;
8524 ASC_SG_LIST_Q scsi_sg_q;
8525 ASC_DCNT saved_data_addr;
8526 ASC_DCNT saved_data_cnt;
8527 PortAddr iop_base;
8528 ushort sg_list_dwords;
8529 ushort sg_index;
8530 ushort sg_entry_cnt;
8531 ushort q_addr;
8532 uchar next_qp;
8533
8534 iop_base = asc_dvc->iop_base;
8535 sg_head = scsiq->sg_head;
8536 saved_data_addr = scsiq->q1.data_addr;
8537 saved_data_cnt = scsiq->q1.data_cnt;
8538 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
8539 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
1da177e4 8540#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8541 /*
8542 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
8543 * then not all SG elements will fit in the allocated queues.
8544 * The rest of the SG elements will be copied when the RISC
8545 * completes the SG elements that fit and halts.
8546 */
8547 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
8548 /*
8549 * Set sg_entry_cnt to be the number of SG elements that
8550 * will fit in the allocated SG queues. It is minus 1, because
8551 * the first SG element is handled above. ASC_MAX_SG_LIST is
8552 * already inflated by 1 to account for this. For example it
8553 * may be 50 which is 1 + 7 queues * 7 SG elements.
8554 */
8555 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8556
8557 /*
8558 * Keep track of remaining number of SG elements that will
8559 * need to be handled from a_isr.c.
8560 */
8561 scsiq->remain_sg_entry_cnt =
8562 sg_head->entry_cnt - ASC_MAX_SG_LIST;
8563 } else {
1da177e4 8564#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
8565 /*
8566 * Set sg_entry_cnt to be the number of SG elements that
8567 * will fit in the allocated SG queues. It is minus 1, because
8568 * the first SG element is handled above.
8569 */
8570 sg_entry_cnt = sg_head->entry_cnt - 1;
1da177e4 8571#if CC_VERY_LONG_SG_LIST
27c868c2 8572 }
1da177e4 8573#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
8574 if (sg_entry_cnt != 0) {
8575 scsiq->q1.cntl |= QC_SG_HEAD;
8576 q_addr = ASC_QNO_TO_QADDR(q_no);
8577 sg_index = 1;
8578 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
8579 scsi_sg_q.sg_head_qp = q_no;
8580 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8581 for (i = 0; i < sg_head->queue_cnt; i++) {
8582 scsi_sg_q.seq_no = i + 1;
8583 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8584 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8585 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8586 if (i == 0) {
8587 scsi_sg_q.sg_list_cnt =
8588 ASC_SG_LIST_PER_Q;
8589 scsi_sg_q.sg_cur_list_cnt =
8590 ASC_SG_LIST_PER_Q;
8591 } else {
8592 scsi_sg_q.sg_list_cnt =
8593 ASC_SG_LIST_PER_Q - 1;
8594 scsi_sg_q.sg_cur_list_cnt =
8595 ASC_SG_LIST_PER_Q - 1;
8596 }
8597 } else {
1da177e4 8598#if CC_VERY_LONG_SG_LIST
27c868c2
MW
8599 /*
8600 * This is the last SG queue in the list of
8601 * allocated SG queues. If there are more
8602 * SG elements than will fit in the allocated
8603 * queues, then set the QCSG_SG_XFER_MORE flag.
8604 */
8605 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
8606 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8607 } else {
1da177e4 8608#endif /* CC_VERY_LONG_SG_LIST */
27c868c2 8609 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
1da177e4 8610#if CC_VERY_LONG_SG_LIST
27c868c2 8611 }
1da177e4 8612#endif /* CC_VERY_LONG_SG_LIST */
27c868c2
MW
8613 sg_list_dwords = sg_entry_cnt << 1;
8614 if (i == 0) {
8615 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
8616 scsi_sg_q.sg_cur_list_cnt =
8617 sg_entry_cnt;
8618 } else {
8619 scsi_sg_q.sg_list_cnt =
8620 sg_entry_cnt - 1;
8621 scsi_sg_q.sg_cur_list_cnt =
8622 sg_entry_cnt - 1;
8623 }
8624 sg_entry_cnt = 0;
8625 }
8626 next_qp = AscReadLramByte(iop_base,
8627 (ushort)(q_addr +
8628 ASC_SCSIQ_B_FWD));
8629 scsi_sg_q.q_no = next_qp;
8630 q_addr = ASC_QNO_TO_QADDR(next_qp);
8631 AscMemWordCopyPtrToLram(iop_base,
8632 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8633 (uchar *)&scsi_sg_q,
8634 sizeof(ASC_SG_LIST_Q) >> 1);
8635 AscMemDWordCopyPtrToLram(iop_base,
8636 q_addr + ASC_SGQ_LIST_BEG,
8637 (uchar *)&sg_head->
8638 sg_list[sg_index],
8639 sg_list_dwords);
8640 sg_index += ASC_SG_LIST_PER_Q;
8641 scsiq->next_sg_index = sg_index;
8642 }
8643 } else {
8644 scsiq->q1.cntl &= ~QC_SG_HEAD;
8645 }
8646 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
8647 scsiq->q1.data_addr = saved_data_addr;
8648 scsiq->q1.data_cnt = saved_data_cnt;
8649 return (sta);
1da177e4
LT
8650}
8651
27c868c2
MW
8652static int
8653AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
1da177e4 8654{
27c868c2 8655 int sta = FALSE;
1da177e4 8656
27c868c2
MW
8657 if (AscHostReqRiscHalt(iop_base)) {
8658 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8659 AscStartChip(iop_base);
8660 return (sta);
8661 }
8662 return (sta);
1da177e4
LT
8663}
8664
27c868c2 8665static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
1da177e4 8666{
27c868c2
MW
8667 ASC_SCSI_BIT_ID_TYPE org_id;
8668 int i;
8669 int sta = TRUE;
8670
8671 AscSetBank(iop_base, 1);
8672 org_id = AscReadChipDvcID(iop_base);
8673 for (i = 0; i <= ASC_MAX_TID; i++) {
8674 if (org_id == (0x01 << i))
8675 break;
8676 }
8677 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8678 AscWriteChipDvcID(iop_base, id);
8679 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8680 AscSetBank(iop_base, 0);
8681 AscSetChipSyn(iop_base, sdtr_data);
8682 if (AscGetChipSyn(iop_base) != sdtr_data) {
8683 sta = FALSE;
8684 }
8685 } else {
8686 sta = FALSE;
8687 }
8688 AscSetBank(iop_base, 1);
8689 AscWriteChipDvcID(iop_base, org_id);
8690 AscSetBank(iop_base, 0);
8691 return (sta);
8692}
1da177e4 8693
27c868c2 8694static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
1da177e4 8695{
27c868c2
MW
8696 uchar i;
8697 ushort s_addr;
8698 PortAddr iop_base;
8699 ushort warn_code;
8700
8701 iop_base = asc_dvc->iop_base;
8702 warn_code = 0;
8703 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
8704 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
8705 64) >> 1)
8706 );
8707 i = ASC_MIN_ACTIVE_QNO;
8708 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
8709 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8710 (uchar)(i + 1));
8711 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8712 (uchar)(asc_dvc->max_total_qng));
8713 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8714 (uchar)i);
8715 i++;
8716 s_addr += ASC_QBLK_SIZE;
8717 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
8718 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8719 (uchar)(i + 1));
8720 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8721 (uchar)(i - 1));
8722 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8723 (uchar)i);
8724 }
8725 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8726 (uchar)ASC_QLINK_END);
8727 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8728 (uchar)(asc_dvc->max_total_qng - 1));
8729 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8730 (uchar)asc_dvc->max_total_qng);
8731 i++;
8732 s_addr += ASC_QBLK_SIZE;
8733 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
8734 i++, s_addr += ASC_QBLK_SIZE) {
8735 AscWriteLramByte(iop_base,
8736 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
8737 AscWriteLramByte(iop_base,
8738 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
8739 AscWriteLramByte(iop_base,
8740 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
8741 }
8742 return (warn_code);
1da177e4
LT
8743}
8744
27c868c2 8745static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
1da177e4 8746{
27c868c2
MW
8747 PortAddr iop_base;
8748 int i;
8749 ushort lram_addr;
8750
8751 iop_base = asc_dvc->iop_base;
8752 AscPutRiscVarFreeQHead(iop_base, 1);
8753 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
8754 AscPutVarFreeQHead(iop_base, 1);
8755 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
8756 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
8757 (uchar)((int)asc_dvc->max_total_qng + 1));
8758 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
8759 (uchar)((int)asc_dvc->max_total_qng + 2));
8760 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
8761 asc_dvc->max_total_qng);
8762 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
8763 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8764 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
8765 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
8766 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
8767 AscPutQDoneInProgress(iop_base, 0);
8768 lram_addr = ASC_QADR_BEG;
8769 for (i = 0; i < 32; i++, lram_addr += 2) {
8770 AscWriteLramWord(iop_base, lram_addr, 0);
8771 }
8772 return (0);
1da177e4
LT
8773}
8774
27c868c2 8775static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
1da177e4 8776{
27c868c2
MW
8777 if (asc_dvc->err_code == 0) {
8778 asc_dvc->err_code = err_code;
8779 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8780 err_code);
8781 }
8782 return (err_code);
1da177e4
LT
8783}
8784
27c868c2
MW
8785static uchar
8786AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
1da177e4 8787{
27c868c2
MW
8788 EXT_MSG sdtr_buf;
8789 uchar sdtr_period_index;
8790 PortAddr iop_base;
8791
8792 iop_base = asc_dvc->iop_base;
47d853cc 8793 sdtr_buf.msg_type = EXTENDED_MESSAGE;
27c868c2 8794 sdtr_buf.msg_len = MS_SDTR_LEN;
47d853cc 8795 sdtr_buf.msg_req = EXTENDED_SDTR;
27c868c2
MW
8796 sdtr_buf.xfer_period = sdtr_period;
8797 sdtr_offset &= ASC_SYN_MAX_OFFSET;
8798 sdtr_buf.req_ack_offset = sdtr_offset;
8799 if ((sdtr_period_index =
8800 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
8801 asc_dvc->max_sdtr_index) {
8802 AscMemWordCopyPtrToLram(iop_base,
8803 ASCV_MSGOUT_BEG,
8804 (uchar *)&sdtr_buf,
8805 sizeof(EXT_MSG) >> 1);
8806 return ((sdtr_period_index << 4) | sdtr_offset);
8807 } else {
8808
8809 sdtr_buf.req_ack_offset = 0;
8810 AscMemWordCopyPtrToLram(iop_base,
8811 ASCV_MSGOUT_BEG,
8812 (uchar *)&sdtr_buf,
8813 sizeof(EXT_MSG) >> 1);
8814 return (0);
8815 }
1da177e4
LT
8816}
8817
27c868c2
MW
8818static uchar
8819AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
1da177e4 8820{
27c868c2
MW
8821 uchar byte;
8822 uchar sdtr_period_ix;
8823
8824 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8825 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
8826 ) {
8827 return (0xFF);
8828 }
8829 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8830 return (byte);
1da177e4
LT
8831}
8832
27c868c2 8833static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
1da177e4 8834{
27c868c2
MW
8835 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8836 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8837 return;
1da177e4
LT
8838}
8839
27c868c2 8840static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
1da177e4 8841{
27c868c2
MW
8842 uchar *period_table;
8843 int max_index;
8844 int min_index;
8845 int i;
8846
8847 period_table = asc_dvc->sdtr_period_tbl;
8848 max_index = (int)asc_dvc->max_sdtr_index;
8849 min_index = (int)asc_dvc->host_init_sdtr_index;
8850 if ((syn_time <= period_table[max_index])) {
8851 for (i = min_index; i < (max_index - 1); i++) {
8852 if (syn_time <= period_table[i]) {
8853 return ((uchar)i);
8854 }
8855 }
8856 return ((uchar)max_index);
8857 } else {
8858 return ((uchar)(max_index + 1));
8859 }
1da177e4
LT
8860}
8861
27c868c2 8862static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
1da177e4 8863{
27c868c2
MW
8864 ushort q_addr;
8865 uchar next_qp;
8866 uchar q_status;
8867
8868 q_addr = ASC_QNO_TO_QADDR(free_q_head);
8869 q_status = (uchar)AscReadLramByte(iop_base,
8870 (ushort)(q_addr +
8871 ASC_SCSIQ_B_STATUS));
8872 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
8873 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
8874 return (next_qp);
8875 }
8876 return (ASC_QLINK_END);
1da177e4
LT
8877}
8878
27c868c2
MW
8879static uchar
8880AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
1da177e4 8881{
27c868c2 8882 uchar i;
1da177e4 8883
27c868c2
MW
8884 for (i = 0; i < n_free_q; i++) {
8885 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
8886 == ASC_QLINK_END) {
8887 return (ASC_QLINK_END);
8888 }
8889 }
8890 return (free_q_head);
1da177e4
LT
8891}
8892
27c868c2 8893static int AscHostReqRiscHalt(PortAddr iop_base)
1da177e4 8894{
27c868c2
MW
8895 int count = 0;
8896 int sta = 0;
8897 uchar saved_stop_code;
8898
8899 if (AscIsChipHalted(iop_base))
8900 return (1);
8901 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
8902 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8903 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
8904 do {
8905 if (AscIsChipHalted(iop_base)) {
8906 sta = 1;
8907 break;
8908 }
8909 DvcSleepMilliSecond(100);
8910 } while (count++ < 20);
8911 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
8912 return (sta);
1da177e4
LT
8913}
8914
27c868c2 8915static int AscStopQueueExe(PortAddr iop_base)
1da177e4 8916{
27c868c2
MW
8917 int count = 0;
8918
8919 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
8920 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
8921 ASC_STOP_REQ_RISC_STOP);
8922 do {
8923 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
8924 ASC_STOP_ACK_RISC_STOP) {
8925 return (1);
8926 }
8927 DvcSleepMilliSecond(100);
8928 } while (count++ < 20);
8929 }
8930 return (0);
1da177e4
LT
8931}
8932
27c868c2 8933static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
1da177e4 8934{
27c868c2 8935 udelay(micro_sec);
1da177e4
LT
8936}
8937
27c868c2 8938static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
1da177e4 8939{
27c868c2 8940 udelay((nano_sec + 999) / 1000);
1da177e4
LT
8941}
8942
27c868c2 8943static int AscStartChip(PortAddr iop_base)
1da177e4 8944{
27c868c2
MW
8945 AscSetChipControl(iop_base, 0);
8946 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8947 return (0);
8948 }
8949 return (1);
1da177e4
LT
8950}
8951
27c868c2 8952static int AscStopChip(PortAddr iop_base)
1da177e4 8953{
27c868c2
MW
8954 uchar cc_val;
8955
8956 cc_val =
8957 AscGetChipControl(iop_base) &
8958 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
8959 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
8960 AscSetChipIH(iop_base, INS_HALT);
8961 AscSetChipIH(iop_base, INS_RFLAG_WTM);
8962 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
8963 return (0);
8964 }
8965 return (1);
1da177e4
LT
8966}
8967
27c868c2 8968static int AscIsChipHalted(PortAddr iop_base)
1da177e4 8969{
27c868c2
MW
8970 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
8971 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
8972 return (1);
8973 }
8974 }
8975 return (0);
1da177e4
LT
8976}
8977
27c868c2 8978static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
1da177e4 8979{
27c868c2
MW
8980 AscSetBank(iop_base, 1);
8981 AscWriteChipIH(iop_base, ins_code);
8982 AscSetBank(iop_base, 0);
8983 return;
1da177e4
LT
8984}
8985
27c868c2 8986static void AscAckInterrupt(PortAddr iop_base)
1da177e4 8987{
27c868c2
MW
8988 uchar host_flag;
8989 uchar risc_flag;
8990 ushort loop;
8991
8992 loop = 0;
8993 do {
8994 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8995 if (loop++ > 0x7FFF) {
8996 break;
8997 }
8998 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8999 host_flag =
9000 AscReadLramByte(iop_base,
9001 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
9002 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9003 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
9004 AscSetChipStatus(iop_base, CIW_INT_ACK);
9005 loop = 0;
9006 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
9007 AscSetChipStatus(iop_base, CIW_INT_ACK);
9008 if (loop++ > 3) {
9009 break;
9010 }
9011 }
9012 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9013 return;
1da177e4
LT
9014}
9015
27c868c2 9016static void AscDisableInterrupt(PortAddr iop_base)
1da177e4 9017{
27c868c2 9018 ushort cfg;
1da177e4 9019
27c868c2
MW
9020 cfg = AscGetChipCfgLsw(iop_base);
9021 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
9022 return;
1da177e4
LT
9023}
9024
27c868c2 9025static void AscEnableInterrupt(PortAddr iop_base)
1da177e4 9026{
27c868c2 9027 ushort cfg;
1da177e4 9028
27c868c2
MW
9029 cfg = AscGetChipCfgLsw(iop_base);
9030 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
9031 return;
1da177e4
LT
9032}
9033
27c868c2 9034static void AscSetBank(PortAddr iop_base, uchar bank)
1da177e4 9035{
27c868c2
MW
9036 uchar val;
9037
9038 val = AscGetChipControl(iop_base) &
9039 (~
9040 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
9041 CC_CHIP_RESET));
9042 if (bank == 1) {
9043 val |= CC_BANK_ONE;
9044 } else if (bank == 2) {
9045 val |= CC_DIAG | CC_BANK_ONE;
9046 } else {
9047 val &= ~CC_BANK_ONE;
9048 }
9049 AscSetChipControl(iop_base, val);
9050 return;
1da177e4
LT
9051}
9052
27c868c2 9053static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
1da177e4 9054{
27c868c2
MW
9055 PortAddr iop_base;
9056 int i = 10;
1da177e4 9057
27c868c2
MW
9058 iop_base = asc_dvc->iop_base;
9059 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
9060 && (i-- > 0)) {
9061 DvcSleepMilliSecond(100);
9062 }
9063 AscStopChip(iop_base);
9064 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
9065 DvcDelayNanoSecond(asc_dvc, 60000);
9066 AscSetChipIH(iop_base, INS_RFLAG_WTM);
9067 AscSetChipIH(iop_base, INS_HALT);
9068 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
9069 AscSetChipControl(iop_base, CC_HALT);
9070 DvcSleepMilliSecond(200);
9071 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9072 AscSetChipStatus(iop_base, 0);
9073 return (AscIsChipHalted(iop_base));
1da177e4
LT
9074}
9075
78e77d8b 9076static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
1da177e4 9077{
27c868c2
MW
9078 if (bus_type & ASC_IS_ISA)
9079 return (ASC_MAX_ISA_DMA_COUNT);
9080 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
9081 return (ASC_MAX_VL_DMA_COUNT);
9082 return (ASC_MAX_PCI_DMA_COUNT);
1da177e4
LT
9083}
9084
9085#ifdef CONFIG_ISA
78e77d8b 9086static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
1da177e4 9087{
27c868c2
MW
9088 ushort channel;
9089
9090 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
9091 if (channel == 0x03)
9092 return (0);
9093 else if (channel == 0x00)
9094 return (7);
9095 return (channel + 4);
1da177e4
LT
9096}
9097
78e77d8b 9098static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
1da177e4 9099{
27c868c2
MW
9100 ushort cfg_lsw;
9101 uchar value;
9102
9103 if ((dma_channel >= 5) && (dma_channel <= 7)) {
9104 if (dma_channel == 7)
9105 value = 0x00;
9106 else
9107 value = dma_channel - 4;
9108 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
9109 cfg_lsw |= value;
9110 AscSetChipCfgLsw(iop_base, cfg_lsw);
9111 return (AscGetIsaDmaChannel(iop_base));
9112 }
9113 return (0);
1da177e4
LT
9114}
9115
78e77d8b 9116static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
1da177e4 9117{
27c868c2
MW
9118 speed_value &= 0x07;
9119 AscSetBank(iop_base, 1);
9120 AscWriteChipDmaSpeed(iop_base, speed_value);
9121 AscSetBank(iop_base, 0);
9122 return (AscGetIsaDmaSpeed(iop_base));
1da177e4
LT
9123}
9124
78e77d8b 9125static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
1da177e4 9126{
27c868c2 9127 uchar speed_value;
1da177e4 9128
27c868c2
MW
9129 AscSetBank(iop_base, 1);
9130 speed_value = AscReadChipDmaSpeed(iop_base);
9131 speed_value &= 0x07;
9132 AscSetBank(iop_base, 0);
9133 return (speed_value);
1da177e4
LT
9134}
9135#endif /* CONFIG_ISA */
9136
c2dce2fa 9137static int __devinit AscInitGetConfig(asc_board_t *boardp)
1da177e4 9138{
c2dce2fa 9139 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9649af39 9140 unsigned short warn_code = 0;
27c868c2 9141
27c868c2 9142 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9649af39 9143 if (asc_dvc->err_code != 0)
c2dce2fa 9144 return asc_dvc->err_code;
27c868c2 9145
9649af39 9146 if (AscFindSignature(asc_dvc->iop_base)) {
27c868c2
MW
9147 warn_code |= AscInitAscDvcVar(asc_dvc);
9148 warn_code |= AscInitFromEEP(asc_dvc);
9149 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
ecec1947 9150 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
27c868c2 9151 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
27c868c2
MW
9152 } else {
9153 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9154 }
c2dce2fa
MW
9155
9156 switch (warn_code) {
9157 case 0: /* No error */
9158 break;
9159 case ASC_WARN_IO_PORT_ROTATE:
9160 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
9161 "modified\n", boardp->id);
9162 break;
9163 case ASC_WARN_AUTO_CONFIG:
9164 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
9165 "switch enabled\n", boardp->id);
9166 break;
9167 case ASC_WARN_EEPROM_CHKSUM:
9168 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
9169 "error\n", boardp->id);
9170 break;
9171 case ASC_WARN_IRQ_MODIFIED:
9172 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
9173 boardp->id);
9174 break;
9175 case ASC_WARN_CMD_QNG_CONFLICT:
9176 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
9177 "w/o disconnects\n", boardp->id);
9178 break;
9179 default:
9180 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
9181 "0x%x\n", boardp->id, warn_code);
9182 break;
9183 }
9184
9185 if (asc_dvc->err_code != 0) {
9186 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
9187 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
9188 asc_dvc->err_code);
9189 }
9190
9191 return asc_dvc->err_code;
1da177e4
LT
9192}
9193
c2dce2fa 9194static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 9195{
c2dce2fa 9196 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
394dbf3f
MW
9197 PortAddr iop_base = asc_dvc->iop_base;
9198 unsigned short cfg_msw;
9199 unsigned short warn_code = 0;
27c868c2
MW
9200
9201 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
9202 if (asc_dvc->err_code != 0)
c2dce2fa 9203 return asc_dvc->err_code;
394dbf3f 9204 if (!AscFindSignature(asc_dvc->iop_base)) {
27c868c2 9205 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
c2dce2fa 9206 return asc_dvc->err_code;
27c868c2 9207 }
1da177e4 9208
27c868c2
MW
9209 cfg_msw = AscGetChipCfgMsw(iop_base);
9210 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 9211 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
9212 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9213 AscSetChipCfgMsw(iop_base, cfg_msw);
9214 }
9215 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
9216 asc_dvc->cfg->cmd_qng_enabled) {
9217 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
9218 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9219 }
9220 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9221 warn_code |= ASC_WARN_AUTO_CONFIG;
9222 }
9223 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
9224 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
9225 != asc_dvc->irq_no) {
9226 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
9227 }
9228 }
9649af39 9229#ifdef CONFIG_PCI
27c868c2
MW
9230 if (asc_dvc->bus_type & ASC_IS_PCI) {
9231 cfg_msw &= 0xFFC0;
9232 AscSetChipCfgMsw(iop_base, cfg_msw);
9233 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
9234 } else {
9649af39
MW
9235 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
9236 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
27c868c2
MW
9237 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
9238 asc_dvc->bug_fix_cntl |=
9239 ASC_BUG_FIX_ASYN_USE_SYN;
9240 }
9241 }
9649af39
MW
9242 } else
9243#endif /* CONFIG_PCI */
9244 if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
27c868c2
MW
9245 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
9246 == ASC_CHIP_VER_ASYN_BUG) {
9247 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
9248 }
9249 }
9250 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
9251 asc_dvc->cfg->chip_scsi_id) {
9252 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
9253 }
1da177e4 9254#ifdef CONFIG_ISA
27c868c2
MW
9255 if (asc_dvc->bus_type & ASC_IS_ISA) {
9256 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
9257 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
9258 }
1da177e4 9259#endif /* CONFIG_ISA */
394dbf3f
MW
9260
9261 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
c2dce2fa
MW
9262
9263 switch (warn_code) {
9264 case 0: /* No error. */
9265 break;
9266 case ASC_WARN_IO_PORT_ROTATE:
9267 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
9268 "modified\n", boardp->id);
9269 break;
9270 case ASC_WARN_AUTO_CONFIG:
9271 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
9272 "switch enabled\n", boardp->id);
9273 break;
9274 case ASC_WARN_EEPROM_CHKSUM:
9275 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
9276 "error\n", boardp->id);
9277 break;
9278 case ASC_WARN_IRQ_MODIFIED:
9279 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
9280 boardp->id);
9281 break;
9282 case ASC_WARN_CMD_QNG_CONFLICT:
9283 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
9284 "disconnects\n",
9285 boardp->id);
9286 break;
9287 default:
9288 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
9289 "0x%x\n", boardp->id, warn_code);
9290 break;
9291 }
9292
9293 if (asc_dvc->err_code != 0) {
9294 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
9295 "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
9296 asc_dvc->err_code);
9297 }
9298
9299 return asc_dvc->err_code;
1da177e4
LT
9300}
9301
27c868c2 9302static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
1da177e4 9303{
27c868c2
MW
9304 ushort warn_code;
9305 PortAddr iop_base;
9306
9307 iop_base = asc_dvc->iop_base;
9308 warn_code = 0;
9309 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
9310 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
9311 AscResetChipAndScsiBus(asc_dvc);
9312 DvcSleepMilliSecond((ASC_DCNT)
9313 ((ushort)asc_dvc->scsi_reset_wait * 1000));
9314 }
9315 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
9316 if (asc_dvc->err_code != 0)
9317 return (UW_ERR);
9318 if (!AscFindSignature(asc_dvc->iop_base)) {
9319 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9320 return (warn_code);
9321 }
9322 AscDisableInterrupt(iop_base);
9323 warn_code |= AscInitLram(asc_dvc);
9324 if (asc_dvc->err_code != 0)
9325 return (UW_ERR);
9326 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
9327 (ulong)_asc_mcode_chksum);
9328 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
9329 _asc_mcode_size) != _asc_mcode_chksum) {
9330 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
9331 return (warn_code);
9332 }
9333 warn_code |= AscInitMicroCodeVar(asc_dvc);
9334 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
9335 AscEnableInterrupt(iop_base);
9336 return (warn_code);
1da177e4
LT
9337}
9338
78e77d8b 9339static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
1da177e4 9340{
27c868c2
MW
9341 int i;
9342 PortAddr iop_base;
9343 ushort warn_code;
9344 uchar chip_version;
9345
9346 iop_base = asc_dvc->iop_base;
9347 warn_code = 0;
9348 asc_dvc->err_code = 0;
9349 if ((asc_dvc->bus_type &
9350 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
9351 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
9352 }
9353 AscSetChipControl(iop_base, CC_HALT);
9354 AscSetChipStatus(iop_base, 0);
9355 asc_dvc->bug_fix_cntl = 0;
9356 asc_dvc->pci_fix_asyn_xfer = 0;
9357 asc_dvc->pci_fix_asyn_xfer_always = 0;
9358 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
9359 asc_dvc->sdtr_done = 0;
9360 asc_dvc->cur_total_qng = 0;
9361 asc_dvc->is_in_int = 0;
9362 asc_dvc->in_critical_cnt = 0;
9363 asc_dvc->last_q_shortage = 0;
9364 asc_dvc->use_tagged_qng = 0;
9365 asc_dvc->no_scam = 0;
9366 asc_dvc->unit_not_ready = 0;
9367 asc_dvc->queue_full_or_busy = 0;
9368 asc_dvc->redo_scam = 0;
9369 asc_dvc->res2 = 0;
9370 asc_dvc->host_init_sdtr_index = 0;
9371 asc_dvc->cfg->can_tagged_qng = 0;
9372 asc_dvc->cfg->cmd_qng_enabled = 0;
9373 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
9374 asc_dvc->init_sdtr = 0;
9375 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
9376 asc_dvc->scsi_reset_wait = 3;
9377 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
9378 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
9379 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
9380 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
9381 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
9382 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
9383 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
9384 ASC_LIB_VERSION_MINOR;
9385 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
9386 asc_dvc->cfg->chip_version = chip_version;
9387 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
9388 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
9389 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
9390 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
9391 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
9392 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
9393 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
9394 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
9395 asc_dvc->max_sdtr_index = 7;
9396 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
9397 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
9398 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
9399 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
9400 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
9401 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
9402 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
9403 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
9404 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
9405 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
9406 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
9407 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
9408 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
9409 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
9410 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
9411 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
9412 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
9413 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
9414 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
9415 asc_dvc->max_sdtr_index = 15;
9416 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
9417 AscSetExtraControl(iop_base,
9418 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
9419 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
9420 AscSetExtraControl(iop_base,
9421 (SEC_ACTIVE_NEGATE |
9422 SEC_ENABLE_FILTER));
9423 }
9424 }
9425 if (asc_dvc->bus_type == ASC_IS_PCI) {
9426 AscSetExtraControl(iop_base,
9427 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
9428 }
1da177e4 9429
27c868c2 9430 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
1da177e4 9431#ifdef CONFIG_ISA
27c868c2 9432 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
59fcf844
MW
9433 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
9434 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
9435 asc_dvc->bus_type = ASC_IS_ISAPNP;
9436 }
27c868c2
MW
9437 asc_dvc->cfg->isa_dma_channel =
9438 (uchar)AscGetIsaDmaChannel(iop_base);
9439 }
1da177e4 9440#endif /* CONFIG_ISA */
27c868c2
MW
9441 for (i = 0; i <= ASC_MAX_TID; i++) {
9442 asc_dvc->cur_dvc_qng[i] = 0;
9443 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
9444 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
9445 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
9446 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
9447 }
9448 return (warn_code);
1da177e4
LT
9449}
9450
78e77d8b 9451static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
1da177e4 9452{
27c868c2
MW
9453 ASCEEP_CONFIG eep_config_buf;
9454 ASCEEP_CONFIG *eep_config;
9455 PortAddr iop_base;
9456 ushort chksum;
9457 ushort warn_code;
9458 ushort cfg_msw, cfg_lsw;
9459 int i;
9460 int write_eep = 0;
9461
9462 iop_base = asc_dvc->iop_base;
9463 warn_code = 0;
9464 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
9465 AscStopQueueExe(iop_base);
9466 if ((AscStopChip(iop_base) == FALSE) ||
9467 (AscGetChipScsiCtrl(iop_base) != 0)) {
9468 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
9469 AscResetChipAndScsiBus(asc_dvc);
9470 DvcSleepMilliSecond((ASC_DCNT)
9471 ((ushort)asc_dvc->scsi_reset_wait * 1000));
9472 }
9473 if (AscIsChipHalted(iop_base) == FALSE) {
9474 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
9475 return (warn_code);
9476 }
9477 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
9478 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
9479 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
9480 return (warn_code);
9481 }
9482 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
9483 cfg_msw = AscGetChipCfgMsw(iop_base);
9484 cfg_lsw = AscGetChipCfgLsw(iop_base);
9485 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
c2dce2fa 9486 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
27c868c2
MW
9487 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9488 AscSetChipCfgMsw(iop_base, cfg_msw);
9489 }
9490 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
9491 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
9492 if (chksum == 0) {
9493 chksum = 0xaa55;
9494 }
9495 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9496 warn_code |= ASC_WARN_AUTO_CONFIG;
9497 if (asc_dvc->cfg->chip_version == 3) {
9498 if (eep_config->cfg_lsw != cfg_lsw) {
9499 warn_code |= ASC_WARN_EEPROM_RECOVER;
9500 eep_config->cfg_lsw =
9501 AscGetChipCfgLsw(iop_base);
9502 }
9503 if (eep_config->cfg_msw != cfg_msw) {
9504 warn_code |= ASC_WARN_EEPROM_RECOVER;
9505 eep_config->cfg_msw =
9506 AscGetChipCfgMsw(iop_base);
9507 }
9508 }
9509 }
9510 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9511 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
9512 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
9513 eep_config->chksum);
9514 if (chksum != eep_config->chksum) {
9515 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
9516 ASC_CHIP_VER_PCI_ULTRA_3050) {
9517 ASC_DBG(1,
9518 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
9519 eep_config->init_sdtr = 0xFF;
9520 eep_config->disc_enable = 0xFF;
9521 eep_config->start_motor = 0xFF;
9522 eep_config->use_cmd_qng = 0;
9523 eep_config->max_total_qng = 0xF0;
9524 eep_config->max_tag_qng = 0x20;
9525 eep_config->cntl = 0xBFFF;
9526 ASC_EEP_SET_CHIP_ID(eep_config, 7);
9527 eep_config->no_scam = 0;
9528 eep_config->adapter_info[0] = 0;
9529 eep_config->adapter_info[1] = 0;
9530 eep_config->adapter_info[2] = 0;
9531 eep_config->adapter_info[3] = 0;
9532 eep_config->adapter_info[4] = 0;
9533 /* Indicate EEPROM-less board. */
9534 eep_config->adapter_info[5] = 0xBB;
9535 } else {
9536 ASC_PRINT
9537 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
9538 write_eep = 1;
9539 warn_code |= ASC_WARN_EEPROM_CHKSUM;
9540 }
9541 }
9542 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
9543 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
9544 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
9545 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
9546 asc_dvc->start_motor = eep_config->start_motor;
9547 asc_dvc->dvc_cntl = eep_config->cntl;
9548 asc_dvc->no_scam = eep_config->no_scam;
9549 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
9550 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
9551 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
9552 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
9553 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
9554 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
9555 if (!AscTestExternalLram(asc_dvc)) {
9556 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
9557 ASC_IS_PCI_ULTRA)) {
9558 eep_config->max_total_qng =
9559 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
9560 eep_config->max_tag_qng =
9561 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
9562 } else {
9563 eep_config->cfg_msw |= 0x0800;
9564 cfg_msw |= 0x0800;
9565 AscSetChipCfgMsw(iop_base, cfg_msw);
9566 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
9567 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
9568 }
9569 } else {
9570 }
9571 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
9572 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
9573 }
9574 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
9575 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
9576 }
9577 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
9578 eep_config->max_tag_qng = eep_config->max_total_qng;
9579 }
9580 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
9581 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
9582 }
9583 asc_dvc->max_total_qng = eep_config->max_total_qng;
9584 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
9585 eep_config->use_cmd_qng) {
9586 eep_config->disc_enable = eep_config->use_cmd_qng;
9587 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9588 }
9589 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
9590 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
9591 }
9592 ASC_EEP_SET_CHIP_ID(eep_config,
9593 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
9594 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
9595 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
9596 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
9597 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
9598 }
1da177e4 9599
27c868c2
MW
9600 for (i = 0; i <= ASC_MAX_TID; i++) {
9601 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
9602 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
9603 asc_dvc->cfg->sdtr_period_offset[i] =
9604 (uchar)(ASC_DEF_SDTR_OFFSET |
9605 (asc_dvc->host_init_sdtr_index << 4));
9606 }
9607 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
9608 if (write_eep) {
9609 if ((i =
9610 AscSetEEPConfig(iop_base, eep_config,
9611 asc_dvc->bus_type)) != 0) {
9612 ASC_PRINT1
9613 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
9614 i);
9615 } else {
9616 ASC_PRINT
9617 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
9618 }
9619 }
9620 return (warn_code);
1da177e4
LT
9621}
9622
27c868c2 9623static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
1da177e4 9624{
27c868c2
MW
9625 int i;
9626 ushort warn_code;
9627 PortAddr iop_base;
9628 ASC_PADDR phy_addr;
9629 ASC_DCNT phy_size;
9630
9631 iop_base = asc_dvc->iop_base;
9632 warn_code = 0;
9633 for (i = 0; i <= ASC_MAX_TID; i++) {
9634 AscPutMCodeInitSDTRAtID(iop_base, i,
9635 asc_dvc->cfg->sdtr_period_offset[i]
9636 );
9637 }
1da177e4 9638
27c868c2
MW
9639 AscInitQLinkVar(asc_dvc);
9640 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
9641 asc_dvc->cfg->disc_enable);
9642 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
9643 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
9644
9645 /* Align overrun buffer on an 8 byte boundary. */
9646 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
9647 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
9648 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
9649 (uchar *)&phy_addr, 1);
9650 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
9651 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
9652 (uchar *)&phy_size, 1);
9653
9654 asc_dvc->cfg->mcode_date =
9655 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
9656 asc_dvc->cfg->mcode_version =
9657 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
9658
9659 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
9660 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
9661 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
9662 return (warn_code);
9663 }
9664 if (AscStartChip(iop_base) != 1) {
9665 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
9666 return (warn_code);
9667 }
1da177e4 9668
27c868c2 9669 return (warn_code);
1da177e4
LT
9670}
9671
78e77d8b 9672static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
1da177e4 9673{
27c868c2
MW
9674 PortAddr iop_base;
9675 ushort q_addr;
9676 ushort saved_word;
9677 int sta;
9678
9679 iop_base = asc_dvc->iop_base;
9680 sta = 0;
9681 q_addr = ASC_QNO_TO_QADDR(241);
9682 saved_word = AscReadLramWord(iop_base, q_addr);
9683 AscSetChipLramAddr(iop_base, q_addr);
9684 AscSetChipLramData(iop_base, 0x55AA);
9685 DvcSleepMilliSecond(10);
9686 AscSetChipLramAddr(iop_base, q_addr);
9687 if (AscGetChipLramData(iop_base) == 0x55AA) {
9688 sta = 1;
9689 AscWriteLramWord(iop_base, q_addr, saved_word);
9690 }
9691 return (sta);
1da177e4
LT
9692}
9693
78e77d8b 9694static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
1da177e4 9695{
27c868c2
MW
9696 uchar read_back;
9697 int retry;
9698
9699 retry = 0;
9700 while (TRUE) {
9701 AscSetChipEEPCmd(iop_base, cmd_reg);
9702 DvcSleepMilliSecond(1);
9703 read_back = AscGetChipEEPCmd(iop_base);
9704 if (read_back == cmd_reg) {
9705 return (1);
9706 }
9707 if (retry++ > ASC_EEP_MAX_RETRY) {
9708 return (0);
9709 }
9710 }
1da177e4
LT
9711}
9712
78e77d8b 9713static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
1da177e4 9714{
27c868c2
MW
9715 ushort read_back;
9716 int retry;
9717
9718 retry = 0;
9719 while (TRUE) {
9720 AscSetChipEEPData(iop_base, data_reg);
9721 DvcSleepMilliSecond(1);
9722 read_back = AscGetChipEEPData(iop_base);
9723 if (read_back == data_reg) {
9724 return (1);
9725 }
9726 if (retry++ > ASC_EEP_MAX_RETRY) {
9727 return (0);
9728 }
9729 }
1da177e4
LT
9730}
9731
78e77d8b 9732static void __devinit AscWaitEEPRead(void)
1da177e4 9733{
27c868c2
MW
9734 DvcSleepMilliSecond(1);
9735 return;
1da177e4
LT
9736}
9737
78e77d8b 9738static void __devinit AscWaitEEPWrite(void)
1da177e4 9739{
27c868c2
MW
9740 DvcSleepMilliSecond(20);
9741 return;
1da177e4
LT
9742}
9743
78e77d8b 9744static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
1da177e4 9745{
27c868c2
MW
9746 ushort read_wval;
9747 uchar cmd_reg;
9748
9749 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9750 AscWaitEEPRead();
9751 cmd_reg = addr | ASC_EEP_CMD_READ;
9752 AscWriteEEPCmdReg(iop_base, cmd_reg);
9753 AscWaitEEPRead();
9754 read_wval = AscGetChipEEPData(iop_base);
9755 AscWaitEEPRead();
9756 return (read_wval);
1da177e4
LT
9757}
9758
78e77d8b 9759static ushort __devinit
27c868c2 9760AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
1da177e4 9761{
27c868c2
MW
9762 ushort read_wval;
9763
9764 read_wval = AscReadEEPWord(iop_base, addr);
9765 if (read_wval != word_val) {
9766 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
9767 AscWaitEEPRead();
9768 AscWriteEEPDataReg(iop_base, word_val);
9769 AscWaitEEPRead();
9770 AscWriteEEPCmdReg(iop_base,
9771 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
9772 AscWaitEEPWrite();
9773 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9774 AscWaitEEPRead();
9775 return (AscReadEEPWord(iop_base, addr));
9776 }
9777 return (read_wval);
1da177e4
LT
9778}
9779
78e77d8b 9780static ushort __devinit
27c868c2 9781AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9782{
27c868c2
MW
9783 ushort wval;
9784 ushort sum;
9785 ushort *wbuf;
9786 int cfg_beg;
9787 int cfg_end;
9788 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
9789 int s_addr;
9790
9791 wbuf = (ushort *)cfg_buf;
9792 sum = 0;
9793 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
9794 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9795 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
9796 sum += *wbuf;
9797 }
9798 if (bus_type & ASC_IS_VL) {
9799 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9800 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9801 } else {
9802 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9803 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9804 }
9805 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9806 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
9807 if (s_addr <= uchar_end_in_config) {
9808 /*
9809 * Swap all char fields - must unswap bytes already swapped
9810 * by AscReadEEPWord().
9811 */
9812 *wbuf = le16_to_cpu(wval);
9813 } else {
9814 /* Don't swap word field at the end - cntl field. */
9815 *wbuf = wval;
9816 }
9817 sum += wval; /* Checksum treats all EEPROM data as words. */
9818 }
9819 /*
9820 * Read the checksum word which will be compared against 'sum'
9821 * by the caller. Word field already swapped.
9822 */
9823 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
9824 return (sum);
1da177e4
LT
9825}
9826
78e77d8b 9827static int __devinit
27c868c2 9828AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9829{
27c868c2
MW
9830 int n_error;
9831 ushort *wbuf;
9832 ushort word;
9833 ushort sum;
9834 int s_addr;
9835 int cfg_beg;
9836 int cfg_end;
9837 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
9838
9839 wbuf = (ushort *)cfg_buf;
9840 n_error = 0;
9841 sum = 0;
9842 /* Write two config words; AscWriteEEPWord() will swap bytes. */
9843 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9844 sum += *wbuf;
9845 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9846 n_error++;
9847 }
9848 }
9849 if (bus_type & ASC_IS_VL) {
9850 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9851 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9852 } else {
9853 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9854 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9855 }
9856 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9857 if (s_addr <= uchar_end_in_config) {
9858 /*
9859 * This is a char field. Swap char fields before they are
9860 * swapped again by AscWriteEEPWord().
9861 */
9862 word = cpu_to_le16(*wbuf);
9863 if (word !=
9864 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
9865 n_error++;
9866 }
9867 } else {
9868 /* Don't swap word field at the end - cntl field. */
9869 if (*wbuf !=
9870 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
9871 n_error++;
9872 }
9873 }
9874 sum += *wbuf; /* Checksum calculated from word values. */
9875 }
9876 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
9877 *wbuf = sum;
9878 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
9879 n_error++;
9880 }
1da177e4 9881
27c868c2
MW
9882 /* Read EEPROM back again. */
9883 wbuf = (ushort *)cfg_buf;
9884 /*
9885 * Read two config words; Byte-swapping done by AscReadEEPWord().
9886 */
9887 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
9888 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
9889 n_error++;
9890 }
9891 }
9892 if (bus_type & ASC_IS_VL) {
9893 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
9894 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
9895 } else {
9896 cfg_beg = ASC_EEP_DVC_CFG_BEG;
9897 cfg_end = ASC_EEP_MAX_DVC_ADDR;
9898 }
9899 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
9900 if (s_addr <= uchar_end_in_config) {
9901 /*
9902 * Swap all char fields. Must unswap bytes already swapped
9903 * by AscReadEEPWord().
9904 */
9905 word =
9906 le16_to_cpu(AscReadEEPWord
9907 (iop_base, (uchar)s_addr));
9908 } else {
9909 /* Don't swap word field at the end - cntl field. */
9910 word = AscReadEEPWord(iop_base, (uchar)s_addr);
9911 }
9912 if (*wbuf != word) {
9913 n_error++;
9914 }
9915 }
9916 /* Read checksum; Byte swapping not needed. */
9917 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
9918 n_error++;
9919 }
9920 return (n_error);
1da177e4
LT
9921}
9922
78e77d8b 9923static int __devinit
27c868c2 9924AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
1da177e4 9925{
27c868c2
MW
9926 int retry;
9927 int n_error;
9928
9929 retry = 0;
9930 while (TRUE) {
9931 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
9932 bus_type)) == 0) {
9933 break;
9934 }
9935 if (++retry > ASC_EEP_MAX_RETRY) {
9936 break;
9937 }
9938 }
9939 return (n_error);
1da177e4
LT
9940}
9941
47d853cc 9942static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
1da177e4 9943{
47d853cc
MW
9944 char type = sdev->type;
9945 ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
27c868c2
MW
9946
9947 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
9948 if (!(asc_dvc->init_sdtr & tid_bits)) {
47d853cc
MW
9949 if ((type == TYPE_ROM) &&
9950 (strncmp(sdev->vendor, "HP ", 3) == 0)) {
27c868c2
MW
9951 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9952 }
9953 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
47d853cc
MW
9954 if ((type == TYPE_PROCESSOR) ||
9955 (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
9956 (type == TYPE_TAPE)) {
27c868c2
MW
9957 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9958 }
9959
9960 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
9961 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
47d853cc
MW
9962 sdev->id,
9963 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
27c868c2
MW
9964 }
9965 }
9966 }
1da177e4
LT
9967}
9968
27c868c2 9969static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
1da177e4 9970{
27c868c2
MW
9971 uchar byte_data;
9972 ushort word_data;
9973
9974 if (isodd_word(addr)) {
9975 AscSetChipLramAddr(iop_base, addr - 1);
9976 word_data = AscGetChipLramData(iop_base);
9977 byte_data = (uchar)((word_data >> 8) & 0xFF);
9978 } else {
9979 AscSetChipLramAddr(iop_base, addr);
9980 word_data = AscGetChipLramData(iop_base);
9981 byte_data = (uchar)(word_data & 0xFF);
9982 }
9983 return (byte_data);
1da177e4 9984}
27c868c2
MW
9985
9986static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
1da177e4 9987{
27c868c2 9988 ushort word_data;
1da177e4 9989
27c868c2
MW
9990 AscSetChipLramAddr(iop_base, addr);
9991 word_data = AscGetChipLramData(iop_base);
9992 return (word_data);
1da177e4
LT
9993}
9994
9995#if CC_VERY_LONG_SG_LIST
27c868c2 9996static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
1da177e4 9997{
27c868c2
MW
9998 ushort val_low, val_high;
9999 ASC_DCNT dword_data;
10000
10001 AscSetChipLramAddr(iop_base, addr);
10002 val_low = AscGetChipLramData(iop_base);
10003 val_high = AscGetChipLramData(iop_base);
10004 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
10005 return (dword_data);
1da177e4
LT
10006}
10007#endif /* CC_VERY_LONG_SG_LIST */
10008
27c868c2 10009static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
1da177e4 10010{
27c868c2
MW
10011 AscSetChipLramAddr(iop_base, addr);
10012 AscSetChipLramData(iop_base, word_val);
10013 return;
1da177e4
LT
10014}
10015
27c868c2 10016static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
1da177e4 10017{
27c868c2
MW
10018 ushort word_data;
10019
10020 if (isodd_word(addr)) {
10021 addr--;
10022 word_data = AscReadLramWord(iop_base, addr);
10023 word_data &= 0x00FF;
10024 word_data |= (((ushort)byte_val << 8) & 0xFF00);
10025 } else {
10026 word_data = AscReadLramWord(iop_base, addr);
10027 word_data &= 0xFF00;
10028 word_data |= ((ushort)byte_val & 0x00FF);
10029 }
10030 AscWriteLramWord(iop_base, addr, word_data);
10031 return;
1da177e4
LT
10032}
10033
10034/*
10035 * Copy 2 bytes to LRAM.
10036 *
10037 * The source data is assumed to be in little-endian order in memory
10038 * and is maintained in little-endian order when written to LRAM.
10039 */
27c868c2
MW
10040static void
10041AscMemWordCopyPtrToLram(PortAddr iop_base,
10042 ushort s_addr, uchar *s_buffer, int words)
1da177e4 10043{
27c868c2
MW
10044 int i;
10045
10046 AscSetChipLramAddr(iop_base, s_addr);
10047 for (i = 0; i < 2 * words; i += 2) {
10048 /*
10049 * On a little-endian system the second argument below
10050 * produces a little-endian ushort which is written to
10051 * LRAM in little-endian order. On a big-endian system
10052 * the second argument produces a big-endian ushort which
10053 * is "transparently" byte-swapped by outpw() and written
10054 * in little-endian order to LRAM.
10055 */
10056 outpw(iop_base + IOP_RAM_DATA,
10057 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
10058 }
10059 return;
1da177e4
LT
10060}
10061
10062/*
10063 * Copy 4 bytes to LRAM.
10064 *
10065 * The source data is assumed to be in little-endian order in memory
10066 * and is maintained in little-endian order when writen to LRAM.
10067 */
27c868c2
MW
10068static void
10069AscMemDWordCopyPtrToLram(PortAddr iop_base,
10070 ushort s_addr, uchar *s_buffer, int dwords)
1da177e4 10071{
27c868c2
MW
10072 int i;
10073
10074 AscSetChipLramAddr(iop_base, s_addr);
10075 for (i = 0; i < 4 * dwords; i += 4) {
10076 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
10077 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
10078 }
10079 return;
1da177e4
LT
10080}
10081
10082/*
10083 * Copy 2 bytes from LRAM.
10084 *
10085 * The source data is assumed to be in little-endian order in LRAM
10086 * and is maintained in little-endian order when written to memory.
10087 */
27c868c2
MW
10088static void
10089AscMemWordCopyPtrFromLram(PortAddr iop_base,
10090 ushort s_addr, uchar *d_buffer, int words)
1da177e4 10091{
27c868c2
MW
10092 int i;
10093 ushort word;
10094
10095 AscSetChipLramAddr(iop_base, s_addr);
10096 for (i = 0; i < 2 * words; i += 2) {
10097 word = inpw(iop_base + IOP_RAM_DATA);
10098 d_buffer[i] = word & 0xff;
10099 d_buffer[i + 1] = (word >> 8) & 0xff;
10100 }
10101 return;
1da177e4
LT
10102}
10103
27c868c2 10104static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
1da177e4 10105{
27c868c2
MW
10106 ASC_DCNT sum;
10107 int i;
1da177e4 10108
27c868c2
MW
10109 sum = 0L;
10110 for (i = 0; i < words; i++, s_addr += 2) {
10111 sum += AscReadLramWord(iop_base, s_addr);
10112 }
10113 return (sum);
1da177e4
LT
10114}
10115
27c868c2
MW
10116static void
10117AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
1da177e4 10118{
27c868c2 10119 int i;
1da177e4 10120
27c868c2
MW
10121 AscSetChipLramAddr(iop_base, s_addr);
10122 for (i = 0; i < words; i++) {
10123 AscSetChipLramData(iop_base, set_wval);
10124 }
10125 return;
1da177e4
LT
10126}
10127
1da177e4
LT
10128/*
10129 * --- Adv Library Functions
10130 */
10131
10132/* a_mcode.h */
10133
10134/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
10135static unsigned char _adv_asc3550_buf[] = {
10136 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
629d688d
MW
10137 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
10138 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
10139 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
27c868c2 10140 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
629d688d
MW
10141 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
10142 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
10143 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
27c868c2 10144 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
629d688d
MW
10145 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
10146 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
10147 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
27c868c2 10148 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
629d688d
MW
10149 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
10150 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
10151 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
27c868c2 10152 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
629d688d
MW
10153 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
10154 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
10155 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
27c868c2 10156 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
629d688d
MW
10157 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
10158 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
10159 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
27c868c2 10160 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
629d688d
MW
10161 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
10162 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
10163 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
27c868c2 10164 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
629d688d
MW
10165 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
10166 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
10167 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
27c868c2 10168 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
629d688d
MW
10169 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
10170 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
10171 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
27c868c2 10172 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
629d688d
MW
10173 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
10174 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
10175 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
27c868c2 10176 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
629d688d
MW
10177 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
10178 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
10179 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
27c868c2 10180 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
10181 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
10182 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
10183 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
27c868c2 10184 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
10185 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
10186 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
10187 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
27c868c2 10188 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
629d688d
MW
10189 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
10190 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
10191 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
27c868c2 10192 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
629d688d
MW
10193 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
10194 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
10195 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
27c868c2 10196 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
629d688d
MW
10197 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
10198 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
10199 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
27c868c2 10200 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
10201 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
10202 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
10203 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
27c868c2 10204 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
629d688d
MW
10205 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
10206 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
10207 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
27c868c2 10208 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
629d688d
MW
10209 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
10210 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
10211 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
27c868c2 10212 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
629d688d
MW
10213 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
10214 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
10215 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
27c868c2 10216 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
629d688d
MW
10217 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
10218 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
10219 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
27c868c2 10220 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
629d688d
MW
10221 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
10222 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
10223 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
27c868c2 10224 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
629d688d
MW
10225 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
10226 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
10227 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
27c868c2 10228 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
629d688d
MW
10229 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
10230 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
10231 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
27c868c2 10232 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
629d688d
MW
10233 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
10234 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
10235 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
27c868c2 10236 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
629d688d
MW
10237 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
10238 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
10239 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
27c868c2 10240 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
629d688d
MW
10241 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
10242 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
10243 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
27c868c2 10244 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
629d688d
MW
10245 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
10246 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
10247 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
27c868c2 10248 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
629d688d
MW
10249 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
10250 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
10251 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
27c868c2 10252 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
629d688d
MW
10253 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
10254 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
10255 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
27c868c2 10256 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
629d688d
MW
10257 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
10258 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
10259 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
27c868c2 10260 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
629d688d
MW
10261 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
10262 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
10263 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
27c868c2 10264 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
629d688d
MW
10265 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
10266 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
10267 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
27c868c2 10268 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
629d688d
MW
10269 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
10270 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
10271 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
27c868c2 10272 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
629d688d
MW
10273 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
10274 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
10275 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
27c868c2 10276 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
629d688d
MW
10277 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
10278 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
10279 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
27c868c2 10280 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
629d688d
MW
10281 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
10282 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
10283 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
27c868c2 10284 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
629d688d
MW
10285 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
10286 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
10287 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
27c868c2 10288 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
629d688d
MW
10289 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
10290 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
10291 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
27c868c2 10292 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
629d688d
MW
10293 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
10294 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
10295 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
27c868c2 10296 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
629d688d
MW
10297 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
10298 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
10299 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
27c868c2 10300 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
629d688d
MW
10301 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
10302 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
10303 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
27c868c2 10304 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
629d688d
MW
10305 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
10306 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
10307 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
27c868c2 10308 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
629d688d
MW
10309 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
10310 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
10311 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
27c868c2 10312 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
629d688d
MW
10313 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
10314 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
10315 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
27c868c2 10316 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
629d688d
MW
10317 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
10318 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
10319 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
27c868c2 10320 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
629d688d
MW
10321 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
10322 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
10323 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
27c868c2 10324 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
629d688d
MW
10325 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
10326 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
10327 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
27c868c2 10328 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
629d688d
MW
10329 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
10330 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
10331 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
27c868c2 10332 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
629d688d
MW
10333 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
10334 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
10335 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
27c868c2 10336 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
629d688d
MW
10337 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
10338 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
10339 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
27c868c2 10340 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
629d688d
MW
10341 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
10342 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
10343 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
27c868c2 10344 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
629d688d
MW
10345 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
10346 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
10347 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
27c868c2 10348 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
629d688d
MW
10349 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
10350 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
10351 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
27c868c2 10352 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
629d688d
MW
10353 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
10354 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
10355 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
27c868c2 10356 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
629d688d
MW
10357 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
10358 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
10359 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
27c868c2 10360 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
629d688d
MW
10361 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
10362 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
10363 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
27c868c2 10364 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
629d688d
MW
10365 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
10366 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
10367 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
27c868c2 10368 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
629d688d
MW
10369 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
10370 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
10371 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
27c868c2 10372 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
629d688d
MW
10373 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
10374 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
10375 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
27c868c2 10376 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
629d688d
MW
10377 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
10378 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
10379 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
27c868c2 10380 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
629d688d
MW
10381 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
10382 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
10383 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
27c868c2 10384 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
629d688d
MW
10385 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
10386 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
10387 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
27c868c2 10388 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
629d688d
MW
10389 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
10390 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
10391 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
27c868c2 10392 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
629d688d
MW
10393 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
10394 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
10395 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
27c868c2 10396 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
629d688d
MW
10397 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
10398 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
10399 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
27c868c2 10400 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
629d688d
MW
10401 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
10402 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
10403 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
27c868c2 10404 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
629d688d
MW
10405 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
10406 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
10407 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
27c868c2 10408 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
629d688d
MW
10409 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
10410 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
10411 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
27c868c2 10412 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
629d688d
MW
10413 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
10414 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
10415 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
27c868c2 10416 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
629d688d
MW
10417 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
10418 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
10419 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
27c868c2 10420 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
629d688d
MW
10421 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
10422 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
10423 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
27c868c2 10424 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
629d688d
MW
10425 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
10426 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
10427 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
27c868c2 10428 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
629d688d
MW
10429 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
10430 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
10431 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
27c868c2 10432 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
629d688d
MW
10433 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
10434 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
10435 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
27c868c2 10436 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
629d688d
MW
10437 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
10438 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
10439 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
27c868c2 10440 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
629d688d
MW
10441 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
10442 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
10443 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
27c868c2 10444 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
629d688d
MW
10445 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
10446 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
10447 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
27c868c2 10448 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
629d688d
MW
10449 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
10450 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
10451 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
27c868c2 10452 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
629d688d
MW
10453 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
10454 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
10455 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
27c868c2 10456 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
629d688d
MW
10457 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
10458 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
10459 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
27c868c2 10460 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
629d688d
MW
10461 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
10462 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
10463 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
27c868c2 10464 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
629d688d
MW
10465 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
10466 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
10467 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
27c868c2 10468 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
629d688d
MW
10469 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
10470 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
10471 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
27c868c2 10472 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
629d688d
MW
10473 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
10474 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
10475 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
27c868c2 10476 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
629d688d
MW
10477 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
10478 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
10479 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
27c868c2 10480 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
629d688d
MW
10481 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
10482 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
10483 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
27c868c2 10484 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
629d688d
MW
10485 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
10486 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
10487 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
27c868c2 10488 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
629d688d
MW
10489 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
10490 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
10491 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
27c868c2 10492 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
629d688d
MW
10493 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
10494 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
10495 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
27c868c2 10496 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
629d688d
MW
10497 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
10498 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
10499 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
27c868c2 10500 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
629d688d
MW
10501 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
10502 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
10503 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
27c868c2 10504 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
629d688d
MW
10505 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
10506 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
10507 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
27c868c2 10508 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
629d688d
MW
10509 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
10510 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
10511 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
27c868c2 10512 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
629d688d
MW
10513 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
10514 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
10515 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
27c868c2 10516 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
629d688d
MW
10517 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
10518 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
10519 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
27c868c2 10520 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
629d688d
MW
10521 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
10522 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
10523 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
27c868c2 10524 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
629d688d
MW
10525 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
10526 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
10527 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
27c868c2 10528 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
629d688d
MW
10529 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
10530 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
10531 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
27c868c2 10532 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
629d688d
MW
10533 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
10534 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
10535 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
27c868c2 10536 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
629d688d
MW
10537 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
10538 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
10539 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
27c868c2 10540 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
629d688d
MW
10541 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
10542 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
10543 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
27c868c2 10544 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
629d688d
MW
10545 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
10546 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
10547 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
27c868c2 10548 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
629d688d
MW
10549 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
10550 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
10551 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
27c868c2 10552 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
629d688d
MW
10553 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
10554 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
1da177e4
LT
10555};
10556
27c868c2
MW
10557static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
10558static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
1da177e4
LT
10559
10560/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
10561static unsigned char _adv_asc38C0800_buf[] = {
10562 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
629d688d
MW
10563 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
10564 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
10565 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
27c868c2 10566 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
629d688d
MW
10567 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
10568 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
10569 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
27c868c2 10570 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
629d688d
MW
10571 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
10572 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
10573 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
27c868c2 10574 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
629d688d
MW
10575 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
10576 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
10577 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
27c868c2 10578 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
629d688d
MW
10579 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
10580 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
10581 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
27c868c2 10582 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
629d688d
MW
10583 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
10584 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
10585 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
27c868c2 10586 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
629d688d
MW
10587 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
10588 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
10589 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
27c868c2 10590 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
629d688d
MW
10591 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
10592 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
10593 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
27c868c2 10594 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
629d688d
MW
10595 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
10596 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
10597 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
27c868c2 10598 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
629d688d
MW
10599 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
10600 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
10601 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
27c868c2 10602 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
629d688d
MW
10603 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
10604 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
10605 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
27c868c2 10606 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
10607 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
10608 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
10609 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
27c868c2 10610 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
10611 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
10612 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
10613 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
27c868c2 10614 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
629d688d
MW
10615 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
10616 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
10617 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
27c868c2 10618 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
629d688d
MW
10619 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
10620 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
10621 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
27c868c2 10622 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
629d688d
MW
10623 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
10624 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
10625 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
27c868c2 10626 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
629d688d
MW
10627 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
10628 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
10629 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
27c868c2 10630 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
629d688d
MW
10631 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
10632 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
10633 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
27c868c2 10634 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
629d688d
MW
10635 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
10636 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
10637 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
27c868c2 10638 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
629d688d
MW
10639 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
10640 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
10641 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
27c868c2 10642 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
629d688d
MW
10643 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
10644 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
10645 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
27c868c2 10646 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
629d688d
MW
10647 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
10648 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
10649 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
27c868c2 10650 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
629d688d
MW
10651 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
10652 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
10653 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
27c868c2 10654 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
629d688d
MW
10655 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
10656 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
10657 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
27c868c2 10658 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
629d688d
MW
10659 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
10660 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
10661 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
27c868c2 10662 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
629d688d
MW
10663 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
10664 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
10665 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
27c868c2 10666 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
629d688d
MW
10667 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
10668 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
10669 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
27c868c2 10670 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
629d688d
MW
10671 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
10672 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
10673 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
27c868c2 10674 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
629d688d
MW
10675 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
10676 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
10677 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
27c868c2 10678 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
629d688d
MW
10679 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
10680 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
10681 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
27c868c2 10682 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
629d688d
MW
10683 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
10684 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
10685 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
27c868c2 10686 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
629d688d
MW
10687 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
10688 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
10689 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
27c868c2 10690 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
629d688d
MW
10691 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
10692 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
10693 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
27c868c2 10694 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
629d688d
MW
10695 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
10696 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
10697 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
27c868c2 10698 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
629d688d
MW
10699 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
10700 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
10701 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
27c868c2 10702 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
629d688d
MW
10703 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
10704 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
10705 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
27c868c2 10706 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
629d688d
MW
10707 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
10708 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
10709 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
27c868c2 10710 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
629d688d
MW
10711 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
10712 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
10713 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
27c868c2 10714 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
629d688d
MW
10715 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
10716 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
10717 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
27c868c2 10718 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
629d688d
MW
10719 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
10720 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
10721 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
27c868c2 10722 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
629d688d
MW
10723 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
10724 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
10725 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
27c868c2 10726 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
629d688d
MW
10727 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
10728 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
10729 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
27c868c2 10730 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
629d688d
MW
10731 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
10732 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
10733 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
27c868c2 10734 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
629d688d
MW
10735 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
10736 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
10737 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
27c868c2 10738 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
629d688d
MW
10739 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
10740 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
10741 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
27c868c2 10742 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
629d688d
MW
10743 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
10744 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
10745 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
27c868c2 10746 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
629d688d
MW
10747 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
10748 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
10749 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
27c868c2 10750 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
629d688d
MW
10751 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
10752 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
10753 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
27c868c2 10754 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
629d688d
MW
10755 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
10756 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
10757 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
27c868c2 10758 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
629d688d
MW
10759 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
10760 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
10761 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
27c868c2 10762 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
629d688d
MW
10763 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
10764 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
10765 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
27c868c2 10766 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
629d688d
MW
10767 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
10768 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
10769 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
27c868c2 10770 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
629d688d
MW
10771 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
10772 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
10773 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
27c868c2 10774 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
629d688d
MW
10775 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
10776 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
10777 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
27c868c2 10778 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
629d688d
MW
10779 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
10780 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
10781 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
27c868c2 10782 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
629d688d
MW
10783 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
10784 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
10785 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
27c868c2 10786 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
629d688d
MW
10787 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
10788 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
10789 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
27c868c2 10790 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
629d688d
MW
10791 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
10792 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
10793 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
27c868c2 10794 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
629d688d
MW
10795 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
10796 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
10797 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
27c868c2 10798 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
629d688d
MW
10799 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
10800 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
10801 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
27c868c2 10802 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
629d688d
MW
10803 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
10804 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
10805 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
27c868c2 10806 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
629d688d
MW
10807 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
10808 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
10809 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
27c868c2 10810 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
629d688d
MW
10811 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
10812 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
10813 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
27c868c2 10814 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
629d688d
MW
10815 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
10816 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
10817 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
27c868c2 10818 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
629d688d
MW
10819 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
10820 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
10821 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
27c868c2 10822 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
629d688d
MW
10823 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
10824 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
10825 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
27c868c2 10826 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
629d688d
MW
10827 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
10828 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
10829 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
27c868c2 10830 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
629d688d
MW
10831 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
10832 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
10833 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
27c868c2 10834 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
629d688d
MW
10835 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
10836 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
10837 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
27c868c2 10838 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
629d688d
MW
10839 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
10840 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
10841 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
27c868c2 10842 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
629d688d
MW
10843 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
10844 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
10845 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
27c868c2 10846 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
629d688d
MW
10847 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
10848 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
10849 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
27c868c2 10850 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
629d688d
MW
10851 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
10852 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
10853 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
27c868c2 10854 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
629d688d
MW
10855 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
10856 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
10857 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
27c868c2 10858 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
629d688d
MW
10859 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
10860 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
10861 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
27c868c2 10862 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
629d688d
MW
10863 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
10864 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
10865 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
27c868c2 10866 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
629d688d
MW
10867 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
10868 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
10869 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
27c868c2 10870 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
629d688d
MW
10871 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
10872 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
10873 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
27c868c2 10874 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
629d688d
MW
10875 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
10876 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
10877 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
27c868c2 10878 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
629d688d
MW
10879 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
10880 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
10881 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
27c868c2 10882 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
629d688d
MW
10883 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
10884 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
10885 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
27c868c2 10886 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
629d688d
MW
10887 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
10888 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
10889 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
27c868c2 10890 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
629d688d
MW
10891 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
10892 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
10893 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
27c868c2 10894 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
629d688d
MW
10895 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
10896 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
10897 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
27c868c2 10898 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
629d688d
MW
10899 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
10900 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
10901 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
27c868c2 10902 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
629d688d
MW
10903 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
10904 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
10905 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
27c868c2 10906 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
629d688d
MW
10907 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
10908 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10909 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
27c868c2 10910 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
629d688d
MW
10911 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
10912 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
10913 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
27c868c2 10914 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
629d688d
MW
10915 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
10916 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
10917 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
27c868c2 10918 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
629d688d
MW
10919 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
10920 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
10921 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
27c868c2 10922 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
629d688d
MW
10923 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
10924 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
10925 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
27c868c2 10926 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
629d688d
MW
10927 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
10928 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
10929 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
27c868c2 10930 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
629d688d
MW
10931 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
10932 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
10933 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
27c868c2 10934 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
629d688d
MW
10935 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
10936 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
10937 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
27c868c2 10938 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
629d688d
MW
10939 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
10940 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
10941 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
27c868c2 10942 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
629d688d
MW
10943 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
10944 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
10945 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
27c868c2 10946 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
629d688d
MW
10947 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
10948 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
10949 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
27c868c2 10950 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
629d688d
MW
10951 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
10952 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
10953 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
27c868c2 10954 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
629d688d
MW
10955 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
10956 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
10957 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
27c868c2 10958 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
629d688d
MW
10959 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
10960 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
10961 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
27c868c2 10962 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
629d688d
MW
10963 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
10964 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
10965 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
27c868c2 10966 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
629d688d
MW
10967 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
10968 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
10969 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
27c868c2 10970 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
629d688d
MW
10971 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
10972 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
10973 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
27c868c2 10974 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
629d688d
MW
10975 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
10976 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
10977 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
27c868c2 10978 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
629d688d
MW
10979 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
10980 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
10981 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
27c868c2 10982 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
629d688d
MW
10983 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
10984 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
10985 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
27c868c2 10986 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
629d688d
MW
10987 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
10988 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
10989 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
27c868c2 10990 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
629d688d
MW
10991 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
10992 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
10993 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
27c868c2 10994 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
629d688d
MW
10995 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
10996 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
10997 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
27c868c2 10998 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
629d688d
MW
10999 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
11000 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
11001 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
27c868c2 11002 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
629d688d
MW
11003 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
11004 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
11005 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
27c868c2 11006 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
1da177e4
LT
11007};
11008
27c868c2
MW
11009static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
11010static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
1da177e4
LT
11011
11012/* Microcode buffer is kept after initialization for error recovery. */
27c868c2
MW
11013static unsigned char _adv_asc38C1600_buf[] = {
11014 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
629d688d
MW
11015 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
11016 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
11017 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
27c868c2 11018 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
629d688d
MW
11019 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
11020 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
11021 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
27c868c2 11022 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
629d688d
MW
11023 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
11024 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
11025 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
27c868c2 11026 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
629d688d
MW
11027 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
11028 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
11029 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
27c868c2 11030 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
629d688d
MW
11031 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11032 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
11033 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
27c868c2 11034 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
629d688d
MW
11035 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
11036 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
11037 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
27c868c2 11038 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
629d688d
MW
11039 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
11040 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
11041 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
27c868c2 11042 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
629d688d
MW
11043 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
11044 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
11045 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
27c868c2 11046 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
629d688d
MW
11047 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
11048 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
11049 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
27c868c2 11050 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
629d688d
MW
11051 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
11052 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
11053 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
27c868c2 11054 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
629d688d
MW
11055 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
11056 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
11057 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
27c868c2 11058 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
629d688d
MW
11059 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
11060 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
11061 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
27c868c2 11062 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
629d688d
MW
11063 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
11064 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
11065 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
27c868c2 11066 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
629d688d
MW
11067 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
11068 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
11069 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
27c868c2 11070 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
629d688d
MW
11071 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
11072 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
11073 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
27c868c2 11074 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
629d688d
MW
11075 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
11076 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
11077 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
27c868c2 11078 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
629d688d
MW
11079 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
11080 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
11081 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
27c868c2 11082 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
629d688d
MW
11083 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
11084 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
11085 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
27c868c2 11086 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
629d688d
MW
11087 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11088 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
11089 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
27c868c2 11090 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
629d688d
MW
11091 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
11092 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
11093 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
27c868c2 11094 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
629d688d
MW
11095 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
11096 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
11097 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
27c868c2 11098 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
629d688d
MW
11099 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
11100 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
11101 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
27c868c2 11102 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
629d688d
MW
11103 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
11104 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
11105 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
27c868c2 11106 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
629d688d
MW
11107 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
11108 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
11109 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
27c868c2 11110 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
629d688d
MW
11111 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
11112 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
11113 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
27c868c2 11114 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
629d688d
MW
11115 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
11116 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
11117 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
27c868c2 11118 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
629d688d
MW
11119 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
11120 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
11121 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
27c868c2 11122 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
629d688d
MW
11123 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
11124 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
11125 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
27c868c2 11126 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
629d688d
MW
11127 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
11128 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
11129 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
27c868c2 11130 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
629d688d
MW
11131 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
11132 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
11133 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
27c868c2 11134 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
629d688d
MW
11135 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
11136 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
11137 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
27c868c2 11138 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
629d688d
MW
11139 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
11140 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
11141 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
27c868c2 11142 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
629d688d
MW
11143 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
11144 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
11145 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
27c868c2 11146 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
629d688d
MW
11147 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
11148 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
11149 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
27c868c2 11150 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
629d688d
MW
11151 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
11152 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
11153 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
27c868c2 11154 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
629d688d
MW
11155 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
11156 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
11157 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
27c868c2 11158 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
629d688d
MW
11159 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
11160 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
11161 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
27c868c2 11162 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
629d688d
MW
11163 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
11164 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
11165 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
27c868c2 11166 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
629d688d
MW
11167 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
11168 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
11169 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
27c868c2 11170 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
629d688d
MW
11171 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
11172 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
11173 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
27c868c2 11174 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
629d688d
MW
11175 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
11176 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
11177 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
27c868c2 11178 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
629d688d
MW
11179 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
11180 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
11181 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 11182 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
629d688d
MW
11183 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
11184 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
11185 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
27c868c2 11186 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
629d688d
MW
11187 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
11188 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
11189 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
27c868c2 11190 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
629d688d
MW
11191 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
11192 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
11193 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
27c868c2 11194 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
629d688d
MW
11195 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
11196 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
11197 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
27c868c2 11198 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
629d688d
MW
11199 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
11200 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
11201 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
27c868c2 11202 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
629d688d
MW
11203 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
11204 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
11205 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
27c868c2 11206 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
629d688d
MW
11207 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
11208 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
11209 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
27c868c2 11210 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
629d688d
MW
11211 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
11212 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
11213 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
27c868c2 11214 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
629d688d
MW
11215 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
11216 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
11217 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
27c868c2 11218 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
629d688d
MW
11219 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
11220 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
11221 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
27c868c2 11222 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
629d688d
MW
11223 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
11224 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
11225 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
27c868c2 11226 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
629d688d
MW
11227 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
11228 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
11229 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
27c868c2 11230 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
629d688d
MW
11231 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
11232 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
11233 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
27c868c2 11234 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
629d688d
MW
11235 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
11236 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
11237 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
27c868c2 11238 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
629d688d
MW
11239 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
11240 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
11241 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
27c868c2 11242 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
629d688d
MW
11243 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
11244 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
11245 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
27c868c2 11246 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
629d688d
MW
11247 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
11248 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
11249 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
27c868c2 11250 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
629d688d
MW
11251 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
11252 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
11253 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
27c868c2 11254 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
629d688d
MW
11255 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
11256 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
11257 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
27c868c2 11258 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
629d688d
MW
11259 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
11260 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
11261 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
27c868c2 11262 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
629d688d
MW
11263 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
11264 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
11265 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
27c868c2 11266 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
629d688d
MW
11267 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
11268 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
11269 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
27c868c2 11270 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
629d688d
MW
11271 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
11272 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
11273 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
27c868c2 11274 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
629d688d
MW
11275 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
11276 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
11277 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
27c868c2 11278 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
629d688d
MW
11279 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
11280 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
11281 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
27c868c2 11282 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
629d688d
MW
11283 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
11284 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
11285 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
27c868c2 11286 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
629d688d
MW
11287 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
11288 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
11289 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
27c868c2 11290 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
629d688d
MW
11291 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
11292 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
11293 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
27c868c2 11294 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
629d688d
MW
11295 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
11296 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
11297 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
27c868c2 11298 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
629d688d
MW
11299 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
11300 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
11301 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
27c868c2 11302 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
629d688d
MW
11303 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
11304 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
11305 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
27c868c2 11306 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
629d688d
MW
11307 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
11308 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
11309 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
27c868c2 11310 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
629d688d
MW
11311 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
11312 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
11313 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
27c868c2 11314 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
629d688d
MW
11315 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
11316 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
11317 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
27c868c2 11318 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
629d688d
MW
11319 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
11320 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
11321 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
27c868c2 11322 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
629d688d
MW
11323 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
11324 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
11325 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
27c868c2 11326 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
629d688d
MW
11327 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
11328 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
11329 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
27c868c2 11330 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
629d688d
MW
11331 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
11332 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
11333 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
27c868c2 11334 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
629d688d
MW
11335 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
11336 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
11337 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
27c868c2 11338 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
629d688d
MW
11339 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
11340 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
11341 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
27c868c2 11342 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
629d688d
MW
11343 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
11344 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
11345 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
27c868c2 11346 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
629d688d
MW
11347 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
11348 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
11349 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
27c868c2 11350 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
629d688d
MW
11351 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
11352 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
11353 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
27c868c2 11354 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
629d688d
MW
11355 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
11356 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
11357 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
27c868c2 11358 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
629d688d
MW
11359 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
11360 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
11361 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
27c868c2 11362 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
629d688d
MW
11363 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
11364 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
11365 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
27c868c2 11366 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
629d688d
MW
11367 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
11368 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
11369 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
27c868c2 11370 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
629d688d
MW
11371 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
11372 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
11373 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
27c868c2 11374 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
629d688d
MW
11375 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
11376 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
11377 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
27c868c2 11378 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
629d688d
MW
11379 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
11380 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
11381 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
27c868c2 11382 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
629d688d
MW
11383 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
11384 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
11385 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
27c868c2 11386 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
629d688d
MW
11387 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
11388 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
11389 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
27c868c2 11390 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
629d688d
MW
11391 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
11392 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
11393 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
27c868c2 11394 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
629d688d
MW
11395 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
11396 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
11397 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
27c868c2 11398 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
629d688d
MW
11399 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
11400 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
11401 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
27c868c2 11402 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
629d688d
MW
11403 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
11404 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
11405 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
27c868c2 11406 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
629d688d
MW
11407 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
11408 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
11409 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
27c868c2 11410 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
629d688d
MW
11411 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
11412 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
11413 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
27c868c2 11414 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
629d688d
MW
11415 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
11416 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
11417 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
27c868c2 11418 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
629d688d
MW
11419 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
11420 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
11421 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
27c868c2 11422 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
629d688d
MW
11423 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
11424 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
11425 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
27c868c2 11426 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
629d688d
MW
11427 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
11428 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
11429 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
27c868c2 11430 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
629d688d
MW
11431 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
11432 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
11433 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
27c868c2 11434 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
629d688d
MW
11435 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
11436 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
11437 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
27c868c2 11438 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
629d688d
MW
11439 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
11440 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
11441 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
27c868c2 11442 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
629d688d
MW
11443 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
11444 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
11445 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
27c868c2 11446 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
629d688d
MW
11447 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
11448 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
11449 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
27c868c2 11450 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
629d688d
MW
11451 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
11452 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
11453 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
27c868c2 11454 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
629d688d
MW
11455 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
11456 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
11457 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
27c868c2 11458 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
629d688d
MW
11459 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
11460 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
11461 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
27c868c2 11462 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
629d688d
MW
11463 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
11464 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
11465 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
27c868c2 11466 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
629d688d
MW
11467 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
11468 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
11469 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
27c868c2 11470 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
629d688d
MW
11471 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
11472 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
11473 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
27c868c2 11474 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
629d688d
MW
11475 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
11476 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
11477 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
27c868c2 11478 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
629d688d
MW
11479 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
11480 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
11481 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
27c868c2 11482 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
629d688d
MW
11483 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
11484 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
11485 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
27c868c2 11486 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
629d688d
MW
11487 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
11488 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
11489 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
27c868c2 11490 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
629d688d
MW
11491 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
11492 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
11493 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
27c868c2 11494 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
629d688d
MW
11495 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
11496 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
11497 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
27c868c2 11498 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
629d688d
MW
11499 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
11500 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
11501 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
27c868c2 11502 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
629d688d
MW
11503 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
11504 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
11505 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
27c868c2 11506 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
629d688d
MW
11507 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
11508 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
11509 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
27c868c2 11510 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
629d688d
MW
11511 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
11512 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
11513 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
27c868c2 11514 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
629d688d
MW
11515 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
11516 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
11517 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
27c868c2 11518 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
629d688d
MW
11519 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
11520 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
11521 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
27c868c2 11522 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
629d688d
MW
11523 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
11524 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
11525 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
27c868c2 11526 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
629d688d
MW
11527 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
11528 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
11529 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
27c868c2 11530 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
629d688d
MW
11531 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
11532 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
11533 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 11534 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
11535 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
11536 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
11537 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
27c868c2 11538 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
629d688d
MW
11539 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
11540 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
11541 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
1da177e4
LT
11542};
11543
27c868c2
MW
11544static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
11545static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
1da177e4 11546
1da177e4
LT
11547/*
11548 * EEPROM Configuration.
11549 *
11550 * All drivers should use this structure to set the default EEPROM
11551 * configuration. The BIOS now uses this structure when it is built.
11552 * Additional structure information can be found in a_condor.h where
11553 * the structure is defined.
11554 *
11555 * The *_Field_IsChar structs are needed to correct for endianness.
11556 * These values are read from the board 16 bits at a time directly
11557 * into the structs. Because some fields are char, the values will be
11558 * in the wrong order. The *_Field_IsChar tells when to flip the
11559 * bytes. Data read and written to PCI memory is automatically swapped
11560 * on big-endian platforms so char fields read as words are actually being
11561 * unswapped on big-endian platforms.
11562 */
78e77d8b 11563static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
27c868c2
MW
11564 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
11565 0x0000, /* cfg_msw */
11566 0xFFFF, /* disc_enable */
11567 0xFFFF, /* wdtr_able */
11568 0xFFFF, /* sdtr_able */
11569 0xFFFF, /* start_motor */
11570 0xFFFF, /* tagqng_able */
11571 0xFFFF, /* bios_scan */
11572 0, /* scam_tolerant */
11573 7, /* adapter_scsi_id */
11574 0, /* bios_boot_delay */
11575 3, /* scsi_reset_delay */
11576 0, /* bios_id_lun */
11577 0, /* termination */
11578 0, /* reserved1 */
11579 0xFFE7, /* bios_ctrl */
11580 0xFFFF, /* ultra_able */
11581 0, /* reserved2 */
11582 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
11583 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11584 0, /* dvc_cntl */
11585 0, /* bug_fix */
11586 0, /* serial_number_word1 */
11587 0, /* serial_number_word2 */
11588 0, /* serial_number_word3 */
11589 0, /* check_sum */
11590 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11591 , /* oem_name[16] */
11592 0, /* dvc_err_code */
11593 0, /* adv_err_code */
11594 0, /* adv_err_addr */
11595 0, /* saved_dvc_err_code */
11596 0, /* saved_adv_err_code */
11597 0, /* saved_adv_err_addr */
11598 0 /* num_of_err */
1da177e4
LT
11599};
11600
78e77d8b 11601static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11602 0, /* cfg_lsw */
11603 0, /* cfg_msw */
11604 0, /* -disc_enable */
11605 0, /* wdtr_able */
11606 0, /* sdtr_able */
11607 0, /* start_motor */
11608 0, /* tagqng_able */
11609 0, /* bios_scan */
11610 0, /* scam_tolerant */
11611 1, /* adapter_scsi_id */
11612 1, /* bios_boot_delay */
11613 1, /* scsi_reset_delay */
11614 1, /* bios_id_lun */
11615 1, /* termination */
11616 1, /* reserved1 */
11617 0, /* bios_ctrl */
11618 0, /* ultra_able */
11619 0, /* reserved2 */
11620 1, /* max_host_qng */
11621 1, /* max_dvc_qng */
11622 0, /* dvc_cntl */
11623 0, /* bug_fix */
11624 0, /* serial_number_word1 */
11625 0, /* serial_number_word2 */
11626 0, /* serial_number_word3 */
11627 0, /* check_sum */
11628 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11629 , /* oem_name[16] */
11630 0, /* dvc_err_code */
11631 0, /* adv_err_code */
11632 0, /* adv_err_addr */
11633 0, /* saved_dvc_err_code */
11634 0, /* saved_adv_err_code */
11635 0, /* saved_adv_err_addr */
11636 0 /* num_of_err */
1da177e4
LT
11637};
11638
78e77d8b 11639static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
27c868c2
MW
11640 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
11641 0x0000, /* 01 cfg_msw */
11642 0xFFFF, /* 02 disc_enable */
11643 0xFFFF, /* 03 wdtr_able */
11644 0x4444, /* 04 sdtr_speed1 */
11645 0xFFFF, /* 05 start_motor */
11646 0xFFFF, /* 06 tagqng_able */
11647 0xFFFF, /* 07 bios_scan */
11648 0, /* 08 scam_tolerant */
11649 7, /* 09 adapter_scsi_id */
11650 0, /* bios_boot_delay */
11651 3, /* 10 scsi_reset_delay */
11652 0, /* bios_id_lun */
11653 0, /* 11 termination_se */
11654 0, /* termination_lvd */
11655 0xFFE7, /* 12 bios_ctrl */
11656 0x4444, /* 13 sdtr_speed2 */
11657 0x4444, /* 14 sdtr_speed3 */
11658 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
11659 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11660 0, /* 16 dvc_cntl */
11661 0x4444, /* 17 sdtr_speed4 */
11662 0, /* 18 serial_number_word1 */
11663 0, /* 19 serial_number_word2 */
11664 0, /* 20 serial_number_word3 */
11665 0, /* 21 check_sum */
11666 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11667 , /* 22-29 oem_name[16] */
11668 0, /* 30 dvc_err_code */
11669 0, /* 31 adv_err_code */
11670 0, /* 32 adv_err_addr */
11671 0, /* 33 saved_dvc_err_code */
11672 0, /* 34 saved_adv_err_code */
11673 0, /* 35 saved_adv_err_addr */
11674 0, /* 36 reserved */
11675 0, /* 37 reserved */
11676 0, /* 38 reserved */
11677 0, /* 39 reserved */
11678 0, /* 40 reserved */
11679 0, /* 41 reserved */
11680 0, /* 42 reserved */
11681 0, /* 43 reserved */
11682 0, /* 44 reserved */
11683 0, /* 45 reserved */
11684 0, /* 46 reserved */
11685 0, /* 47 reserved */
11686 0, /* 48 reserved */
11687 0, /* 49 reserved */
11688 0, /* 50 reserved */
11689 0, /* 51 reserved */
11690 0, /* 52 reserved */
11691 0, /* 53 reserved */
11692 0, /* 54 reserved */
11693 0, /* 55 reserved */
11694 0, /* 56 cisptr_lsw */
11695 0, /* 57 cisprt_msw */
11696 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
11697 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
11698 0, /* 60 reserved */
11699 0, /* 61 reserved */
11700 0, /* 62 reserved */
11701 0 /* 63 reserved */
1da177e4
LT
11702};
11703
78e77d8b 11704static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11705 0, /* 00 cfg_lsw */
11706 0, /* 01 cfg_msw */
11707 0, /* 02 disc_enable */
11708 0, /* 03 wdtr_able */
11709 0, /* 04 sdtr_speed1 */
11710 0, /* 05 start_motor */
11711 0, /* 06 tagqng_able */
11712 0, /* 07 bios_scan */
11713 0, /* 08 scam_tolerant */
11714 1, /* 09 adapter_scsi_id */
11715 1, /* bios_boot_delay */
11716 1, /* 10 scsi_reset_delay */
11717 1, /* bios_id_lun */
11718 1, /* 11 termination_se */
11719 1, /* termination_lvd */
11720 0, /* 12 bios_ctrl */
11721 0, /* 13 sdtr_speed2 */
11722 0, /* 14 sdtr_speed3 */
11723 1, /* 15 max_host_qng */
11724 1, /* max_dvc_qng */
11725 0, /* 16 dvc_cntl */
11726 0, /* 17 sdtr_speed4 */
11727 0, /* 18 serial_number_word1 */
11728 0, /* 19 serial_number_word2 */
11729 0, /* 20 serial_number_word3 */
11730 0, /* 21 check_sum */
11731 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11732 , /* 22-29 oem_name[16] */
11733 0, /* 30 dvc_err_code */
11734 0, /* 31 adv_err_code */
11735 0, /* 32 adv_err_addr */
11736 0, /* 33 saved_dvc_err_code */
11737 0, /* 34 saved_adv_err_code */
11738 0, /* 35 saved_adv_err_addr */
11739 0, /* 36 reserved */
11740 0, /* 37 reserved */
11741 0, /* 38 reserved */
11742 0, /* 39 reserved */
11743 0, /* 40 reserved */
11744 0, /* 41 reserved */
11745 0, /* 42 reserved */
11746 0, /* 43 reserved */
11747 0, /* 44 reserved */
11748 0, /* 45 reserved */
11749 0, /* 46 reserved */
11750 0, /* 47 reserved */
11751 0, /* 48 reserved */
11752 0, /* 49 reserved */
11753 0, /* 50 reserved */
11754 0, /* 51 reserved */
11755 0, /* 52 reserved */
11756 0, /* 53 reserved */
11757 0, /* 54 reserved */
11758 0, /* 55 reserved */
11759 0, /* 56 cisptr_lsw */
11760 0, /* 57 cisprt_msw */
11761 0, /* 58 subsysvid */
11762 0, /* 59 subsysid */
11763 0, /* 60 reserved */
11764 0, /* 61 reserved */
11765 0, /* 62 reserved */
11766 0 /* 63 reserved */
1da177e4
LT
11767};
11768
78e77d8b 11769static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
27c868c2
MW
11770 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
11771 0x0000, /* 01 cfg_msw */
11772 0xFFFF, /* 02 disc_enable */
11773 0xFFFF, /* 03 wdtr_able */
11774 0x5555, /* 04 sdtr_speed1 */
11775 0xFFFF, /* 05 start_motor */
11776 0xFFFF, /* 06 tagqng_able */
11777 0xFFFF, /* 07 bios_scan */
11778 0, /* 08 scam_tolerant */
11779 7, /* 09 adapter_scsi_id */
11780 0, /* bios_boot_delay */
11781 3, /* 10 scsi_reset_delay */
11782 0, /* bios_id_lun */
11783 0, /* 11 termination_se */
11784 0, /* termination_lvd */
11785 0xFFE7, /* 12 bios_ctrl */
11786 0x5555, /* 13 sdtr_speed2 */
11787 0x5555, /* 14 sdtr_speed3 */
11788 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
11789 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
11790 0, /* 16 dvc_cntl */
11791 0x5555, /* 17 sdtr_speed4 */
11792 0, /* 18 serial_number_word1 */
11793 0, /* 19 serial_number_word2 */
11794 0, /* 20 serial_number_word3 */
11795 0, /* 21 check_sum */
11796 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11797 , /* 22-29 oem_name[16] */
11798 0, /* 30 dvc_err_code */
11799 0, /* 31 adv_err_code */
11800 0, /* 32 adv_err_addr */
11801 0, /* 33 saved_dvc_err_code */
11802 0, /* 34 saved_adv_err_code */
11803 0, /* 35 saved_adv_err_addr */
11804 0, /* 36 reserved */
11805 0, /* 37 reserved */
11806 0, /* 38 reserved */
11807 0, /* 39 reserved */
11808 0, /* 40 reserved */
11809 0, /* 41 reserved */
11810 0, /* 42 reserved */
11811 0, /* 43 reserved */
11812 0, /* 44 reserved */
11813 0, /* 45 reserved */
11814 0, /* 46 reserved */
11815 0, /* 47 reserved */
11816 0, /* 48 reserved */
11817 0, /* 49 reserved */
11818 0, /* 50 reserved */
11819 0, /* 51 reserved */
11820 0, /* 52 reserved */
11821 0, /* 53 reserved */
11822 0, /* 54 reserved */
11823 0, /* 55 reserved */
11824 0, /* 56 cisptr_lsw */
11825 0, /* 57 cisprt_msw */
11826 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
11827 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
11828 0, /* 60 reserved */
11829 0, /* 61 reserved */
11830 0, /* 62 reserved */
11831 0 /* 63 reserved */
1da177e4
LT
11832};
11833
78e77d8b 11834static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
27c868c2
MW
11835 0, /* 00 cfg_lsw */
11836 0, /* 01 cfg_msw */
11837 0, /* 02 disc_enable */
11838 0, /* 03 wdtr_able */
11839 0, /* 04 sdtr_speed1 */
11840 0, /* 05 start_motor */
11841 0, /* 06 tagqng_able */
11842 0, /* 07 bios_scan */
11843 0, /* 08 scam_tolerant */
11844 1, /* 09 adapter_scsi_id */
11845 1, /* bios_boot_delay */
11846 1, /* 10 scsi_reset_delay */
11847 1, /* bios_id_lun */
11848 1, /* 11 termination_se */
11849 1, /* termination_lvd */
11850 0, /* 12 bios_ctrl */
11851 0, /* 13 sdtr_speed2 */
11852 0, /* 14 sdtr_speed3 */
11853 1, /* 15 max_host_qng */
11854 1, /* max_dvc_qng */
11855 0, /* 16 dvc_cntl */
11856 0, /* 17 sdtr_speed4 */
11857 0, /* 18 serial_number_word1 */
11858 0, /* 19 serial_number_word2 */
11859 0, /* 20 serial_number_word3 */
11860 0, /* 21 check_sum */
11861 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11862 , /* 22-29 oem_name[16] */
11863 0, /* 30 dvc_err_code */
11864 0, /* 31 adv_err_code */
11865 0, /* 32 adv_err_addr */
11866 0, /* 33 saved_dvc_err_code */
11867 0, /* 34 saved_adv_err_code */
11868 0, /* 35 saved_adv_err_addr */
11869 0, /* 36 reserved */
11870 0, /* 37 reserved */
11871 0, /* 38 reserved */
11872 0, /* 39 reserved */
11873 0, /* 40 reserved */
11874 0, /* 41 reserved */
11875 0, /* 42 reserved */
11876 0, /* 43 reserved */
11877 0, /* 44 reserved */
11878 0, /* 45 reserved */
11879 0, /* 46 reserved */
11880 0, /* 47 reserved */
11881 0, /* 48 reserved */
11882 0, /* 49 reserved */
11883 0, /* 50 reserved */
11884 0, /* 51 reserved */
11885 0, /* 52 reserved */
11886 0, /* 53 reserved */
11887 0, /* 54 reserved */
11888 0, /* 55 reserved */
11889 0, /* 56 cisptr_lsw */
11890 0, /* 57 cisprt_msw */
11891 0, /* 58 subsysvid */
11892 0, /* 59 subsysid */
11893 0, /* 60 reserved */
11894 0, /* 61 reserved */
11895 0, /* 62 reserved */
11896 0 /* 63 reserved */
1da177e4
LT
11897};
11898
c2dce2fa 11899#ifdef CONFIG_PCI
1da177e4
LT
11900/*
11901 * Initialize the ADV_DVC_VAR structure.
11902 *
11903 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
11904 *
11905 * For a non-fatal error return a warning code. If there are no warnings
11906 * then 0 is returned.
11907 */
394dbf3f 11908static int __devinit
c2dce2fa 11909AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp)
1da177e4 11910{
c2dce2fa 11911 ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
9649af39
MW
11912 unsigned short warn_code = 0;
11913 AdvPortAddr iop_base = asc_dvc->iop_base;
9649af39 11914 u16 cmd;
27c868c2
MW
11915 int status;
11916
27c868c2 11917 asc_dvc->err_code = 0;
1da177e4 11918
27c868c2
MW
11919 /*
11920 * Save the state of the PCI Configuration Command Register
11921 * "Parity Error Response Control" Bit. If the bit is clear (0),
11922 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
11923 * DMA parity errors.
11924 */
11925 asc_dvc->cfg->control_flag = 0;
9649af39
MW
11926 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
11927 if ((cmd & PCI_COMMAND_PARITY) == 0)
27c868c2 11928 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
1da177e4 11929
27c868c2
MW
11930 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
11931 ADV_LIB_VERSION_MINOR;
11932 asc_dvc->cfg->chip_version =
11933 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
11934
11935 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
11936 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
11937 (ushort)ADV_CHIP_ID_BYTE);
11938
11939 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
11940 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
11941 (ushort)ADV_CHIP_ID_WORD);
11942
11943 /*
11944 * Reset the chip to start and allow register writes.
11945 */
11946 if (AdvFindSignature(iop_base) == 0) {
11947 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11948 return ADV_ERROR;
11949 } else {
11950 /*
11951 * The caller must set 'chip_type' to a valid setting.
11952 */
11953 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
11954 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
11955 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
11956 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
11957 return ADV_ERROR;
11958 }
1da177e4 11959
27c868c2
MW
11960 /*
11961 * Reset Chip.
11962 */
11963 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11964 ADV_CTRL_REG_CMD_RESET);
11965 DvcSleepMilliSecond(100);
11966 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
11967 ADV_CTRL_REG_CMD_WR_IO_REG);
11968
11969 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
9649af39 11970 status = AdvInitFrom38C1600EEP(asc_dvc);
27c868c2 11971 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
9649af39 11972 status = AdvInitFrom38C0800EEP(asc_dvc);
27c868c2 11973 } else {
9649af39 11974 status = AdvInitFrom3550EEP(asc_dvc);
27c868c2
MW
11975 }
11976 warn_code |= status;
11977 }
1da177e4 11978
c2dce2fa
MW
11979 if (warn_code != 0) {
11980 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
11981 boardp->id, warn_code);
11982 }
11983
11984 if (asc_dvc->err_code) {
11985 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
11986 boardp->id, asc_dvc->err_code);
11987 }
11988
11989 return asc_dvc->err_code;
1da177e4 11990}
c2dce2fa 11991#endif
1da177e4 11992
a9f4a59a
MW
11993static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
11994{
11995 ADV_CARR_T *carrp;
11996 ADV_SDCNT buf_size;
11997 ADV_PADDR carr_paddr;
11998
11999 BUG_ON(!asc_dvc->carrier_buf);
12000
12001 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
12002 asc_dvc->carr_freelist = NULL;
12003 if (carrp == asc_dvc->carrier_buf) {
12004 buf_size = ADV_CARRIER_BUFSIZE;
12005 } else {
12006 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
12007 }
12008
12009 do {
12010 /* Get physical address of the carrier 'carrp'. */
12011 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
12012 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
12013 (uchar *)carrp,
12014 (ADV_SDCNT *)&contig_len,
12015 ADV_IS_CARRIER_FLAG));
12016
12017 buf_size -= sizeof(ADV_CARR_T);
12018
12019 /*
12020 * If the current carrier is not physically contiguous, then
12021 * maybe there was a page crossing. Try the next carrier
12022 * aligned start address.
12023 */
12024 if (contig_len < sizeof(ADV_CARR_T)) {
12025 carrp++;
12026 continue;
12027 }
12028
12029 carrp->carr_pa = carr_paddr;
12030 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
12031
12032 /*
12033 * Insert the carrier at the beginning of the freelist.
12034 */
12035 carrp->next_vpa =
12036 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
12037 asc_dvc->carr_freelist = carrp;
12038
12039 carrp++;
12040 } while (buf_size > 0);
12041}
12042
b9d96614
MW
12043/*
12044 * Load the Microcode
12045 *
12046 * Write the microcode image to RISC memory starting at address 0.
12047 *
12048 * The microcode is stored compressed in the following format:
12049 *
12050 * 254 word (508 byte) table indexed by byte code followed
12051 * by the following byte codes:
12052 *
12053 * 1-Byte Code:
12054 * 00: Emit word 0 in table.
12055 * 01: Emit word 1 in table.
12056 * .
12057 * FD: Emit word 253 in table.
12058 *
12059 * Multi-Byte Code:
12060 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
12061 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
12062 *
12063 * Returns 0 or an error if the checksum doesn't match
12064 */
12065static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
12066 int memsize, int chksum)
12067{
12068 int i, j, end, len = 0;
12069 ADV_DCNT sum;
12070
12071 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
12072
12073 for (i = 253 * 2; i < size; i++) {
12074 if (buf[i] == 0xff) {
12075 unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
12076 for (j = 0; j < buf[i + 1]; j++) {
12077 AdvWriteWordAutoIncLram(iop_base, word);
12078 len += 2;
12079 }
12080 i += 3;
12081 } else if (buf[i] == 0xfe) {
12082 unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
12083 AdvWriteWordAutoIncLram(iop_base, word);
12084 i += 2;
12085 len += 2;
12086 } else {
12087 unsigned char off = buf[i] * 2;
12088 unsigned short word = (buf[off + 1] << 8) | buf[off];
12089 AdvWriteWordAutoIncLram(iop_base, word);
12090 len += 2;
12091 }
12092 }
12093
12094 end = len;
12095
12096 while (len < memsize) {
12097 AdvWriteWordAutoIncLram(iop_base, 0);
12098 len += 2;
12099 }
12100
12101 /* Verify the microcode checksum. */
12102 sum = 0;
12103 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
12104
12105 for (len = 0; len < end; len += 2) {
12106 sum += AdvReadWordAutoIncLram(iop_base);
12107 }
12108
12109 if (sum != chksum)
12110 return ASC_IERR_MCODE_CHKSUM;
12111
12112 return 0;
12113}
12114
1da177e4
LT
12115/*
12116 * Initialize the ASC-3550.
12117 *
12118 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12119 *
12120 * For a non-fatal error return a warning code. If there are no warnings
12121 * then 0 is returned.
12122 *
12123 * Needed after initialization for error recovery.
12124 */
27c868c2 12125static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 12126{
27c868c2
MW
12127 AdvPortAddr iop_base;
12128 ushort warn_code;
27c868c2
MW
12129 int begin_addr;
12130 int end_addr;
12131 ushort code_sum;
12132 int word;
27c868c2
MW
12133 int i;
12134 ushort scsi_cfg1;
12135 uchar tid;
12136 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
12137 ushort wdtr_able = 0, sdtr_able, tagqng_able;
12138 uchar max_cmd[ADV_MAX_TID + 1];
12139
12140 /* If there is already an error, don't continue. */
b9d96614 12141 if (asc_dvc->err_code != 0)
27c868c2 12142 return ADV_ERROR;
1da177e4 12143
27c868c2
MW
12144 /*
12145 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
12146 */
12147 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
b9d96614 12148 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
27c868c2
MW
12149 return ADV_ERROR;
12150 }
1da177e4 12151
27c868c2
MW
12152 warn_code = 0;
12153 iop_base = asc_dvc->iop_base;
12154
12155 /*
12156 * Save the RISC memory BIOS region before writing the microcode.
12157 * The BIOS may already be loaded and using its RISC LRAM region
12158 * so its region must be saved and restored.
12159 *
12160 * Note: This code makes the assumption, which is currently true,
12161 * that a chip reset does not clear RISC LRAM.
12162 */
12163 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12164 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12165 bios_mem[i]);
12166 }
1da177e4 12167
27c868c2
MW
12168 /*
12169 * Save current per TID negotiated values.
12170 */
12171 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
12172 ushort bios_version, major, minor;
12173
12174 bios_version =
12175 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
12176 major = (bios_version >> 12) & 0xF;
12177 minor = (bios_version >> 8) & 0xF;
12178 if (major < 3 || (major == 3 && minor == 1)) {
12179 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
12180 AdvReadWordLram(iop_base, 0x120, wdtr_able);
12181 } else {
12182 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12183 }
12184 }
12185 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12186 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
12187 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12188 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
12189 max_cmd[tid]);
12190 }
1da177e4 12191
b9d96614
MW
12192 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
12193 _adv_asc3550_size, ADV_3550_MEMSIZE,
12194 _adv_asc3550_chksum);
12195 if (asc_dvc->err_code)
27c868c2 12196 return ADV_ERROR;
1da177e4 12197
27c868c2
MW
12198 /*
12199 * Restore the RISC memory BIOS region.
12200 */
12201 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12202 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12203 bios_mem[i]);
12204 }
1da177e4 12205
27c868c2
MW
12206 /*
12207 * Calculate and write the microcode code checksum to the microcode
12208 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
12209 */
12210 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
12211 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
12212 code_sum = 0;
12213 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
12214 for (word = begin_addr; word < end_addr; word += 2) {
12215 code_sum += AdvReadWordAutoIncLram(iop_base);
12216 }
12217 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
12218
12219 /*
12220 * Read and save microcode version and date.
12221 */
12222 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
12223 asc_dvc->cfg->mcode_date);
12224 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
12225 asc_dvc->cfg->mcode_version);
12226
12227 /*
12228 * Set the chip type to indicate the ASC3550.
12229 */
12230 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
12231
12232 /*
12233 * If the PCI Configuration Command Register "Parity Error Response
12234 * Control" Bit was clear (0), then set the microcode variable
12235 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
12236 * to ignore DMA parity errors.
12237 */
12238 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
12239 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12240 word |= CONTROL_FLAG_IGNORE_PERR;
12241 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12242 }
1da177e4 12243
27c868c2
MW
12244 /*
12245 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
12246 * threshold of 128 bytes. This register is only accessible to the host.
12247 */
12248 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
12249 START_CTL_EMFU | READ_CMD_MRM);
12250
12251 /*
12252 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 12253 * queuing will be set in slave_configure() based on what a
27c868c2
MW
12254 * device reports it is capable of in Inquiry byte 7.
12255 *
12256 * If SCSI Bus Resets have been disabled, then directly set
12257 * SDTR and WDTR from the EEPROM configuration. This will allow
12258 * the BIOS and warm boot to work without a SCSI bus hang on
12259 * the Inquiry caused by host and target mismatched DTR values.
12260 * Without the SCSI Bus Reset, before an Inquiry a device can't
12261 * be assumed to be in Asynchronous, Narrow mode.
12262 */
12263 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
12264 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
12265 asc_dvc->wdtr_able);
12266 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
12267 asc_dvc->sdtr_able);
12268 }
1da177e4 12269
27c868c2
MW
12270 /*
12271 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
12272 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
12273 * bitmask. These values determine the maximum SDTR speed negotiated
12274 * with a device.
12275 *
12276 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
12277 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
12278 * without determining here whether the device supports SDTR.
12279 *
12280 * 4-bit speed SDTR speed name
12281 * =========== ===============
12282 * 0000b (0x0) SDTR disabled
12283 * 0001b (0x1) 5 Mhz
12284 * 0010b (0x2) 10 Mhz
12285 * 0011b (0x3) 20 Mhz (Ultra)
12286 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
12287 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
12288 * 0110b (0x6) Undefined
12289 * .
12290 * 1111b (0xF) Undefined
12291 */
12292 word = 0;
12293 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12294 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
12295 /* Set Ultra speed for TID 'tid'. */
12296 word |= (0x3 << (4 * (tid % 4)));
12297 } else {
12298 /* Set Fast speed for TID 'tid'. */
12299 word |= (0x2 << (4 * (tid % 4)));
12300 }
12301 if (tid == 3) { /* Check if done with sdtr_speed1. */
12302 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
12303 word = 0;
12304 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
12305 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
12306 word = 0;
12307 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
12308 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
12309 word = 0;
12310 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
12311 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
12312 /* End of loop. */
12313 }
12314 }
1da177e4 12315
27c868c2
MW
12316 /*
12317 * Set microcode operating variable for the disconnect per TID bitmask.
12318 */
12319 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
12320 asc_dvc->cfg->disc_enable);
12321
12322 /*
12323 * Set SCSI_CFG0 Microcode Default Value.
12324 *
12325 * The microcode will set the SCSI_CFG0 register using this value
12326 * after it is started below.
12327 */
12328 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
12329 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
12330 asc_dvc->chip_scsi_id);
12331
12332 /*
12333 * Determine SCSI_CFG1 Microcode Default Value.
12334 *
12335 * The microcode will set the SCSI_CFG1 register using this value
12336 * after it is started below.
12337 */
12338
12339 /* Read current SCSI_CFG1 Register value. */
12340 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12341
12342 /*
12343 * If all three connectors are in use, return an error.
12344 */
12345 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
12346 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
12347 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
12348 return ADV_ERROR;
12349 }
1da177e4 12350
27c868c2
MW
12351 /*
12352 * If the internal narrow cable is reversed all of the SCSI_CTRL
12353 * register signals will be set. Check for and return an error if
12354 * this condition is found.
12355 */
12356 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
12357 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
12358 return ADV_ERROR;
12359 }
1da177e4 12360
27c868c2
MW
12361 /*
12362 * If this is a differential board and a single-ended device
12363 * is attached to one of the connectors, return an error.
12364 */
12365 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
12366 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
12367 return ADV_ERROR;
12368 }
1da177e4 12369
27c868c2
MW
12370 /*
12371 * If automatic termination control is enabled, then set the
12372 * termination value based on a table listed in a_condor.h.
12373 *
12374 * If manual termination was specified with an EEPROM setting
12375 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
12376 * is ready to be 'ored' into SCSI_CFG1.
12377 */
12378 if (asc_dvc->cfg->termination == 0) {
12379 /*
12380 * The software always controls termination by setting TERM_CTL_SEL.
12381 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
12382 */
12383 asc_dvc->cfg->termination |= TERM_CTL_SEL;
12384
12385 switch (scsi_cfg1 & CABLE_DETECT) {
12386 /* TERM_CTL_H: on, TERM_CTL_L: on */
12387 case 0x3:
12388 case 0x7:
12389 case 0xB:
12390 case 0xD:
12391 case 0xE:
12392 case 0xF:
12393 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
12394 break;
12395
12396 /* TERM_CTL_H: on, TERM_CTL_L: off */
12397 case 0x1:
12398 case 0x5:
12399 case 0x9:
12400 case 0xA:
12401 case 0xC:
12402 asc_dvc->cfg->termination |= TERM_CTL_H;
12403 break;
12404
12405 /* TERM_CTL_H: off, TERM_CTL_L: off */
12406 case 0x2:
12407 case 0x6:
12408 break;
12409 }
12410 }
1da177e4 12411
27c868c2
MW
12412 /*
12413 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
12414 */
12415 scsi_cfg1 &= ~TERM_CTL;
12416
12417 /*
12418 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
12419 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
12420 * referenced, because the hardware internally inverts
12421 * the Termination High and Low bits if TERM_POL is set.
12422 */
12423 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
12424
12425 /*
12426 * Set SCSI_CFG1 Microcode Default Value
12427 *
12428 * Set filter value and possibly modified termination control
12429 * bits in the Microcode SCSI_CFG1 Register Value.
12430 *
12431 * The microcode will set the SCSI_CFG1 register using this value
12432 * after it is started below.
12433 */
12434 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
12435 FLTR_DISABLE | scsi_cfg1);
12436
12437 /*
12438 * Set MEM_CFG Microcode Default Value
12439 *
12440 * The microcode will set the MEM_CFG register using this value
12441 * after it is started below.
12442 *
12443 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12444 * are defined.
12445 *
12446 * ASC-3550 has 8KB internal memory.
12447 */
12448 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12449 BIOS_EN | RAM_SZ_8KB);
12450
12451 /*
12452 * Set SEL_MASK Microcode Default Value
12453 *
12454 * The microcode will set the SEL_MASK register using this value
12455 * after it is started below.
12456 */
12457 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12458 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12459
a9f4a59a 12460 AdvBuildCarrierFreelist(asc_dvc);
1da177e4 12461
27c868c2
MW
12462 /*
12463 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12464 */
1da177e4 12465
27c868c2
MW
12466 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12467 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12468 return ADV_ERROR;
12469 }
12470 asc_dvc->carr_freelist = (ADV_CARR_T *)
12471 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12472
12473 /*
12474 * The first command issued will be placed in the stopper carrier.
12475 */
12476 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12477
12478 /*
12479 * Set RISC ICQ physical address start value.
12480 */
12481 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12482
12483 /*
12484 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12485 */
12486 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12487 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12488 return ADV_ERROR;
12489 }
12490 asc_dvc->carr_freelist = (ADV_CARR_T *)
12491 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12492
12493 /*
12494 * The first command completed by the RISC will be placed in
12495 * the stopper.
12496 *
12497 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12498 * completed the RISC will set the ASC_RQ_STOPPER bit.
12499 */
12500 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12501
12502 /*
12503 * Set RISC IRQ physical address start value.
12504 */
12505 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12506 asc_dvc->carr_pending_cnt = 0;
12507
12508 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12509 (ADV_INTR_ENABLE_HOST_INTR |
12510 ADV_INTR_ENABLE_GLOBAL_INTR));
12511
12512 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12513 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12514
12515 /* finally, finally, gentlemen, start your engine */
12516 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12517
12518 /*
12519 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12520 * Resets should be performed. The RISC has to be running
12521 * to issue a SCSI Bus Reset.
12522 */
12523 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
12524 /*
12525 * If the BIOS Signature is present in memory, restore the
12526 * BIOS Handshake Configuration Table and do not perform
12527 * a SCSI Bus Reset.
12528 */
12529 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
12530 0x55AA) {
12531 /*
12532 * Restore per TID negotiated values.
12533 */
12534 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12535 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12536 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
12537 tagqng_able);
12538 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12539 AdvWriteByteLram(iop_base,
12540 ASC_MC_NUMBER_OF_MAX_CMD + tid,
12541 max_cmd[tid]);
12542 }
12543 } else {
12544 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
12545 warn_code = ASC_WARN_BUSRESET_ERROR;
12546 }
12547 }
12548 }
1da177e4 12549
27c868c2
MW
12550 return warn_code;
12551}
1da177e4 12552
27c868c2
MW
12553/*
12554 * Initialize the ASC-38C0800.
12555 *
12556 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12557 *
12558 * For a non-fatal error return a warning code. If there are no warnings
12559 * then 0 is returned.
12560 *
12561 * Needed after initialization for error recovery.
12562 */
12563static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
12564{
12565 AdvPortAddr iop_base;
12566 ushort warn_code;
27c868c2
MW
12567 int begin_addr;
12568 int end_addr;
12569 ushort code_sum;
12570 int word;
27c868c2
MW
12571 int i;
12572 ushort scsi_cfg1;
12573 uchar byte;
12574 uchar tid;
12575 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
12576 ushort wdtr_able, sdtr_able, tagqng_able;
12577 uchar max_cmd[ADV_MAX_TID + 1];
12578
12579 /* If there is already an error, don't continue. */
b9d96614 12580 if (asc_dvc->err_code != 0)
27c868c2 12581 return ADV_ERROR;
1da177e4 12582
27c868c2
MW
12583 /*
12584 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
12585 */
12586 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
12587 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
12588 return ADV_ERROR;
12589 }
1da177e4 12590
27c868c2
MW
12591 warn_code = 0;
12592 iop_base = asc_dvc->iop_base;
12593
12594 /*
12595 * Save the RISC memory BIOS region before writing the microcode.
12596 * The BIOS may already be loaded and using its RISC LRAM region
12597 * so its region must be saved and restored.
12598 *
12599 * Note: This code makes the assumption, which is currently true,
12600 * that a chip reset does not clear RISC LRAM.
12601 */
12602 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12603 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12604 bios_mem[i]);
12605 }
1da177e4 12606
27c868c2
MW
12607 /*
12608 * Save current per TID negotiated values.
12609 */
12610 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
12611 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
12612 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
12613 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12614 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
12615 max_cmd[tid]);
12616 }
1da177e4 12617
27c868c2
MW
12618 /*
12619 * RAM BIST (RAM Built-In Self Test)
12620 *
12621 * Address : I/O base + offset 0x38h register (byte).
12622 * Function: Bit 7-6(RW) : RAM mode
12623 * Normal Mode : 0x00
12624 * Pre-test Mode : 0x40
12625 * RAM Test Mode : 0x80
12626 * Bit 5 : unused
12627 * Bit 4(RO) : Done bit
12628 * Bit 3-0(RO) : Status
12629 * Host Error : 0x08
12630 * Int_RAM Error : 0x04
12631 * RISC Error : 0x02
12632 * SCSI Error : 0x01
12633 * No Error : 0x00
12634 *
12635 * Note: RAM BIST code should be put right here, before loading the
12636 * microcode and after saving the RISC memory BIOS region.
12637 */
12638
12639 /*
12640 * LRAM Pre-test
12641 *
12642 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
12643 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
12644 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
12645 * to NORMAL_MODE, return an error too.
12646 */
12647 for (i = 0; i < 2; i++) {
12648 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
12649 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
12650 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12651 if ((byte & RAM_TEST_DONE) == 0
12652 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 12653 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12654 return ADV_ERROR;
12655 }
12656
12657 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12658 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
12659 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
12660 != NORMAL_VALUE) {
b9d96614 12661 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
12662 return ADV_ERROR;
12663 }
12664 }
1da177e4 12665
27c868c2
MW
12666 /*
12667 * LRAM Test - It takes about 1.5 ms to run through the test.
12668 *
12669 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
12670 * If Done bit not set or Status not 0, save register byte, set the
12671 * err_code, and return an error.
12672 */
12673 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
12674 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
12675
12676 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
12677 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
12678 /* Get here if Done bit not set or Status not 0. */
12679 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 12680 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
12681 return ADV_ERROR;
12682 }
1da177e4 12683
27c868c2
MW
12684 /* We need to reset back to normal mode after LRAM test passes. */
12685 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
12686
b9d96614
MW
12687 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
12688 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
12689 _adv_asc38C0800_chksum);
12690 if (asc_dvc->err_code)
27c868c2 12691 return ADV_ERROR;
1da177e4 12692
27c868c2
MW
12693 /*
12694 * Restore the RISC memory BIOS region.
12695 */
12696 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12697 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12698 bios_mem[i]);
12699 }
1da177e4 12700
27c868c2
MW
12701 /*
12702 * Calculate and write the microcode code checksum to the microcode
12703 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
12704 */
12705 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
12706 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
12707 code_sum = 0;
12708 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
12709 for (word = begin_addr; word < end_addr; word += 2) {
12710 code_sum += AdvReadWordAutoIncLram(iop_base);
12711 }
12712 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
12713
12714 /*
12715 * Read microcode version and date.
12716 */
12717 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
12718 asc_dvc->cfg->mcode_date);
12719 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
12720 asc_dvc->cfg->mcode_version);
12721
12722 /*
12723 * Set the chip type to indicate the ASC38C0800.
12724 */
12725 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
12726
12727 /*
12728 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
12729 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
12730 * cable detection and then we are able to read C_DET[3:0].
12731 *
12732 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
12733 * Microcode Default Value' section below.
12734 */
12735 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12736 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
12737 scsi_cfg1 | DIS_TERM_DRV);
12738
12739 /*
12740 * If the PCI Configuration Command Register "Parity Error Response
12741 * Control" Bit was clear (0), then set the microcode variable
12742 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
12743 * to ignore DMA parity errors.
12744 */
12745 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
12746 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12747 word |= CONTROL_FLAG_IGNORE_PERR;
12748 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
12749 }
1da177e4 12750
27c868c2
MW
12751 /*
12752 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
12753 * bits for the default FIFO threshold.
12754 *
12755 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
12756 *
12757 * For DMA Errata #4 set the BC_THRESH_ENB bit.
12758 */
12759 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
12760 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
12761 READ_CMD_MRM);
12762
12763 /*
12764 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 12765 * queuing will be set in slave_configure() based on what a
27c868c2
MW
12766 * device reports it is capable of in Inquiry byte 7.
12767 *
12768 * If SCSI Bus Resets have been disabled, then directly set
12769 * SDTR and WDTR from the EEPROM configuration. This will allow
12770 * the BIOS and warm boot to work without a SCSI bus hang on
12771 * the Inquiry caused by host and target mismatched DTR values.
12772 * Without the SCSI Bus Reset, before an Inquiry a device can't
12773 * be assumed to be in Asynchronous, Narrow mode.
12774 */
12775 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
12776 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
12777 asc_dvc->wdtr_able);
12778 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
12779 asc_dvc->sdtr_able);
12780 }
1da177e4 12781
27c868c2
MW
12782 /*
12783 * Set microcode operating variables for DISC and SDTR_SPEED1,
12784 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
12785 * configuration values.
12786 *
12787 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
12788 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
12789 * without determining here whether the device supports SDTR.
12790 */
12791 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
12792 asc_dvc->cfg->disc_enable);
12793 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
12794 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
12795 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
12796 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
12797
12798 /*
12799 * Set SCSI_CFG0 Microcode Default Value.
12800 *
12801 * The microcode will set the SCSI_CFG0 register using this value
12802 * after it is started below.
12803 */
12804 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
12805 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
12806 asc_dvc->chip_scsi_id);
12807
12808 /*
12809 * Determine SCSI_CFG1 Microcode Default Value.
12810 *
12811 * The microcode will set the SCSI_CFG1 register using this value
12812 * after it is started below.
12813 */
12814
12815 /* Read current SCSI_CFG1 Register value. */
12816 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
12817
12818 /*
12819 * If the internal narrow cable is reversed all of the SCSI_CTRL
12820 * register signals will be set. Check for and return an error if
12821 * this condition is found.
12822 */
12823 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
12824 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
12825 return ADV_ERROR;
12826 }
1da177e4 12827
27c868c2 12828 /*
b9d96614
MW
12829 * All kind of combinations of devices attached to one of four
12830 * connectors are acceptable except HVD device attached. For example,
12831 * LVD device can be attached to SE connector while SE device attached
12832 * to LVD connector. If LVD device attached to SE connector, it only
12833 * runs up to Ultra speed.
27c868c2 12834 *
b9d96614
MW
12835 * If an HVD device is attached to one of LVD connectors, return an
12836 * error. However, there is no way to detect HVD device attached to
12837 * SE connectors.
27c868c2
MW
12838 */
12839 if (scsi_cfg1 & HVD) {
b9d96614 12840 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
27c868c2
MW
12841 return ADV_ERROR;
12842 }
1da177e4 12843
27c868c2
MW
12844 /*
12845 * If either SE or LVD automatic termination control is enabled, then
12846 * set the termination value based on a table listed in a_condor.h.
12847 *
12848 * If manual termination was specified with an EEPROM setting then
b9d96614
MW
12849 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
12850 * to be 'ored' into SCSI_CFG1.
27c868c2
MW
12851 */
12852 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
12853 /* SE automatic termination control is enabled. */
12854 switch (scsi_cfg1 & C_DET_SE) {
12855 /* TERM_SE_HI: on, TERM_SE_LO: on */
12856 case 0x1:
12857 case 0x2:
12858 case 0x3:
12859 asc_dvc->cfg->termination |= TERM_SE;
12860 break;
12861
12862 /* TERM_SE_HI: on, TERM_SE_LO: off */
12863 case 0x0:
12864 asc_dvc->cfg->termination |= TERM_SE_HI;
12865 break;
12866 }
12867 }
12868
12869 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
12870 /* LVD automatic termination control is enabled. */
12871 switch (scsi_cfg1 & C_DET_LVD) {
12872 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
12873 case 0x4:
12874 case 0x8:
12875 case 0xC:
12876 asc_dvc->cfg->termination |= TERM_LVD;
12877 break;
12878
12879 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
12880 case 0x0:
12881 break;
12882 }
12883 }
12884
12885 /*
12886 * Clear any set TERM_SE and TERM_LVD bits.
12887 */
12888 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
12889
12890 /*
12891 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
12892 */
12893 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
12894
12895 /*
b9d96614
MW
12896 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
12897 * bits and set possibly modified termination control bits in the
12898 * Microcode SCSI_CFG1 Register Value.
27c868c2
MW
12899 */
12900 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
12901
12902 /*
12903 * Set SCSI_CFG1 Microcode Default Value
12904 *
12905 * Set possibly modified termination control and reset DIS_TERM_DRV
12906 * bits in the Microcode SCSI_CFG1 Register Value.
12907 *
12908 * The microcode will set the SCSI_CFG1 register using this value
12909 * after it is started below.
12910 */
12911 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
12912
12913 /*
12914 * Set MEM_CFG Microcode Default Value
12915 *
12916 * The microcode will set the MEM_CFG register using this value
12917 * after it is started below.
12918 *
12919 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
12920 * are defined.
12921 *
12922 * ASC-38C0800 has 16KB internal memory.
12923 */
12924 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
12925 BIOS_EN | RAM_SZ_16KB);
12926
12927 /*
12928 * Set SEL_MASK Microcode Default Value
12929 *
12930 * The microcode will set the SEL_MASK register using this value
12931 * after it is started below.
12932 */
12933 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
12934 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
12935
a9f4a59a 12936 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
12937
12938 /*
12939 * Set-up the Host->RISC Initiator Command Queue (ICQ).
12940 */
12941
12942 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
12943 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12944 return ADV_ERROR;
12945 }
12946 asc_dvc->carr_freelist = (ADV_CARR_T *)
12947 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
12948
12949 /*
12950 * The first command issued will be placed in the stopper carrier.
12951 */
12952 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12953
12954 /*
12955 * Set RISC ICQ physical address start value.
12956 * carr_pa is LE, must be native before write
12957 */
12958 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
12959
12960 /*
12961 * Set-up the RISC->Host Initiator Response Queue (IRQ).
12962 */
12963 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
12964 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
12965 return ADV_ERROR;
12966 }
12967 asc_dvc->carr_freelist = (ADV_CARR_T *)
12968 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
12969
12970 /*
12971 * The first command completed by the RISC will be placed in
12972 * the stopper.
12973 *
12974 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
12975 * completed the RISC will set the ASC_RQ_STOPPER bit.
12976 */
12977 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
12978
12979 /*
12980 * Set RISC IRQ physical address start value.
12981 *
12982 * carr_pa is LE, must be native before write *
12983 */
12984 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
12985 asc_dvc->carr_pending_cnt = 0;
12986
12987 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
12988 (ADV_INTR_ENABLE_HOST_INTR |
12989 ADV_INTR_ENABLE_GLOBAL_INTR));
12990
12991 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
12992 AdvWriteWordRegister(iop_base, IOPW_PC, word);
12993
12994 /* finally, finally, gentlemen, start your engine */
12995 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
12996
12997 /*
12998 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
12999 * Resets should be performed. The RISC has to be running
13000 * to issue a SCSI Bus Reset.
13001 */
13002 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
13003 /*
13004 * If the BIOS Signature is present in memory, restore the
13005 * BIOS Handshake Configuration Table and do not perform
13006 * a SCSI Bus Reset.
13007 */
13008 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
13009 0x55AA) {
13010 /*
13011 * Restore per TID negotiated values.
13012 */
13013 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13014 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13015 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
13016 tagqng_able);
13017 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13018 AdvWriteByteLram(iop_base,
13019 ASC_MC_NUMBER_OF_MAX_CMD + tid,
13020 max_cmd[tid]);
13021 }
13022 } else {
13023 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
13024 warn_code = ASC_WARN_BUSRESET_ERROR;
13025 }
13026 }
13027 }
13028
13029 return warn_code;
1da177e4
LT
13030}
13031
13032/*
27c868c2 13033 * Initialize the ASC-38C1600.
1da177e4 13034 *
27c868c2 13035 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
1da177e4
LT
13036 *
13037 * For a non-fatal error return a warning code. If there are no warnings
13038 * then 0 is returned.
13039 *
13040 * Needed after initialization for error recovery.
13041 */
27c868c2 13042static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
1da177e4 13043{
27c868c2
MW
13044 AdvPortAddr iop_base;
13045 ushort warn_code;
27c868c2
MW
13046 int begin_addr;
13047 int end_addr;
13048 ushort code_sum;
13049 long word;
27c868c2
MW
13050 int i;
13051 ushort scsi_cfg1;
13052 uchar byte;
13053 uchar tid;
13054 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
13055 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
13056 uchar max_cmd[ASC_MAX_TID + 1];
13057
13058 /* If there is already an error, don't continue. */
13059 if (asc_dvc->err_code != 0) {
13060 return ADV_ERROR;
13061 }
1da177e4 13062
27c868c2
MW
13063 /*
13064 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
13065 */
13066 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13067 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
13068 return ADV_ERROR;
13069 }
1da177e4 13070
27c868c2
MW
13071 warn_code = 0;
13072 iop_base = asc_dvc->iop_base;
13073
13074 /*
13075 * Save the RISC memory BIOS region before writing the microcode.
13076 * The BIOS may already be loaded and using its RISC LRAM region
13077 * so its region must be saved and restored.
13078 *
13079 * Note: This code makes the assumption, which is currently true,
13080 * that a chip reset does not clear RISC LRAM.
13081 */
13082 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13083 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13084 bios_mem[i]);
13085 }
1da177e4 13086
27c868c2
MW
13087 /*
13088 * Save current per TID negotiated values.
13089 */
13090 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13091 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13092 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
13093 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13094 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13095 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13096 max_cmd[tid]);
13097 }
1da177e4 13098
27c868c2
MW
13099 /*
13100 * RAM BIST (Built-In Self Test)
13101 *
13102 * Address : I/O base + offset 0x38h register (byte).
13103 * Function: Bit 7-6(RW) : RAM mode
13104 * Normal Mode : 0x00
13105 * Pre-test Mode : 0x40
13106 * RAM Test Mode : 0x80
13107 * Bit 5 : unused
13108 * Bit 4(RO) : Done bit
13109 * Bit 3-0(RO) : Status
13110 * Host Error : 0x08
13111 * Int_RAM Error : 0x04
13112 * RISC Error : 0x02
13113 * SCSI Error : 0x01
13114 * No Error : 0x00
13115 *
13116 * Note: RAM BIST code should be put right here, before loading the
13117 * microcode and after saving the RISC memory BIOS region.
13118 */
13119
13120 /*
13121 * LRAM Pre-test
13122 *
13123 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
13124 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
13125 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
13126 * to NORMAL_MODE, return an error too.
13127 */
13128 for (i = 0; i < 2; i++) {
13129 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
13130 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
13131 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
13132 if ((byte & RAM_TEST_DONE) == 0
13133 || (byte & 0x0F) != PRE_TEST_VALUE) {
b9d96614 13134 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
13135 return ADV_ERROR;
13136 }
13137
13138 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
13139 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
13140 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
13141 != NORMAL_VALUE) {
b9d96614 13142 asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
27c868c2
MW
13143 return ADV_ERROR;
13144 }
13145 }
1da177e4 13146
27c868c2
MW
13147 /*
13148 * LRAM Test - It takes about 1.5 ms to run through the test.
13149 *
13150 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
13151 * If Done bit not set or Status not 0, save register byte, set the
13152 * err_code, and return an error.
13153 */
13154 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
13155 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
13156
13157 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
13158 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
13159 /* Get here if Done bit not set or Status not 0. */
13160 asc_dvc->bist_err_code = byte; /* for BIOS display message */
b9d96614 13161 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
27c868c2
MW
13162 return ADV_ERROR;
13163 }
1da177e4 13164
27c868c2
MW
13165 /* We need to reset back to normal mode after LRAM test passes. */
13166 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
13167
b9d96614
MW
13168 asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
13169 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
13170 _adv_asc38C1600_chksum);
13171 if (asc_dvc->err_code)
27c868c2 13172 return ADV_ERROR;
1da177e4 13173
27c868c2
MW
13174 /*
13175 * Restore the RISC memory BIOS region.
13176 */
13177 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13178 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13179 bios_mem[i]);
13180 }
1da177e4 13181
27c868c2
MW
13182 /*
13183 * Calculate and write the microcode code checksum to the microcode
13184 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13185 */
13186 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13187 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13188 code_sum = 0;
13189 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13190 for (word = begin_addr; word < end_addr; word += 2) {
13191 code_sum += AdvReadWordAutoIncLram(iop_base);
13192 }
13193 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13194
13195 /*
13196 * Read microcode version and date.
13197 */
13198 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13199 asc_dvc->cfg->mcode_date);
13200 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13201 asc_dvc->cfg->mcode_version);
13202
13203 /*
13204 * Set the chip type to indicate the ASC38C1600.
13205 */
13206 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
13207
13208 /*
13209 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
13210 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
13211 * cable detection and then we are able to read C_DET[3:0].
13212 *
13213 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
13214 * Microcode Default Value' section below.
13215 */
13216 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13217 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
13218 scsi_cfg1 | DIS_TERM_DRV);
13219
13220 /*
13221 * If the PCI Configuration Command Register "Parity Error Response
13222 * Control" Bit was clear (0), then set the microcode variable
13223 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13224 * to ignore DMA parity errors.
13225 */
13226 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13227 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13228 word |= CONTROL_FLAG_IGNORE_PERR;
13229 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13230 }
1da177e4 13231
27c868c2
MW
13232 /*
13233 * If the BIOS control flag AIPP (Asynchronous Information
13234 * Phase Protection) disable bit is not set, then set the firmware
13235 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
13236 * AIPP checking and encoding.
13237 */
13238 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
13239 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13240 word |= CONTROL_FLAG_ENABLE_AIPP;
13241 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13242 }
1da177e4 13243
27c868c2
MW
13244 /*
13245 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
13246 * and START_CTL_TH [3:2].
13247 */
13248 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13249 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
13250
13251 /*
13252 * Microcode operating variables for WDTR, SDTR, and command tag
47d853cc 13253 * queuing will be set in slave_configure() based on what a
27c868c2
MW
13254 * device reports it is capable of in Inquiry byte 7.
13255 *
13256 * If SCSI Bus Resets have been disabled, then directly set
13257 * SDTR and WDTR from the EEPROM configuration. This will allow
13258 * the BIOS and warm boot to work without a SCSI bus hang on
13259 * the Inquiry caused by host and target mismatched DTR values.
13260 * Without the SCSI Bus Reset, before an Inquiry a device can't
13261 * be assumed to be in Asynchronous, Narrow mode.
13262 */
13263 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13264 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13265 asc_dvc->wdtr_able);
13266 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13267 asc_dvc->sdtr_able);
13268 }
1da177e4 13269
27c868c2
MW
13270 /*
13271 * Set microcode operating variables for DISC and SDTR_SPEED1,
13272 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
13273 * configuration values.
13274 *
13275 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13276 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13277 * without determining here whether the device supports SDTR.
13278 */
13279 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
13280 asc_dvc->cfg->disc_enable);
13281 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
13282 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
13283 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
13284 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
13285
13286 /*
13287 * Set SCSI_CFG0 Microcode Default Value.
13288 *
13289 * The microcode will set the SCSI_CFG0 register using this value
13290 * after it is started below.
13291 */
13292 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
13293 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
13294 asc_dvc->chip_scsi_id);
13295
13296 /*
13297 * Calculate SCSI_CFG1 Microcode Default Value.
13298 *
13299 * The microcode will set the SCSI_CFG1 register using this value
13300 * after it is started below.
13301 *
13302 * Each ASC-38C1600 function has only two cable detect bits.
13303 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
13304 */
13305 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13306
13307 /*
13308 * If the cable is reversed all of the SCSI_CTRL register signals
13309 * will be set. Check for and return an error if this condition is
13310 * found.
13311 */
13312 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
13313 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
13314 return ADV_ERROR;
13315 }
1da177e4 13316
27c868c2
MW
13317 /*
13318 * Each ASC-38C1600 function has two connectors. Only an HVD device
13319 * can not be connected to either connector. An LVD device or SE device
13320 * may be connected to either connecor. If an SE device is connected,
13321 * then at most Ultra speed (20 Mhz) can be used on both connectors.
13322 *
13323 * If an HVD device is attached, return an error.
13324 */
13325 if (scsi_cfg1 & HVD) {
13326 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
13327 return ADV_ERROR;
13328 }
1da177e4 13329
27c868c2
MW
13330 /*
13331 * Each function in the ASC-38C1600 uses only the SE cable detect and
13332 * termination because there are two connectors for each function. Each
13333 * function may use either LVD or SE mode. Corresponding the SE automatic
13334 * termination control EEPROM bits are used for each function. Each
13335 * function has its own EEPROM. If SE automatic control is enabled for
13336 * the function, then set the termination value based on a table listed
13337 * in a_condor.h.
13338 *
13339 * If manual termination is specified in the EEPROM for the function,
13340 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
13341 * ready to be 'ored' into SCSI_CFG1.
13342 */
13343 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
13ac2d9c 13344 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2
MW
13345 /* SE automatic termination control is enabled. */
13346 switch (scsi_cfg1 & C_DET_SE) {
13347 /* TERM_SE_HI: on, TERM_SE_LO: on */
13348 case 0x1:
13349 case 0x2:
13350 case 0x3:
13351 asc_dvc->cfg->termination |= TERM_SE;
13352 break;
13353
13354 case 0x0:
13ac2d9c 13355 if (PCI_FUNC(pdev->devfn) == 0) {
27c868c2
MW
13356 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
13357 } else {
13358 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
13359 asc_dvc->cfg->termination |= TERM_SE_HI;
13360 }
13361 break;
13362 }
13363 }
1da177e4 13364
27c868c2
MW
13365 /*
13366 * Clear any set TERM_SE bits.
13367 */
13368 scsi_cfg1 &= ~TERM_SE;
13369
13370 /*
13371 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
13372 */
13373 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
13374
13375 /*
13376 * Clear Big Endian and Terminator Polarity bits and set possibly
13377 * modified termination control bits in the Microcode SCSI_CFG1
13378 * Register Value.
13379 *
13380 * Big Endian bit is not used even on big endian machines.
13381 */
13382 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
13383
13384 /*
13385 * Set SCSI_CFG1 Microcode Default Value
13386 *
13387 * Set possibly modified termination control bits in the Microcode
13388 * SCSI_CFG1 Register Value.
13389 *
13390 * The microcode will set the SCSI_CFG1 register using this value
13391 * after it is started below.
13392 */
13393 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
13394
13395 /*
13396 * Set MEM_CFG Microcode Default Value
13397 *
13398 * The microcode will set the MEM_CFG register using this value
13399 * after it is started below.
13400 *
13401 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
13402 * are defined.
13403 *
13404 * ASC-38C1600 has 32KB internal memory.
13405 *
13406 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
13407 * out a special 16K Adv Library and Microcode version. After the issue
13408 * resolved, we should turn back to the 32K support. Both a_condor.h and
13409 * mcode.sas files also need to be updated.
13410 *
13411 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
13412 * BIOS_EN | RAM_SZ_32KB);
13413 */
13414 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
13415 BIOS_EN | RAM_SZ_16KB);
13416
13417 /*
13418 * Set SEL_MASK Microcode Default Value
13419 *
13420 * The microcode will set the SEL_MASK register using this value
13421 * after it is started below.
13422 */
13423 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
13424 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
13425
a9f4a59a 13426 AdvBuildCarrierFreelist(asc_dvc);
27c868c2
MW
13427
13428 /*
13429 * Set-up the Host->RISC Initiator Command Queue (ICQ).
13430 */
13431 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
13432 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
13433 return ADV_ERROR;
13434 }
13435 asc_dvc->carr_freelist = (ADV_CARR_T *)
13436 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
13437
13438 /*
13439 * The first command issued will be placed in the stopper carrier.
13440 */
13441 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13442
13443 /*
13444 * Set RISC ICQ physical address start value. Initialize the
13445 * COMMA register to the same value otherwise the RISC will
13446 * prematurely detect a command is available.
13447 */
13448 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
13449 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
13450 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
13451
13452 /*
13453 * Set-up the RISC->Host Initiator Response Queue (IRQ).
13454 */
13455 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
13456 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
13457 return ADV_ERROR;
13458 }
13459 asc_dvc->carr_freelist = (ADV_CARR_T *)
13460 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
13461
13462 /*
13463 * The first command completed by the RISC will be placed in
13464 * the stopper.
13465 *
13466 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
13467 * completed the RISC will set the ASC_RQ_STOPPER bit.
13468 */
13469 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13470
13471 /*
13472 * Set RISC IRQ physical address start value.
13473 */
13474 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
13475 asc_dvc->carr_pending_cnt = 0;
13476
13477 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
13478 (ADV_INTR_ENABLE_HOST_INTR |
13479 ADV_INTR_ENABLE_GLOBAL_INTR));
13480 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
13481 AdvWriteWordRegister(iop_base, IOPW_PC, word);
13482
13483 /* finally, finally, gentlemen, start your engine */
13484 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
13485
13486 /*
13487 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
13488 * Resets should be performed. The RISC has to be running
13489 * to issue a SCSI Bus Reset.
13490 */
13491 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
13492 /*
13493 * If the BIOS Signature is present in memory, restore the
13494 * per TID microcode operating variables.
13495 */
13496 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
13497 0x55AA) {
13498 /*
13499 * Restore per TID negotiated values.
13500 */
13501 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13502 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13503 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
13504 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
13505 tagqng_able);
13506 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13507 AdvWriteByteLram(iop_base,
13508 ASC_MC_NUMBER_OF_MAX_CMD + tid,
13509 max_cmd[tid]);
13510 }
13511 } else {
13512 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
13513 warn_code = ASC_WARN_BUSRESET_ERROR;
13514 }
13515 }
13516 }
1da177e4 13517
27c868c2
MW
13518 return warn_code;
13519}
1da177e4 13520
27c868c2
MW
13521/*
13522 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
13523 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
13524 * all of this is done.
13525 *
13526 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13527 *
13528 * For a non-fatal error return a warning code. If there are no warnings
13529 * then 0 is returned.
13530 *
13531 * Note: Chip is stopped on entry.
13532 */
78e77d8b 13533static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
13534{
13535 AdvPortAddr iop_base;
13536 ushort warn_code;
13537 ADVEEP_3550_CONFIG eep_config;
1da177e4 13538
27c868c2 13539 iop_base = asc_dvc->iop_base;
1da177e4 13540
27c868c2 13541 warn_code = 0;
1da177e4 13542
27c868c2
MW
13543 /*
13544 * Read the board's EEPROM configuration.
13545 *
13546 * Set default values if a bad checksum is found.
13547 */
13548 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
13549 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13550
27c868c2
MW
13551 /*
13552 * Set EEPROM default values.
13553 */
d68f4321
MW
13554 memcpy(&eep_config, &Default_3550_EEPROM_Config,
13555 sizeof(ADVEEP_3550_CONFIG));
1da177e4 13556
27c868c2 13557 /*
d68f4321
MW
13558 * Assume the 6 byte board serial number that was read from
13559 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13560 */
13561 eep_config.serial_number_word3 =
13562 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 13563
27c868c2
MW
13564 eep_config.serial_number_word2 =
13565 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 13566
27c868c2
MW
13567 eep_config.serial_number_word1 =
13568 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13569
27c868c2
MW
13570 AdvSet3550EEPConfig(iop_base, &eep_config);
13571 }
13572 /*
13573 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13574 * EEPROM configuration that was read.
13575 *
13576 * This is the mapping of EEPROM fields to Adv Library fields.
13577 */
13578 asc_dvc->wdtr_able = eep_config.wdtr_able;
13579 asc_dvc->sdtr_able = eep_config.sdtr_able;
13580 asc_dvc->ultra_able = eep_config.ultra_able;
13581 asc_dvc->tagqng_able = eep_config.tagqng_able;
13582 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13583 asc_dvc->max_host_qng = eep_config.max_host_qng;
13584 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13585 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13586 asc_dvc->start_motor = eep_config.start_motor;
13587 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13588 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13589 asc_dvc->no_scam = eep_config.scam_tolerant;
13590 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13591 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13592 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13593
13594 /*
13595 * Set the host maximum queuing (max. 253, min. 16) and the per device
13596 * maximum queuing (max. 63, min. 4).
13597 */
13598 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13599 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13600 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13601 /* If the value is zero, assume it is uninitialized. */
13602 if (eep_config.max_host_qng == 0) {
13603 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13604 } else {
13605 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13606 }
13607 }
1da177e4 13608
27c868c2
MW
13609 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13610 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13611 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13612 /* If the value is zero, assume it is uninitialized. */
13613 if (eep_config.max_dvc_qng == 0) {
13614 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13615 } else {
13616 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13617 }
13618 }
1da177e4 13619
27c868c2
MW
13620 /*
13621 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13622 * set 'max_dvc_qng' to 'max_host_qng'.
13623 */
13624 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13625 eep_config.max_dvc_qng = eep_config.max_host_qng;
13626 }
1da177e4 13627
27c868c2
MW
13628 /*
13629 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13630 * values based on possibly adjusted EEPROM values.
13631 */
13632 asc_dvc->max_host_qng = eep_config.max_host_qng;
13633 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13634
13635 /*
13636 * If the EEPROM 'termination' field is set to automatic (0), then set
13637 * the ADV_DVC_CFG 'termination' field to automatic also.
13638 *
13639 * If the termination is specified with a non-zero 'termination'
13640 * value check that a legal value is set and set the ADV_DVC_CFG
13641 * 'termination' field appropriately.
13642 */
13643 if (eep_config.termination == 0) {
13644 asc_dvc->cfg->termination = 0; /* auto termination */
13645 } else {
13646 /* Enable manual control with low off / high off. */
13647 if (eep_config.termination == 1) {
13648 asc_dvc->cfg->termination = TERM_CTL_SEL;
13649
13650 /* Enable manual control with low off / high on. */
13651 } else if (eep_config.termination == 2) {
13652 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
13653
13654 /* Enable manual control with low on / high on. */
13655 } else if (eep_config.termination == 3) {
13656 asc_dvc->cfg->termination =
13657 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
13658 } else {
13659 /*
13660 * The EEPROM 'termination' field contains a bad value. Use
13661 * automatic termination instead.
13662 */
13663 asc_dvc->cfg->termination = 0;
13664 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13665 }
13666 }
1da177e4 13667
27c868c2
MW
13668 return warn_code;
13669}
1da177e4 13670
27c868c2
MW
13671/*
13672 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
13673 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
13674 * all of this is done.
13675 *
13676 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13677 *
13678 * For a non-fatal error return a warning code. If there are no warnings
13679 * then 0 is returned.
13680 *
13681 * Note: Chip is stopped on entry.
13682 */
78e77d8b 13683static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
27c868c2
MW
13684{
13685 AdvPortAddr iop_base;
13686 ushort warn_code;
13687 ADVEEP_38C0800_CONFIG eep_config;
27c868c2
MW
13688 uchar tid, termination;
13689 ushort sdtr_speed = 0;
13690
13691 iop_base = asc_dvc->iop_base;
13692
13693 warn_code = 0;
13694
13695 /*
13696 * Read the board's EEPROM configuration.
13697 *
13698 * Set default values if a bad checksum is found.
13699 */
13700 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
13701 eep_config.check_sum) {
13702 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13703
27c868c2
MW
13704 /*
13705 * Set EEPROM default values.
13706 */
d68f4321
MW
13707 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
13708 sizeof(ADVEEP_38C0800_CONFIG));
1da177e4 13709
27c868c2 13710 /*
d68f4321
MW
13711 * Assume the 6 byte board serial number that was read from
13712 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13713 */
13714 eep_config.serial_number_word3 =
13715 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
1da177e4 13716
27c868c2
MW
13717 eep_config.serial_number_word2 =
13718 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
1da177e4 13719
27c868c2
MW
13720 eep_config.serial_number_word1 =
13721 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13722
27c868c2
MW
13723 AdvSet38C0800EEPConfig(iop_base, &eep_config);
13724 }
13725 /*
13726 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
13727 * EEPROM configuration that was read.
13728 *
13729 * This is the mapping of EEPROM fields to Adv Library fields.
13730 */
13731 asc_dvc->wdtr_able = eep_config.wdtr_able;
13732 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13733 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13734 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13735 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13736 asc_dvc->tagqng_able = eep_config.tagqng_able;
13737 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13738 asc_dvc->max_host_qng = eep_config.max_host_qng;
13739 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13740 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13741 asc_dvc->start_motor = eep_config.start_motor;
13742 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13743 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13744 asc_dvc->no_scam = eep_config.scam_tolerant;
13745 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13746 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13747 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13748
13749 /*
13750 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13751 * are set, then set an 'sdtr_able' bit for it.
13752 */
13753 asc_dvc->sdtr_able = 0;
13754 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13755 if (tid == 0) {
13756 sdtr_speed = asc_dvc->sdtr_speed1;
13757 } else if (tid == 4) {
13758 sdtr_speed = asc_dvc->sdtr_speed2;
13759 } else if (tid == 8) {
13760 sdtr_speed = asc_dvc->sdtr_speed3;
13761 } else if (tid == 12) {
13762 sdtr_speed = asc_dvc->sdtr_speed4;
13763 }
13764 if (sdtr_speed & ADV_MAX_TID) {
13765 asc_dvc->sdtr_able |= (1 << tid);
13766 }
13767 sdtr_speed >>= 4;
13768 }
1da177e4 13769
27c868c2
MW
13770 /*
13771 * Set the host maximum queuing (max. 253, min. 16) and the per device
13772 * maximum queuing (max. 63, min. 4).
13773 */
13774 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13775 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13776 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13777 /* If the value is zero, assume it is uninitialized. */
13778 if (eep_config.max_host_qng == 0) {
13779 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13780 } else {
13781 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13782 }
13783 }
1da177e4 13784
27c868c2
MW
13785 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13786 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13787 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13788 /* If the value is zero, assume it is uninitialized. */
13789 if (eep_config.max_dvc_qng == 0) {
13790 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13791 } else {
13792 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13793 }
13794 }
1da177e4 13795
27c868c2
MW
13796 /*
13797 * If 'max_dvc_qng' is greater than 'max_host_qng', then
13798 * set 'max_dvc_qng' to 'max_host_qng'.
13799 */
13800 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13801 eep_config.max_dvc_qng = eep_config.max_host_qng;
13802 }
1da177e4 13803
27c868c2
MW
13804 /*
13805 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13806 * values based on possibly adjusted EEPROM values.
13807 */
13808 asc_dvc->max_host_qng = eep_config.max_host_qng;
13809 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13810
13811 /*
13812 * If the EEPROM 'termination' field is set to automatic (0), then set
13813 * the ADV_DVC_CFG 'termination' field to automatic also.
13814 *
13815 * If the termination is specified with a non-zero 'termination'
13816 * value check that a legal value is set and set the ADV_DVC_CFG
13817 * 'termination' field appropriately.
13818 */
13819 if (eep_config.termination_se == 0) {
13820 termination = 0; /* auto termination for SE */
13821 } else {
13822 /* Enable manual control with low off / high off. */
13823 if (eep_config.termination_se == 1) {
13824 termination = 0;
13825
13826 /* Enable manual control with low off / high on. */
13827 } else if (eep_config.termination_se == 2) {
13828 termination = TERM_SE_HI;
13829
13830 /* Enable manual control with low on / high on. */
13831 } else if (eep_config.termination_se == 3) {
13832 termination = TERM_SE;
13833 } else {
13834 /*
13835 * The EEPROM 'termination_se' field contains a bad value.
13836 * Use automatic termination instead.
13837 */
13838 termination = 0;
13839 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13840 }
13841 }
1da177e4 13842
27c868c2
MW
13843 if (eep_config.termination_lvd == 0) {
13844 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
13845 } else {
13846 /* Enable manual control with low off / high off. */
13847 if (eep_config.termination_lvd == 1) {
13848 asc_dvc->cfg->termination = termination;
13849
13850 /* Enable manual control with low off / high on. */
13851 } else if (eep_config.termination_lvd == 2) {
13852 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13853
13854 /* Enable manual control with low on / high on. */
13855 } else if (eep_config.termination_lvd == 3) {
13856 asc_dvc->cfg->termination = termination | TERM_LVD;
13857 } else {
13858 /*
13859 * The EEPROM 'termination_lvd' field contains a bad value.
13860 * Use automatic termination instead.
13861 */
13862 asc_dvc->cfg->termination = termination;
13863 warn_code |= ASC_WARN_EEPROM_TERMINATION;
13864 }
13865 }
1da177e4 13866
27c868c2 13867 return warn_code;
1da177e4
LT
13868}
13869
13870/*
27c868c2
MW
13871 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13872 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13873 * all of this is done.
1da177e4
LT
13874 *
13875 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13876 *
13877 * For a non-fatal error return a warning code. If there are no warnings
13878 * then 0 is returned.
13879 *
27c868c2 13880 * Note: Chip is stopped on entry.
1da177e4 13881 */
78e77d8b 13882static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
1da177e4 13883{
27c868c2
MW
13884 AdvPortAddr iop_base;
13885 ushort warn_code;
13886 ADVEEP_38C1600_CONFIG eep_config;
27c868c2
MW
13887 uchar tid, termination;
13888 ushort sdtr_speed = 0;
13889
13890 iop_base = asc_dvc->iop_base;
13891
13892 warn_code = 0;
13893
13894 /*
13895 * Read the board's EEPROM configuration.
13896 *
13897 * Set default values if a bad checksum is found.
13898 */
13899 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13900 eep_config.check_sum) {
13ac2d9c 13901 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
27c868c2 13902 warn_code |= ASC_WARN_EEPROM_CHKSUM;
1da177e4 13903
27c868c2
MW
13904 /*
13905 * Set EEPROM default values.
13906 */
d68f4321
MW
13907 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13908 sizeof(ADVEEP_38C1600_CONFIG));
27c868c2 13909
d68f4321
MW
13910 if (PCI_FUNC(pdev->devfn) != 0) {
13911 u8 ints;
13912 /*
13913 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13914 * and old Mac system booting problem. The Expansion
13915 * ROM must be disabled in Function 1 for these systems
13916 */
13917 eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13918 /*
13919 * Clear the INTAB (bit 11) if the GPIO 0 input
13920 * indicates the Function 1 interrupt line is wired
13921 * to INTB.
13922 *
13923 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13924 * 1 - Function 1 interrupt line wired to INT A.
13925 * 0 - Function 1 interrupt line wired to INT B.
13926 *
13927 * Note: Function 0 is always wired to INTA.
13928 * Put all 5 GPIO bits in input mode and then read
13929 * their input values.
13930 */
13931 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13932 ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13933 if ((ints & 0x01) == 0)
13934 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
27c868c2 13935 }
1da177e4 13936
27c868c2 13937 /*
d68f4321
MW
13938 * Assume the 6 byte board serial number that was read from
13939 * EEPROM is correct even if the EEPROM checksum failed.
27c868c2
MW
13940 */
13941 eep_config.serial_number_word3 =
d68f4321 13942 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
27c868c2 13943 eep_config.serial_number_word2 =
d68f4321 13944 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
27c868c2 13945 eep_config.serial_number_word1 =
d68f4321 13946 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
1da177e4 13947
27c868c2
MW
13948 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13949 }
1da177e4 13950
27c868c2
MW
13951 /*
13952 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13953 * EEPROM configuration that was read.
13954 *
13955 * This is the mapping of EEPROM fields to Adv Library fields.
13956 */
13957 asc_dvc->wdtr_able = eep_config.wdtr_able;
13958 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13959 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13960 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13961 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13962 asc_dvc->ppr_able = 0;
13963 asc_dvc->tagqng_able = eep_config.tagqng_able;
13964 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13965 asc_dvc->max_host_qng = eep_config.max_host_qng;
13966 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13967 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13968 asc_dvc->start_motor = eep_config.start_motor;
13969 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13970 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13971 asc_dvc->no_scam = eep_config.scam_tolerant;
13972
13973 /*
13974 * For every Target ID if any of its 'sdtr_speed[1234]' bits
13975 * are set, then set an 'sdtr_able' bit for it.
13976 */
13977 asc_dvc->sdtr_able = 0;
13978 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13979 if (tid == 0) {
13980 sdtr_speed = asc_dvc->sdtr_speed1;
13981 } else if (tid == 4) {
13982 sdtr_speed = asc_dvc->sdtr_speed2;
13983 } else if (tid == 8) {
13984 sdtr_speed = asc_dvc->sdtr_speed3;
13985 } else if (tid == 12) {
13986 sdtr_speed = asc_dvc->sdtr_speed4;
13987 }
13988 if (sdtr_speed & ASC_MAX_TID) {
13989 asc_dvc->sdtr_able |= (1 << tid);
13990 }
13991 sdtr_speed >>= 4;
13992 }
1da177e4 13993
27c868c2
MW
13994 /*
13995 * Set the host maximum queuing (max. 253, min. 16) and the per device
13996 * maximum queuing (max. 63, min. 4).
13997 */
13998 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13999 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14000 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
14001 /* If the value is zero, assume it is uninitialized. */
14002 if (eep_config.max_host_qng == 0) {
14003 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14004 } else {
14005 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
14006 }
14007 }
1da177e4 14008
27c868c2
MW
14009 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
14010 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14011 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
14012 /* If the value is zero, assume it is uninitialized. */
14013 if (eep_config.max_dvc_qng == 0) {
14014 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14015 } else {
14016 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
14017 }
14018 }
1da177e4 14019
27c868c2
MW
14020 /*
14021 * If 'max_dvc_qng' is greater than 'max_host_qng', then
14022 * set 'max_dvc_qng' to 'max_host_qng'.
14023 */
14024 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
14025 eep_config.max_dvc_qng = eep_config.max_host_qng;
14026 }
1da177e4 14027
27c868c2
MW
14028 /*
14029 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
14030 * values based on possibly adjusted EEPROM values.
14031 */
14032 asc_dvc->max_host_qng = eep_config.max_host_qng;
14033 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14034
14035 /*
14036 * If the EEPROM 'termination' field is set to automatic (0), then set
14037 * the ASC_DVC_CFG 'termination' field to automatic also.
14038 *
14039 * If the termination is specified with a non-zero 'termination'
14040 * value check that a legal value is set and set the ASC_DVC_CFG
14041 * 'termination' field appropriately.
14042 */
14043 if (eep_config.termination_se == 0) {
14044 termination = 0; /* auto termination for SE */
14045 } else {
14046 /* Enable manual control with low off / high off. */
14047 if (eep_config.termination_se == 1) {
14048 termination = 0;
14049
14050 /* Enable manual control with low off / high on. */
14051 } else if (eep_config.termination_se == 2) {
14052 termination = TERM_SE_HI;
14053
14054 /* Enable manual control with low on / high on. */
14055 } else if (eep_config.termination_se == 3) {
14056 termination = TERM_SE;
14057 } else {
14058 /*
14059 * The EEPROM 'termination_se' field contains a bad value.
14060 * Use automatic termination instead.
14061 */
14062 termination = 0;
14063 warn_code |= ASC_WARN_EEPROM_TERMINATION;
14064 }
14065 }
1da177e4 14066
27c868c2
MW
14067 if (eep_config.termination_lvd == 0) {
14068 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
14069 } else {
14070 /* Enable manual control with low off / high off. */
14071 if (eep_config.termination_lvd == 1) {
14072 asc_dvc->cfg->termination = termination;
14073
14074 /* Enable manual control with low off / high on. */
14075 } else if (eep_config.termination_lvd == 2) {
14076 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
14077
14078 /* Enable manual control with low on / high on. */
14079 } else if (eep_config.termination_lvd == 3) {
14080 asc_dvc->cfg->termination = termination | TERM_LVD;
14081 } else {
14082 /*
14083 * The EEPROM 'termination_lvd' field contains a bad value.
14084 * Use automatic termination instead.
14085 */
14086 asc_dvc->cfg->termination = termination;
14087 warn_code |= ASC_WARN_EEPROM_TERMINATION;
14088 }
14089 }
1da177e4 14090
27c868c2 14091 return warn_code;
1da177e4
LT
14092}
14093
14094/*
14095 * Read EEPROM configuration into the specified buffer.
14096 *
14097 * Return a checksum based on the EEPROM configuration read.
14098 */
78e77d8b 14099static ushort __devinit
1da177e4
LT
14100AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
14101{
27c868c2
MW
14102 ushort wval, chksum;
14103 ushort *wbuf;
14104 int eep_addr;
14105 ushort *charfields;
14106
14107 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
14108 wbuf = (ushort *)cfg_buf;
14109 chksum = 0;
14110
14111 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
14112 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
14113 wval = AdvReadEEPWord(iop_base, eep_addr);
14114 chksum += wval; /* Checksum is calculated from word values. */
14115 if (*charfields++) {
14116 *wbuf = le16_to_cpu(wval);
14117 } else {
14118 *wbuf = wval;
14119 }
14120 }
14121 /* Read checksum word. */
14122 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14123 wbuf++;
14124 charfields++;
14125
14126 /* Read rest of EEPROM not covered by the checksum. */
14127 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
14128 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
14129 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14130 if (*charfields++) {
14131 *wbuf = le16_to_cpu(*wbuf);
14132 }
14133 }
14134 return chksum;
1da177e4
LT
14135}
14136
14137/*
14138 * Read EEPROM configuration into the specified buffer.
14139 *
14140 * Return a checksum based on the EEPROM configuration read.
14141 */
78e77d8b 14142static ushort __devinit
27c868c2 14143AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 14144{
27c868c2
MW
14145 ushort wval, chksum;
14146 ushort *wbuf;
14147 int eep_addr;
14148 ushort *charfields;
14149
14150 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
14151 wbuf = (ushort *)cfg_buf;
14152 chksum = 0;
14153
14154 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
14155 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
14156 wval = AdvReadEEPWord(iop_base, eep_addr);
14157 chksum += wval; /* Checksum is calculated from word values. */
14158 if (*charfields++) {
14159 *wbuf = le16_to_cpu(wval);
14160 } else {
14161 *wbuf = wval;
14162 }
14163 }
14164 /* Read checksum word. */
14165 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14166 wbuf++;
14167 charfields++;
14168
14169 /* Read rest of EEPROM not covered by the checksum. */
14170 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
14171 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
14172 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14173 if (*charfields++) {
14174 *wbuf = le16_to_cpu(*wbuf);
14175 }
14176 }
14177 return chksum;
1da177e4
LT
14178}
14179
14180/*
14181 * Read EEPROM configuration into the specified buffer.
14182 *
14183 * Return a checksum based on the EEPROM configuration read.
14184 */
78e77d8b 14185static ushort __devinit
27c868c2 14186AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 14187{
27c868c2
MW
14188 ushort wval, chksum;
14189 ushort *wbuf;
14190 int eep_addr;
14191 ushort *charfields;
14192
14193 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
14194 wbuf = (ushort *)cfg_buf;
14195 chksum = 0;
14196
14197 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
14198 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
14199 wval = AdvReadEEPWord(iop_base, eep_addr);
14200 chksum += wval; /* Checksum is calculated from word values. */
14201 if (*charfields++) {
14202 *wbuf = le16_to_cpu(wval);
14203 } else {
14204 *wbuf = wval;
14205 }
14206 }
14207 /* Read checksum word. */
14208 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14209 wbuf++;
14210 charfields++;
14211
14212 /* Read rest of EEPROM not covered by the checksum. */
14213 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
14214 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
14215 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
14216 if (*charfields++) {
14217 *wbuf = le16_to_cpu(*wbuf);
14218 }
14219 }
14220 return chksum;
1da177e4
LT
14221}
14222
14223/*
14224 * Read the EEPROM from specified location
14225 */
78e77d8b 14226static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
1da177e4 14227{
27c868c2
MW
14228 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14229 ASC_EEP_CMD_READ | eep_word_addr);
14230 AdvWaitEEPCmd(iop_base);
14231 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
1da177e4
LT
14232}
14233
14234/*
14235 * Wait for EEPROM command to complete
14236 */
78e77d8b 14237static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
1da177e4 14238{
27c868c2
MW
14239 int eep_delay_ms;
14240
14241 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
14242 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
14243 ASC_EEP_CMD_DONE) {
14244 break;
14245 }
14246 DvcSleepMilliSecond(1);
14247 }
14248 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
14249 0) {
14250 ASC_ASSERT(0);
14251 }
14252 return;
1da177e4
LT
14253}
14254
14255/*
14256 * Write the EEPROM from 'cfg_buf'.
14257 */
78e77d8b 14258void __devinit
1da177e4
LT
14259AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
14260{
27c868c2
MW
14261 ushort *wbuf;
14262 ushort addr, chksum;
14263 ushort *charfields;
14264
14265 wbuf = (ushort *)cfg_buf;
14266 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
14267 chksum = 0;
14268
14269 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
14270 AdvWaitEEPCmd(iop_base);
14271
14272 /*
14273 * Write EEPROM from word 0 to word 20.
14274 */
14275 for (addr = ADV_EEP_DVC_CFG_BEGIN;
14276 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
14277 ushort word;
14278
14279 if (*charfields++) {
14280 word = cpu_to_le16(*wbuf);
14281 } else {
14282 word = *wbuf;
14283 }
14284 chksum += *wbuf; /* Checksum is calculated from word values. */
14285 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
14286 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14287 ASC_EEP_CMD_WRITE | addr);
14288 AdvWaitEEPCmd(iop_base);
14289 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
14290 }
1da177e4 14291
27c868c2
MW
14292 /*
14293 * Write EEPROM checksum at word 21.
14294 */
14295 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
14296 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
14297 AdvWaitEEPCmd(iop_base);
14298 wbuf++;
14299 charfields++;
14300
14301 /*
14302 * Write EEPROM OEM name at words 22 to 29.
14303 */
14304 for (addr = ADV_EEP_DVC_CTL_BEGIN;
14305 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
14306 ushort word;
14307
14308 if (*charfields++) {
14309 word = cpu_to_le16(*wbuf);
14310 } else {
14311 word = *wbuf;
14312 }
14313 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
14314 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14315 ASC_EEP_CMD_WRITE | addr);
14316 AdvWaitEEPCmd(iop_base);
14317 }
14318 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
14319 AdvWaitEEPCmd(iop_base);
14320 return;
1da177e4
LT
14321}
14322
14323/*
14324 * Write the EEPROM from 'cfg_buf'.
14325 */
78e77d8b 14326void __devinit
27c868c2 14327AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
1da177e4 14328{
27c868c2
MW
14329 ushort *wbuf;
14330 ushort *charfields;
14331 ushort addr, chksum;
14332
14333 wbuf = (ushort *)cfg_buf;
14334 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
14335 chksum = 0;
14336
14337 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
14338 AdvWaitEEPCmd(iop_base);
14339
14340 /*
14341 * Write EEPROM from word 0 to word 20.
14342 */
14343 for (addr = ADV_EEP_DVC_CFG_BEGIN;
14344 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
14345 ushort word;
14346
14347 if (*charfields++) {
14348 word = cpu_to_le16(*wbuf);
14349 } else {
14350 word = *wbuf;
14351 }
14352 chksum += *wbuf; /* Checksum is calculated from word values. */
14353 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
14354 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14355 ASC_EEP_CMD_WRITE | addr);
14356 AdvWaitEEPCmd(iop_base);
14357 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
14358 }
1da177e4 14359
27c868c2
MW
14360 /*
14361 * Write EEPROM checksum at word 21.
14362 */
14363 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
14364 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
14365 AdvWaitEEPCmd(iop_base);
14366 wbuf++;
14367 charfields++;
14368
14369 /*
14370 * Write EEPROM OEM name at words 22 to 29.
14371 */
14372 for (addr = ADV_EEP_DVC_CTL_BEGIN;
14373 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
14374 ushort word;
14375
14376 if (*charfields++) {
14377 word = cpu_to_le16(*wbuf);
14378 } else {
14379 word = *wbuf;
14380 }
14381 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
14382 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14383 ASC_EEP_CMD_WRITE | addr);
14384 AdvWaitEEPCmd(iop_base);
14385 }
14386 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
14387 AdvWaitEEPCmd(iop_base);
14388 return;
1da177e4
LT
14389}
14390
14391/*
14392 * Write the EEPROM from 'cfg_buf'.
14393 */
78e77d8b 14394void __devinit
27c868c2 14395AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
1da177e4 14396{
27c868c2
MW
14397 ushort *wbuf;
14398 ushort *charfields;
14399 ushort addr, chksum;
14400
14401 wbuf = (ushort *)cfg_buf;
14402 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
14403 chksum = 0;
14404
14405 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
14406 AdvWaitEEPCmd(iop_base);
14407
14408 /*
14409 * Write EEPROM from word 0 to word 20.
14410 */
14411 for (addr = ADV_EEP_DVC_CFG_BEGIN;
14412 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
14413 ushort word;
14414
14415 if (*charfields++) {
14416 word = cpu_to_le16(*wbuf);
14417 } else {
14418 word = *wbuf;
14419 }
14420 chksum += *wbuf; /* Checksum is calculated from word values. */
14421 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
14422 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14423 ASC_EEP_CMD_WRITE | addr);
14424 AdvWaitEEPCmd(iop_base);
14425 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
14426 }
1da177e4 14427
27c868c2
MW
14428 /*
14429 * Write EEPROM checksum at word 21.
14430 */
14431 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
14432 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
14433 AdvWaitEEPCmd(iop_base);
14434 wbuf++;
14435 charfields++;
14436
14437 /*
14438 * Write EEPROM OEM name at words 22 to 29.
14439 */
14440 for (addr = ADV_EEP_DVC_CTL_BEGIN;
14441 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
14442 ushort word;
14443
14444 if (*charfields++) {
14445 word = cpu_to_le16(*wbuf);
14446 } else {
14447 word = *wbuf;
14448 }
14449 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
14450 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
14451 ASC_EEP_CMD_WRITE | addr);
14452 AdvWaitEEPCmd(iop_base);
14453 }
14454 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
14455 AdvWaitEEPCmd(iop_base);
14456 return;
1da177e4
LT
14457}
14458
14459/* a_advlib.c */
14460/*
14461 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
14462 *
14463 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
14464 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
14465 * RISC to notify it a new command is ready to be executed.
14466 *
14467 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
14468 * set to SCSI_MAX_RETRY.
14469 *
14470 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
14471 * for DMA addresses or math operations are byte swapped to little-endian
14472 * order.
14473 *
14474 * Return:
14475 * ADV_SUCCESS(1) - The request was successfully queued.
14476 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
14477 * request completes.
14478 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
14479 * host IC error.
14480 */
27c868c2 14481static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
1da177e4 14482{
27c868c2
MW
14483 ulong last_int_level;
14484 AdvPortAddr iop_base;
14485 ADV_DCNT req_size;
14486 ADV_PADDR req_paddr;
14487 ADV_CARR_T *new_carrp;
14488
14489 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
14490
14491 /*
14492 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
14493 */
14494 if (scsiq->target_id > ADV_MAX_TID) {
14495 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
14496 scsiq->done_status = QD_WITH_ERROR;
14497 return ADV_ERROR;
14498 }
1da177e4 14499
27c868c2 14500 iop_base = asc_dvc->iop_base;
1da177e4 14501
27c868c2 14502 last_int_level = DvcEnterCritical();
1da177e4 14503
27c868c2
MW
14504 /*
14505 * Allocate a carrier ensuring at least one carrier always
14506 * remains on the freelist and initialize fields.
14507 */
14508 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
14509 DvcLeaveCritical(last_int_level);
14510 return ADV_BUSY;
14511 }
14512 asc_dvc->carr_freelist = (ADV_CARR_T *)
14513 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
14514 asc_dvc->carr_pending_cnt++;
14515
14516 /*
14517 * Set the carrier to be a stopper by setting 'next_vpa'
14518 * to the stopper value. The current stopper will be changed
14519 * below to point to the new stopper.
14520 */
14521 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14522
14523 /*
14524 * Clear the ADV_SCSI_REQ_Q done flag.
14525 */
14526 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
14527
14528 req_size = sizeof(ADV_SCSI_REQ_Q);
14529 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
14530 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
14531
14532 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
14533 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
14534
14535 /* Wait for assertion before making little-endian */
14536 req_paddr = cpu_to_le32(req_paddr);
14537
14538 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
14539 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
14540 scsiq->scsiq_rptr = req_paddr;
14541
14542 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
14543 /*
14544 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
14545 * order during initialization.
14546 */
14547 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
14548
14549 /*
14550 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
14551 * the microcode. The newly allocated stopper will become the new
14552 * stopper.
14553 */
14554 asc_dvc->icq_sp->areq_vpa = req_paddr;
14555
14556 /*
14557 * Set the 'next_vpa' pointer for the old stopper to be the
14558 * physical address of the new stopper. The RISC can only
14559 * follow physical addresses.
14560 */
14561 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
14562
14563 /*
14564 * Set the host adapter stopper pointer to point to the new carrier.
14565 */
14566 asc_dvc->icq_sp = new_carrp;
14567
14568 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
14569 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14570 /*
14571 * Tickle the RISC to tell it to read its Command Queue Head pointer.
14572 */
14573 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
14574 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14575 /*
14576 * Clear the tickle value. In the ASC-3550 the RISC flag
14577 * command 'clr_tickle_a' does not work unless the host
14578 * value is cleared.
14579 */
14580 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
14581 ADV_TICKLE_NOP);
14582 }
14583 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14584 /*
14585 * Notify the RISC a carrier is ready by writing the physical
14586 * address of the new carrier stopper to the COMMA register.
14587 */
14588 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
14589 le32_to_cpu(new_carrp->carr_pa));
14590 }
1da177e4 14591
27c868c2 14592 DvcLeaveCritical(last_int_level);
1da177e4 14593
27c868c2 14594 return ADV_SUCCESS;
1da177e4
LT
14595}
14596
14597/*
14598 * Reset SCSI Bus and purge all outstanding requests.
14599 *
14600 * Return Value:
14601 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
14602 * ADV_FALSE(0) - Microcode command failed.
14603 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
14604 * may be hung which requires driver recovery.
14605 */
27c868c2 14606static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
1da177e4 14607{
27c868c2
MW
14608 int status;
14609
14610 /*
14611 * Send the SCSI Bus Reset idle start idle command which asserts
14612 * the SCSI Bus Reset signal.
14613 */
14614 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
14615 if (status != ADV_TRUE) {
14616 return status;
14617 }
1da177e4 14618
27c868c2
MW
14619 /*
14620 * Delay for the specified SCSI Bus Reset hold time.
14621 *
14622 * The hold time delay is done on the host because the RISC has no
14623 * microsecond accurate timer.
14624 */
14625 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
14626
14627 /*
14628 * Send the SCSI Bus Reset end idle command which de-asserts
14629 * the SCSI Bus Reset signal and purges any pending requests.
14630 */
14631 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
14632 if (status != ADV_TRUE) {
14633 return status;
14634 }
14635
14636 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
1da177e4 14637
27c868c2 14638 return status;
1da177e4
LT
14639}
14640
14641/*
14642 * Reset chip and SCSI Bus.
14643 *
14644 * Return Value:
14645 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
14646 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
14647 */
27c868c2 14648static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
1da177e4 14649{
27c868c2
MW
14650 int status;
14651 ushort wdtr_able, sdtr_able, tagqng_able;
14652 ushort ppr_able = 0;
14653 uchar tid, max_cmd[ADV_MAX_TID + 1];
14654 AdvPortAddr iop_base;
14655 ushort bios_sig;
14656
14657 iop_base = asc_dvc->iop_base;
14658
14659 /*
14660 * Save current per TID negotiated values.
14661 */
14662 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14663 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14664 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14665 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14666 }
14667 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14668 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14669 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14670 max_cmd[tid]);
14671 }
1da177e4 14672
27c868c2
MW
14673 /*
14674 * Force the AdvInitAsc3550/38C0800Driver() function to
14675 * perform a SCSI Bus Reset by clearing the BIOS signature word.
14676 * The initialization functions assumes a SCSI Bus Reset is not
14677 * needed if the BIOS signature word is present.
14678 */
14679 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
14680 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
14681
14682 /*
14683 * Stop chip and reset it.
14684 */
14685 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
14686 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
14687 DvcSleepMilliSecond(100);
14688 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14689 ADV_CTRL_REG_CMD_WR_IO_REG);
14690
14691 /*
14692 * Reset Adv Library error code, if any, and try
14693 * re-initializing the chip.
14694 */
14695 asc_dvc->err_code = 0;
14696 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14697 status = AdvInitAsc38C1600Driver(asc_dvc);
14698 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14699 status = AdvInitAsc38C0800Driver(asc_dvc);
14700 } else {
14701 status = AdvInitAsc3550Driver(asc_dvc);
14702 }
1da177e4 14703
27c868c2
MW
14704 /* Translate initialization return value to status value. */
14705 if (status == 0) {
14706 status = ADV_TRUE;
14707 } else {
14708 status = ADV_FALSE;
14709 }
1da177e4 14710
27c868c2
MW
14711 /*
14712 * Restore the BIOS signature word.
14713 */
14714 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
14715
14716 /*
14717 * Restore per TID negotiated values.
14718 */
14719 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14720 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14721 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14722 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14723 }
14724 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14725 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14726 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14727 max_cmd[tid]);
14728 }
1da177e4 14729
27c868c2 14730 return status;
1da177e4
LT
14731}
14732
14733/*
14734 * Adv Library Interrupt Service Routine
14735 *
14736 * This function is called by a driver's interrupt service routine.
14737 * The function disables and re-enables interrupts.
14738 *
14739 * When a microcode idle command is completed, the ADV_DVC_VAR
14740 * 'idle_cmd_done' field is set to ADV_TRUE.
14741 *
14742 * Note: AdvISR() can be called when interrupts are disabled or even
14743 * when there is no hardware interrupt condition present. It will
14744 * always check for completed idle commands and microcode requests.
14745 * This is an important feature that shouldn't be changed because it
14746 * allows commands to be completed from polling mode loops.
14747 *
14748 * Return:
14749 * ADV_TRUE(1) - interrupt was pending
14750 * ADV_FALSE(0) - no interrupt was pending
14751 */
27c868c2 14752static int AdvISR(ADV_DVC_VAR *asc_dvc)
1da177e4 14753{
27c868c2
MW
14754 AdvPortAddr iop_base;
14755 uchar int_stat;
14756 ushort target_bit;
14757 ADV_CARR_T *free_carrp;
14758 ADV_VADDR irq_next_vpa;
14759 int flags;
14760 ADV_SCSI_REQ_Q *scsiq;
1da177e4 14761
27c868c2 14762 flags = DvcEnterCritical();
1da177e4 14763
27c868c2
MW
14764 iop_base = asc_dvc->iop_base;
14765
14766 /* Reading the register clears the interrupt. */
14767 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
14768
14769 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
14770 ADV_INTR_STATUS_INTRC)) == 0) {
14771 DvcLeaveCritical(flags);
14772 return ADV_FALSE;
14773 }
14774
14775 /*
14776 * Notify the driver of an asynchronous microcode condition by
895d6b4c 14777 * calling the adv_async_callback function. The function
27c868c2
MW
14778 * is passed the microcode ASC_MC_INTRB_CODE byte value.
14779 */
14780 if (int_stat & ADV_INTR_STATUS_INTRB) {
14781 uchar intrb_code;
14782
14783 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
14784
14785 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
14786 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14787 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
14788 asc_dvc->carr_pending_cnt != 0) {
14789 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
14790 ADV_TICKLE_A);
14791 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14792 AdvWriteByteRegister(iop_base,
14793 IOPB_TICKLE,
14794 ADV_TICKLE_NOP);
14795 }
14796 }
14797 }
14798
895d6b4c 14799 adv_async_callback(asc_dvc, intrb_code);
27c868c2
MW
14800 }
14801
14802 /*
14803 * Check if the IRQ stopper carrier contains a completed request.
14804 */
14805 while (((irq_next_vpa =
14806 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
14807 /*
14808 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
14809 * The RISC will have set 'areq_vpa' to a virtual address.
14810 *
14811 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
14812 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
14813 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
14814 * in AdvExeScsiQueue().
14815 */
14816 scsiq = (ADV_SCSI_REQ_Q *)
14817 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
14818
14819 /*
14820 * Request finished with good status and the queue was not
14821 * DMAed to host memory by the firmware. Set all status fields
14822 * to indicate good status.
14823 */
14824 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
14825 scsiq->done_status = QD_NO_ERROR;
14826 scsiq->host_status = scsiq->scsi_status = 0;
14827 scsiq->data_cnt = 0L;
14828 }
14829
14830 /*
14831 * Advance the stopper pointer to the next carrier
14832 * ignoring the lower four bits. Free the previous
14833 * stopper carrier.
14834 */
14835 free_carrp = asc_dvc->irq_sp;
14836 asc_dvc->irq_sp = (ADV_CARR_T *)
14837 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
14838
14839 free_carrp->next_vpa =
14840 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14841 asc_dvc->carr_freelist = free_carrp;
14842 asc_dvc->carr_pending_cnt--;
14843
14844 ASC_ASSERT(scsiq != NULL);
14845 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
14846
14847 /*
14848 * Clear request microcode control flag.
14849 */
14850 scsiq->cntl = 0;
14851
27c868c2
MW
14852 /*
14853 * Notify the driver of the completed request by passing
14854 * the ADV_SCSI_REQ_Q pointer to its callback function.
14855 */
14856 scsiq->a_flag |= ADV_SCSIQ_DONE;
895d6b4c 14857 adv_isr_callback(asc_dvc, scsiq);
27c868c2
MW
14858 /*
14859 * Note: After the driver callback function is called, 'scsiq'
14860 * can no longer be referenced.
14861 *
14862 * Fall through and continue processing other completed
14863 * requests...
14864 */
14865
14866 /*
14867 * Disable interrupts again in case the driver inadvertently
14868 * enabled interrupts in its callback function.
14869 *
14870 * The DvcEnterCritical() return value is ignored, because
14871 * the 'flags' saved when AdvISR() was first entered will be
14872 * used to restore the interrupt flag on exit.
14873 */
14874 (void)DvcEnterCritical();
14875 }
14876 DvcLeaveCritical(flags);
14877 return ADV_TRUE;
1da177e4
LT
14878}
14879
14880/*
14881 * Send an idle command to the chip and wait for completion.
14882 *
14883 * Command completion is polled for once per microsecond.
14884 *
14885 * The function can be called from anywhere including an interrupt handler.
14886 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
14887 * functions to prevent reentrancy.
14888 *
14889 * Return Values:
14890 * ADV_TRUE - command completed successfully
14891 * ADV_FALSE - command failed
14892 * ADV_ERROR - command timed out
14893 */
27c868c2 14894static int
1da177e4 14895AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
27c868c2 14896 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
1da177e4 14897{
27c868c2
MW
14898 ulong last_int_level;
14899 int result;
14900 ADV_DCNT i, j;
14901 AdvPortAddr iop_base;
14902
14903 last_int_level = DvcEnterCritical();
14904
14905 iop_base = asc_dvc->iop_base;
14906
14907 /*
14908 * Clear the idle command status which is set by the microcode
14909 * to a non-zero value to indicate when the command is completed.
14910 * The non-zero result is one of the IDLE_CMD_STATUS_* values
14911 * defined in a_advlib.h.
14912 */
14913 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
14914
14915 /*
14916 * Write the idle command value after the idle command parameter
14917 * has been written to avoid a race condition. If the order is not
14918 * followed, the microcode may process the idle command before the
14919 * parameters have been written to LRAM.
14920 */
14921 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
14922 cpu_to_le32(idle_cmd_parameter));
14923 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
14924
14925 /*
14926 * Tickle the RISC to tell it to process the idle command.
14927 */
14928 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
14929 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
14930 /*
14931 * Clear the tickle value. In the ASC-3550 the RISC flag
14932 * command 'clr_tickle_b' does not work unless the host
14933 * value is cleared.
14934 */
14935 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
14936 }
1da177e4 14937
27c868c2
MW
14938 /* Wait for up to 100 millisecond for the idle command to timeout. */
14939 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
14940 /* Poll once each microsecond for command completion. */
14941 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
14942 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
14943 result);
14944 if (result != 0) {
14945 DvcLeaveCritical(last_int_level);
14946 return result;
14947 }
14948 DvcDelayMicroSecond(asc_dvc, (ushort)1);
14949 }
14950 }
1da177e4 14951
27c868c2
MW
14952 ASC_ASSERT(0); /* The idle command should never timeout. */
14953 DvcLeaveCritical(last_int_level);
14954 return ADV_ERROR;
1da177e4
LT
14955}
14956
b2c16f58
MW
14957static int __devinit
14958advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
14959{
14960 int req_cnt = 0;
14961 adv_req_t *reqp = NULL;
14962 int sg_cnt = 0;
14963 adv_sgblk_t *sgp;
14964 int warn_code, err_code;
14965
14966 /*
14967 * Allocate buffer carrier structures. The total size
14968 * is about 4 KB, so allocate all at once.
14969 */
14970 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
14971 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
14972
14973 if (!boardp->carrp)
14974 goto kmalloc_failed;
14975
14976 /*
14977 * Allocate up to 'max_host_qng' request structures for the Wide
14978 * board. The total size is about 16 KB, so allocate all at once.
14979 * If the allocation fails decrement and try again.
14980 */
14981 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
14982 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
14983
14984 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
14985 "bytes %lu\n", reqp, req_cnt,
14986 (ulong)sizeof(adv_req_t) * req_cnt);
14987
14988 if (reqp)
14989 break;
14990 }
14991
14992 if (!reqp)
14993 goto kmalloc_failed;
14994
14995 boardp->orig_reqp = reqp;
14996
14997 /*
14998 * Allocate up to ADV_TOT_SG_BLOCK request structures for
14999 * the Wide board. Each structure is about 136 bytes.
15000 */
15001 boardp->adv_sgblkp = NULL;
15002 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
15003 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
15004
15005 if (!sgp)
15006 break;
15007
15008 sgp->next_sgblkp = boardp->adv_sgblkp;
15009 boardp->adv_sgblkp = sgp;
15010
15011 }
15012
15013 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
15014 sg_cnt, sizeof(adv_sgblk_t),
15015 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
15016
15017 if (!boardp->adv_sgblkp)
15018 goto kmalloc_failed;
15019
15020 adv_dvc_varp->carrier_buf = boardp->carrp;
15021
15022 /*
15023 * Point 'adv_reqp' to the request structures and
15024 * link them together.
15025 */
15026 req_cnt--;
15027 reqp[req_cnt].next_reqp = NULL;
15028 for (; req_cnt > 0; req_cnt--) {
15029 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
15030 }
15031 boardp->adv_reqp = &reqp[0];
15032
15033 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
15034 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
15035 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
15036 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
15037 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
15038 "\n");
15039 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
15040 } else {
15041 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
15042 "\n");
15043 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
15044 }
15045 err_code = adv_dvc_varp->err_code;
15046
15047 if (warn_code || err_code) {
15048 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
15049 " error 0x%x\n", boardp->id, warn_code, err_code);
15050 }
15051
15052 goto exit;
15053
15054 kmalloc_failed:
15055 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
15056 "failed\n", boardp->id);
15057 err_code = ADV_ERROR;
15058 exit:
15059 return err_code;
15060}
15061
15062static void advansys_wide_free_mem(asc_board_t *boardp)
15063{
15064 kfree(boardp->carrp);
15065 boardp->carrp = NULL;
15066 kfree(boardp->orig_reqp);
15067 boardp->orig_reqp = boardp->adv_reqp = NULL;
15068 while (boardp->adv_sgblkp) {
15069 adv_sgblk_t *sgp = boardp->adv_sgblkp;
15070 boardp->adv_sgblkp = sgp->next_sgblkp;
15071 kfree(sgp);
15072 }
15073}
15074
27c868c2
MW
15075static struct Scsi_Host *__devinit
15076advansys_board_found(int iop, struct device *dev, int bus_type)
15077{
15078 struct Scsi_Host *shost;
15079 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
15080 asc_board_t *boardp;
15081 ASC_DVC_VAR *asc_dvc_varp = NULL;
15082 ADV_DVC_VAR *adv_dvc_varp = NULL;
074c8fe4 15083 int share_irq;
27c868c2
MW
15084 int warn_code, err_code;
15085 int ret;
15086
15087 /*
27c868c2
MW
15088 * Register the adapter, get its configuration, and
15089 * initialize it.
15090 */
8dfb5379
MW
15091 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
15092 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
27c868c2
MW
15093 if (!shost)
15094 return NULL;
15095
27c868c2
MW
15096 /* Initialize private per board data */
15097 boardp = ASC_BOARDP(shost);
15098 memset(boardp, 0, sizeof(asc_board_t));
78e77d8b 15099 boardp->id = asc_board_count++;
27c868c2 15100 spin_lock_init(&boardp->lock);
394dbf3f 15101 boardp->dev = dev;
27c868c2
MW
15102
15103 /*
15104 * Handle both narrow and wide boards.
15105 *
15106 * If a Wide board was detected, set the board structure
15107 * wide board flag. Set-up the board structure based on
15108 * the board type.
15109 */
15110#ifdef CONFIG_PCI
15111 if (bus_type == ASC_IS_PCI &&
15112 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
15113 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
15114 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
15115 boardp->flags |= ASC_IS_WIDE_BOARD;
15116 }
15117#endif /* CONFIG_PCI */
15118
15119 if (ASC_NARROW_BOARD(boardp)) {
15120 ASC_DBG(1, "advansys_board_found: narrow board\n");
15121 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
15122 asc_dvc_varp->bus_type = bus_type;
15123 asc_dvc_varp->drv_ptr = boardp;
15124 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
15125 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
15126 asc_dvc_varp->iop_base = iop;
27c868c2 15127 } else {
57ba5fe9 15128#ifdef CONFIG_PCI
27c868c2
MW
15129 ASC_DBG(1, "advansys_board_found: wide board\n");
15130 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
15131 adv_dvc_varp->drv_ptr = boardp;
15132 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
27c868c2
MW
15133 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
15134 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
15135 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
15136 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
15137 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
15138 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
15139 } else {
15140 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
15141 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
15142 }
27c868c2 15143
57ba5fe9
MW
15144 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
15145 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
15146 boardp->asc_n_io_port);
15147 if (!boardp->ioremap_addr) {
27c868c2
MW
15148 ASC_PRINT3
15149 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
57ba5fe9
MW
15150 boardp->id, pci_resource_start(pdev, 1),
15151 boardp->asc_n_io_port);
b2c16f58 15152 goto err_shost;
27c868c2 15153 }
57ba5fe9 15154 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
71f36115 15155 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
27c868c2 15156 adv_dvc_varp->iop_base);
27c868c2
MW
15157
15158 /*
15159 * Even though it isn't used to access wide boards, other
15160 * than for the debug line below, save I/O Port address so
15161 * that it can be reported.
15162 */
15163 boardp->ioport = iop;
15164
57ba5fe9
MW
15165 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
15166 "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
15167 (ushort)inpw(iop));
15168#endif /* CONFIG_PCI */
27c868c2
MW
15169 }
15170
15171#ifdef CONFIG_PROC_FS
15172 /*
15173 * Allocate buffer for printing information from
15174 * /proc/scsi/advansys/[0...].
15175 */
b2c16f58
MW
15176 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
15177 if (!boardp->prtbuf) {
15178 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
15179 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
15180 goto err_unmap;
27c868c2
MW
15181 }
15182#endif /* CONFIG_PROC_FS */
15183
15184 if (ASC_NARROW_BOARD(boardp)) {
27c868c2
MW
15185 /*
15186 * Set the board bus type and PCI IRQ before
15187 * calling AscInitGetConfig().
15188 */
15189 switch (asc_dvc_varp->bus_type) {
15190#ifdef CONFIG_ISA
15191 case ASC_IS_ISA:
15192 shost->unchecked_isa_dma = TRUE;
074c8fe4 15193 share_irq = 0;
27c868c2
MW
15194 break;
15195 case ASC_IS_VL:
15196 shost->unchecked_isa_dma = FALSE;
074c8fe4 15197 share_irq = 0;
27c868c2
MW
15198 break;
15199 case ASC_IS_EISA:
15200 shost->unchecked_isa_dma = FALSE;
074c8fe4 15201 share_irq = IRQF_SHARED;
27c868c2
MW
15202 break;
15203#endif /* CONFIG_ISA */
15204#ifdef CONFIG_PCI
15205 case ASC_IS_PCI:
15206 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
27c868c2 15207 shost->unchecked_isa_dma = FALSE;
074c8fe4 15208 share_irq = IRQF_SHARED;
27c868c2
MW
15209 break;
15210#endif /* CONFIG_PCI */
15211 default:
15212 ASC_PRINT2
15213 ("advansys_board_found: board %d: unknown adapter type: %d\n",
15214 boardp->id, asc_dvc_varp->bus_type);
15215 shost->unchecked_isa_dma = TRUE;
074c8fe4 15216 share_irq = 0;
27c868c2
MW
15217 break;
15218 }
27c868c2 15219
27c868c2
MW
15220 /*
15221 * NOTE: AscInitGetConfig() may change the board's
15222 * bus_type value. The bus_type value should no
15223 * longer be used. If the bus_type field must be
15224 * referenced only use the bit-wise AND operator "&".
15225 */
15226 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
c2dce2fa 15227 err_code = AscInitGetConfig(boardp);
27c868c2 15228 } else {
c2dce2fa
MW
15229#ifdef CONFIG_PCI
15230 /*
15231 * For Wide boards set PCI information before calling
15232 * AdvInitGetConfig().
15233 */
15234 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
15235 shost->unchecked_isa_dma = FALSE;
15236 share_irq = IRQF_SHARED;
27c868c2 15237 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
394dbf3f 15238
c2dce2fa
MW
15239 err_code = AdvInitGetConfig(pdev, boardp);
15240#endif /* CONFIG_PCI */
27c868c2
MW
15241 }
15242
b2c16f58
MW
15243 if (err_code != 0)
15244 goto err_free_proc;
27c868c2
MW
15245
15246 /*
15247 * Save the EEPROM configuration so that it can be displayed
15248 * from /proc/scsi/advansys/[0...].
15249 */
15250 if (ASC_NARROW_BOARD(boardp)) {
15251
15252 ASCEEP_CONFIG *ep;
15253
15254 /*
15255 * Set the adapter's target id bit in the 'init_tidmask' field.
15256 */
15257 boardp->init_tidmask |=
15258 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
15259
15260 /*
15261 * Save EEPROM settings for the board.
15262 */
15263 ep = &boardp->eep_config.asc_eep;
15264
15265 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
15266 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
15267 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
15268 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
15269 ep->start_motor = asc_dvc_varp->start_motor;
15270 ep->cntl = asc_dvc_varp->dvc_cntl;
15271 ep->no_scam = asc_dvc_varp->no_scam;
15272 ep->max_total_qng = asc_dvc_varp->max_total_qng;
15273 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
15274 /* 'max_tag_qng' is set to the same value for every device. */
15275 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
15276 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
15277 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
15278 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
15279 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
15280 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
15281 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
15282
15283 /*
15284 * Modify board configuration.
15285 */
15286 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
c2dce2fa
MW
15287 err_code = AscInitSetConfig(pdev, boardp);
15288 if (err_code)
b2c16f58 15289 goto err_free_proc;
27c868c2
MW
15290
15291 /*
15292 * Finish initializing the 'Scsi_Host' structure.
15293 */
15294 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
15295 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
15296 shost->irq = asc_dvc_varp->irq_no;
15297 }
15298 } else {
15299 ADVEEP_3550_CONFIG *ep_3550;
15300 ADVEEP_38C0800_CONFIG *ep_38C0800;
15301 ADVEEP_38C1600_CONFIG *ep_38C1600;
15302
15303 /*
15304 * Save Wide EEP Configuration Information.
15305 */
15306 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
15307 ep_3550 = &boardp->eep_config.adv_3550_eep;
15308
15309 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
15310 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
15311 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
15312 ep_3550->termination = adv_dvc_varp->cfg->termination;
15313 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
15314 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
15315 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
15316 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
15317 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
15318 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
15319 ep_3550->start_motor = adv_dvc_varp->start_motor;
15320 ep_3550->scsi_reset_delay =
15321 adv_dvc_varp->scsi_reset_wait;
15322 ep_3550->serial_number_word1 =
15323 adv_dvc_varp->cfg->serial1;
15324 ep_3550->serial_number_word2 =
15325 adv_dvc_varp->cfg->serial2;
15326 ep_3550->serial_number_word3 =
15327 adv_dvc_varp->cfg->serial3;
15328 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
15329 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
15330
15331 ep_38C0800->adapter_scsi_id =
15332 adv_dvc_varp->chip_scsi_id;
15333 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
15334 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
15335 ep_38C0800->termination_lvd =
15336 adv_dvc_varp->cfg->termination;
15337 ep_38C0800->disc_enable =
15338 adv_dvc_varp->cfg->disc_enable;
15339 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
15340 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
15341 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
15342 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
15343 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
15344 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
15345 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
15346 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
15347 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
15348 ep_38C0800->scsi_reset_delay =
15349 adv_dvc_varp->scsi_reset_wait;
15350 ep_38C0800->serial_number_word1 =
15351 adv_dvc_varp->cfg->serial1;
15352 ep_38C0800->serial_number_word2 =
15353 adv_dvc_varp->cfg->serial2;
15354 ep_38C0800->serial_number_word3 =
15355 adv_dvc_varp->cfg->serial3;
15356 } else {
15357 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
15358
15359 ep_38C1600->adapter_scsi_id =
15360 adv_dvc_varp->chip_scsi_id;
15361 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
15362 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
15363 ep_38C1600->termination_lvd =
15364 adv_dvc_varp->cfg->termination;
15365 ep_38C1600->disc_enable =
15366 adv_dvc_varp->cfg->disc_enable;
15367 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
15368 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
15369 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
15370 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
15371 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
15372 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
15373 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
15374 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
15375 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
15376 ep_38C1600->scsi_reset_delay =
15377 adv_dvc_varp->scsi_reset_wait;
15378 ep_38C1600->serial_number_word1 =
15379 adv_dvc_varp->cfg->serial1;
15380 ep_38C1600->serial_number_word2 =
15381 adv_dvc_varp->cfg->serial2;
15382 ep_38C1600->serial_number_word3 =
15383 adv_dvc_varp->cfg->serial3;
15384 }
15385
15386 /*
15387 * Set the adapter's target id bit in the 'init_tidmask' field.
15388 */
15389 boardp->init_tidmask |=
15390 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
27c868c2
MW
15391 }
15392
15393 /*
15394 * Channels are numbered beginning with 0. For AdvanSys one host
15395 * structure supports one channel. Multi-channel boards have a
15396 * separate host structure for each channel.
15397 */
15398 shost->max_channel = 0;
15399 if (ASC_NARROW_BOARD(boardp)) {
15400 shost->max_id = ASC_MAX_TID + 1;
15401 shost->max_lun = ASC_MAX_LUN + 1;
15402
15403 shost->io_port = asc_dvc_varp->iop_base;
15404 boardp->asc_n_io_port = ASC_IOADR_GAP;
15405 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
15406
15407 /* Set maximum number of queues the adapter can handle. */
15408 shost->can_queue = asc_dvc_varp->max_total_qng;
15409 } else {
15410 shost->max_id = ADV_MAX_TID + 1;
15411 shost->max_lun = ADV_MAX_LUN + 1;
15412
15413 /*
15414 * Save the I/O Port address and length even though
15415 * I/O ports are not used to access Wide boards.
15416 * Instead the Wide boards are accessed with
15417 * PCI Memory Mapped I/O.
15418 */
15419 shost->io_port = iop;
27c868c2
MW
15420
15421 shost->this_id = adv_dvc_varp->chip_scsi_id;
15422
15423 /* Set maximum number of queues the adapter can handle. */
15424 shost->can_queue = adv_dvc_varp->max_host_qng;
15425 }
15426
27c868c2
MW
15427 /*
15428 * Following v1.3.89, 'cmd_per_lun' is no longer needed
15429 * and should be set to zero.
15430 *
15431 * But because of a bug introduced in v1.3.89 if the driver is
15432 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
15433 * SCSI function 'allocate_device' will panic. To allow the driver
15434 * to work as a module in these kernels set 'cmd_per_lun' to 1.
15435 *
15436 * Note: This is wrong. cmd_per_lun should be set to the depth
15437 * you want on untagged devices always.
15438 #ifdef MODULE
15439 */
15440 shost->cmd_per_lun = 1;
15441/* #else
15442 shost->cmd_per_lun = 0;
15443#endif */
15444
15445 /*
15446 * Set the maximum number of scatter-gather elements the
15447 * adapter can handle.
15448 */
15449 if (ASC_NARROW_BOARD(boardp)) {
15450 /*
15451 * Allow two commands with 'sg_tablesize' scatter-gather
15452 * elements to be executed simultaneously. This value is
15453 * the theoretical hardware limit. It may be decreased
15454 * below.
15455 */
15456 shost->sg_tablesize =
15457 (((asc_dvc_varp->max_total_qng - 2) / 2) *
15458 ASC_SG_LIST_PER_Q) + 1;
15459 } else {
15460 shost->sg_tablesize = ADV_MAX_SG_LIST;
15461 }
15462
15463 /*
15464 * The value of 'sg_tablesize' can not exceed the SCSI
15465 * mid-level driver definition of SG_ALL. SG_ALL also
15466 * must not be exceeded, because it is used to define the
15467 * size of the scatter-gather table in 'struct asc_sg_head'.
15468 */
15469 if (shost->sg_tablesize > SG_ALL) {
15470 shost->sg_tablesize = SG_ALL;
15471 }
15472
15473 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
15474
15475 /* BIOS start address. */
15476 if (ASC_NARROW_BOARD(boardp)) {
b2c16f58
MW
15477 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
15478 asc_dvc_varp->bus_type);
27c868c2
MW
15479 } else {
15480 /*
15481 * Fill-in BIOS board variables. The Wide BIOS saves
15482 * information in LRAM that is used by the driver.
15483 */
15484 AdvReadWordLram(adv_dvc_varp->iop_base,
15485 BIOS_SIGNATURE, boardp->bios_signature);
15486 AdvReadWordLram(adv_dvc_varp->iop_base,
15487 BIOS_VERSION, boardp->bios_version);
15488 AdvReadWordLram(adv_dvc_varp->iop_base,
15489 BIOS_CODESEG, boardp->bios_codeseg);
15490 AdvReadWordLram(adv_dvc_varp->iop_base,
15491 BIOS_CODELEN, boardp->bios_codelen);
15492
15493 ASC_DBG2(1,
15494 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
15495 boardp->bios_signature, boardp->bios_version);
15496
15497 ASC_DBG2(1,
15498 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
15499 boardp->bios_codeseg, boardp->bios_codelen);
15500
15501 /*
15502 * If the BIOS saved a valid signature, then fill in
15503 * the BIOS code segment base address.
15504 */
15505 if (boardp->bios_signature == 0x55AA) {
15506 /*
15507 * Convert x86 realmode code segment to a linear
15508 * address by shifting left 4.
15509 */
15510 shost->base = ((ulong)boardp->bios_codeseg << 4);
15511 } else {
15512 shost->base = 0;
15513 }
15514 }
15515
15516 /*
15517 * Register Board Resources - I/O Port, DMA, IRQ
15518 */
15519
27c868c2
MW
15520 /* Register DMA Channel for Narrow boards. */
15521 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
15522#ifdef CONFIG_ISA
15523 if (ASC_NARROW_BOARD(boardp)) {
15524 /* Register DMA channel for ISA bus. */
15525 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
15526 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
b2c16f58
MW
15527 ret = request_dma(shost->dma_channel, "advansys");
15528 if (ret) {
27c868c2
MW
15529 ASC_PRINT3
15530 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
15531 boardp->id, shost->dma_channel, ret);
71f36115 15532 goto err_free_proc;
27c868c2
MW
15533 }
15534 AscEnableIsaDma(shost->dma_channel);
15535 }
15536 }
15537#endif /* CONFIG_ISA */
15538
15539 /* Register IRQ Number. */
15540 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
074c8fe4
MW
15541
15542 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
15543 "advansys", shost);
15544
15545 if (ret) {
27c868c2
MW
15546 if (ret == -EBUSY) {
15547 ASC_PRINT2
15548 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
15549 boardp->id, shost->irq);
15550 } else if (ret == -EINVAL) {
15551 ASC_PRINT2
15552 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
15553 boardp->id, shost->irq);
15554 } else {
15555 ASC_PRINT3
15556 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
15557 boardp->id, shost->irq, ret);
15558 }
b2c16f58 15559 goto err_free_dma;
27c868c2
MW
15560 }
15561
15562 /*
15563 * Initialize board RISC chip and enable interrupts.
15564 */
15565 if (ASC_NARROW_BOARD(boardp)) {
15566 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
15567 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
15568 err_code = asc_dvc_varp->err_code;
15569
15570 if (warn_code || err_code) {
15571 ASC_PRINT4
15572 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
15573 boardp->id,
15574 asc_dvc_varp->init_state, warn_code, err_code);
15575 }
15576 } else {
b2c16f58 15577 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
27c868c2
MW
15578 }
15579
b2c16f58
MW
15580 if (err_code != 0)
15581 goto err_free_wide_mem;
15582
27c868c2
MW
15583 ASC_DBG_PRT_SCSI_HOST(2, shost);
15584
8dfb5379
MW
15585 ret = scsi_add_host(shost, dev);
15586 if (ret)
15587 goto err_free_wide_mem;
15588
15589 scsi_scan_host(shost);
27c868c2 15590 return shost;
b2c16f58
MW
15591
15592 err_free_wide_mem:
15593 advansys_wide_free_mem(boardp);
15594 free_irq(shost->irq, shost);
15595 err_free_dma:
15596 if (shost->dma_channel != NO_ISA_DMA)
15597 free_dma(shost->dma_channel);
b2c16f58
MW
15598 err_free_proc:
15599 kfree(boardp->prtbuf);
15600 err_unmap:
15601 if (boardp->ioremap_addr)
15602 iounmap(boardp->ioremap_addr);
15603 err_shost:
8dfb5379 15604 scsi_host_put(shost);
b2c16f58 15605 return NULL;
27c868c2
MW
15606}
15607
27c868c2
MW
15608/*
15609 * advansys_release()
15610 *
15611 * Release resources allocated for a single AdvanSys adapter.
15612 */
15613static int advansys_release(struct Scsi_Host *shost)
15614{
15615 asc_board_t *boardp;
15616
15617 ASC_DBG(1, "advansys_release: begin\n");
8dfb5379 15618 scsi_remove_host(shost);
27c868c2 15619 boardp = ASC_BOARDP(shost);
074c8fe4 15620 free_irq(shost->irq, shost);
27c868c2
MW
15621 if (shost->dma_channel != NO_ISA_DMA) {
15622 ASC_DBG(1, "advansys_release: free_dma()\n");
15623 free_dma(shost->dma_channel);
15624 }
27c868c2 15625 if (ASC_WIDE_BOARD(boardp)) {
27c868c2 15626 iounmap(boardp->ioremap_addr);
b2c16f58 15627 advansys_wide_free_mem(boardp);
27c868c2 15628 }
27c868c2 15629 kfree(boardp->prtbuf);
8dfb5379 15630 scsi_host_put(shost);
27c868c2
MW
15631 ASC_DBG(1, "advansys_release: end\n");
15632 return 0;
15633}
15634
c304ec94
MW
15635static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
15636 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
15637 0x0210, 0x0230, 0x0250, 0x0330
15638};
15639
15640static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
15641{
15642 PortAddr iop_base = _asc_def_iop_base[id];
15643 struct Scsi_Host *shost;
15644
15645 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
15646 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
15647 iop_base);
c304ec94
MW
15648 return -ENODEV;
15649 }
15650 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
15651 if (!AscFindSignature(iop_base))
15652 goto nodev;
15653 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
15654 goto nodev;
15655
15656 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
c304ec94
MW
15657 if (!shost)
15658 goto nodev;
15659
15660 dev_set_drvdata(dev, shost);
15661 return 0;
15662
15663 nodev:
71f36115 15664 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
15665 return -ENODEV;
15666}
15667
15668static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
15669{
71f36115 15670 int ioport = _asc_def_iop_base[id];
c304ec94 15671 advansys_release(dev_get_drvdata(dev));
71f36115 15672 release_region(ioport, ASC_IOADR_GAP);
c304ec94
MW
15673 return 0;
15674}
15675
15676static struct isa_driver advansys_isa_driver = {
15677 .probe = advansys_isa_probe,
15678 .remove = __devexit_p(advansys_isa_remove),
15679 .driver = {
15680 .owner = THIS_MODULE,
15681 .name = "advansys",
15682 },
15683};
15684
15685static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
15686{
15687 PortAddr iop_base = _asc_def_iop_base[id];
15688 struct Scsi_Host *shost;
15689
15690 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
71f36115
MW
15691 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
15692 iop_base);
c304ec94
MW
15693 return -ENODEV;
15694 }
15695 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
c304ec94
MW
15696 if (!AscFindSignature(iop_base))
15697 goto nodev;
15698 /*
15699 * I don't think this condition can actually happen, but the old
15700 * driver did it, and the chances of finding a VLB setup in 2007
15701 * to do testing with is slight to none.
15702 */
15703 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
15704 goto nodev;
15705
15706 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
c304ec94
MW
15707 if (!shost)
15708 goto nodev;
15709
15710 dev_set_drvdata(dev, shost);
15711 return 0;
15712
15713 nodev:
71f36115 15714 release_region(iop_base, ASC_IOADR_GAP);
c304ec94
MW
15715 return -ENODEV;
15716}
15717
15718static struct isa_driver advansys_vlb_driver = {
15719 .probe = advansys_vlb_probe,
15720 .remove = __devexit_p(advansys_isa_remove),
15721 .driver = {
15722 .owner = THIS_MODULE,
b8e5152b 15723 .name = "advansys_vlb",
c304ec94
MW
15724 },
15725};
15726
b09e05a7
MW
15727static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
15728 { "ABP7401" },
15729 { "ABP7501" },
15730 { "" }
15731};
15732
15733MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
15734
15735/*
15736 * EISA is a little more tricky than PCI; each EISA device may have two
15737 * channels, and this driver is written to make each channel its own Scsi_Host
15738 */
15739struct eisa_scsi_data {
15740 struct Scsi_Host *host[2];
15741};
15742
15743static int __devinit advansys_eisa_probe(struct device *dev)
15744{
15745 int i, ioport;
15746 int err;
15747 struct eisa_device *edev = to_eisa_device(dev);
15748 struct eisa_scsi_data *data;
15749
15750 err = -ENOMEM;
15751 data = kzalloc(sizeof(*data), GFP_KERNEL);
15752 if (!data)
15753 goto fail;
15754 ioport = edev->base_addr + 0xc30;
15755
15756 err = -ENODEV;
15757 for (i = 0; i < 2; i++, ioport += 0x20) {
71f36115
MW
15758 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
15759 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
15760 ioport + ASC_IOADR_GAP - 1);
15761 continue;
15762 }
15763 if (!AscFindSignature(ioport)) {
15764 release_region(ioport, ASC_IOADR_GAP);
b09e05a7 15765 continue;
71f36115
MW
15766 }
15767
b09e05a7
MW
15768 /*
15769 * I don't know why we need to do this for EISA chips, but
15770 * not for any others. It looks to be equivalent to
15771 * AscGetChipCfgMsw, but I may have overlooked something,
15772 * so I'm not converting it until I get an EISA board to
15773 * test with.
15774 */
15775 inw(ioport + 4);
15776 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
71f36115 15777 if (data->host[i]) {
b09e05a7 15778 err = 0;
71f36115
MW
15779 } else {
15780 release_region(ioport, ASC_IOADR_GAP);
15781 }
b09e05a7
MW
15782 }
15783
15784 if (err) {
15785 kfree(data);
15786 } else {
15787 dev_set_drvdata(dev, data);
15788 }
15789
15790 fail:
15791 return err;
15792}
15793
15794static __devexit int advansys_eisa_remove(struct device *dev)
15795{
15796 int i;
15797 struct eisa_scsi_data *data = dev_get_drvdata(dev);
15798
15799 for (i = 0; i < 2; i++) {
71f36115 15800 int ioport;
b09e05a7
MW
15801 struct Scsi_Host *shost = data->host[i];
15802 if (!shost)
15803 continue;
71f36115 15804 ioport = shost->io_port;
b09e05a7 15805 advansys_release(shost);
71f36115 15806 release_region(ioport, ASC_IOADR_GAP);
b09e05a7
MW
15807 }
15808
15809 kfree(data);
15810 return 0;
15811}
15812
15813static struct eisa_driver advansys_eisa_driver = {
15814 .id_table = advansys_eisa_table,
15815 .driver = {
15816 .name = "advansys",
15817 .probe = advansys_eisa_probe,
15818 .remove = __devexit_p(advansys_eisa_remove),
15819 }
15820};
15821
2672ea86
DJ
15822/* PCI Devices supported by this driver */
15823static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
27c868c2
MW
15824 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
15825 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15826 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
15827 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15828 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
15829 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15830 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
15831 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15832 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
15833 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15834 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
15835 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
15836 {}
2672ea86 15837};
27c868c2 15838
2672ea86 15839MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
78e77d8b 15840
9649af39
MW
15841static void __devinit advansys_set_latency(struct pci_dev *pdev)
15842{
15843 if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
15844 (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
15845 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
15846 } else {
15847 u8 latency;
15848 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
15849 if (latency < 0x20)
15850 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
15851 }
15852}
15853
78e77d8b
MW
15854static int __devinit
15855advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
15856{
15857 int err, ioport;
15858 struct Scsi_Host *shost;
15859
15860 err = pci_enable_device(pdev);
15861 if (err)
15862 goto fail;
71f36115
MW
15863 err = pci_request_regions(pdev, "advansys");
15864 if (err)
15865 goto disable_device;
9649af39
MW
15866 pci_set_master(pdev);
15867 advansys_set_latency(pdev);
78e77d8b
MW
15868
15869 if (pci_resource_len(pdev, 0) == 0)
15870 goto nodev;
15871
15872 ioport = pci_resource_start(pdev, 0);
15873 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
15874
15875 if (!shost)
15876 goto nodev;
15877
15878 pci_set_drvdata(pdev, shost);
15879 return 0;
15880
15881 nodev:
15882 err = -ENODEV;
71f36115
MW
15883 pci_release_regions(pdev);
15884 disable_device:
78e77d8b
MW
15885 pci_disable_device(pdev);
15886 fail:
15887 return err;
15888}
15889
15890static void __devexit advansys_pci_remove(struct pci_dev *pdev)
15891{
15892 advansys_release(pci_get_drvdata(pdev));
71f36115 15893 pci_release_regions(pdev);
78e77d8b
MW
15894 pci_disable_device(pdev);
15895}
15896
15897static struct pci_driver advansys_pci_driver = {
15898 .name = "advansys",
15899 .id_table = advansys_pci_tbl,
15900 .probe = advansys_pci_probe,
15901 .remove = __devexit_p(advansys_pci_remove),
15902};
8c6af9e1 15903
8dfb5379
MW
15904static int __init advansys_init(void)
15905{
c304ec94 15906 int error;
b09e05a7 15907
c304ec94
MW
15908 error = isa_register_driver(&advansys_isa_driver,
15909 ASC_IOADR_TABLE_MAX_IX);
78e77d8b
MW
15910 if (error)
15911 goto fail;
8dfb5379 15912
c304ec94
MW
15913 error = isa_register_driver(&advansys_vlb_driver,
15914 ASC_IOADR_TABLE_MAX_IX);
15915 if (error)
15916 goto unregister_isa;
15917
15918 error = eisa_driver_register(&advansys_eisa_driver);
15919 if (error)
15920 goto unregister_vlb;
15921
b09e05a7
MW
15922 error = pci_register_driver(&advansys_pci_driver);
15923 if (error)
15924 goto unregister_eisa;
15925
8dfb5379 15926 return 0;
78e77d8b 15927
b09e05a7
MW
15928 unregister_eisa:
15929 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15930 unregister_vlb:
15931 isa_unregister_driver(&advansys_vlb_driver);
15932 unregister_isa:
15933 isa_unregister_driver(&advansys_isa_driver);
78e77d8b 15934 fail:
78e77d8b 15935 return error;
8dfb5379
MW
15936}
15937
15938static void __exit advansys_exit(void)
15939{
78e77d8b 15940 pci_unregister_driver(&advansys_pci_driver);
b09e05a7 15941 eisa_driver_unregister(&advansys_eisa_driver);
c304ec94
MW
15942 isa_unregister_driver(&advansys_vlb_driver);
15943 isa_unregister_driver(&advansys_isa_driver);
8dfb5379
MW
15944}
15945
15946module_init(advansys_init);
15947module_exit(advansys_exit);
15948
8c6af9e1 15949MODULE_LICENSE("GPL");