[SCSI] advansys: Sort out irq number mess
[platform/kernel/linux-starfive.git] / drivers / scsi / advansys.c
1 #define DRV_NAME "advansys"
2 #define ASC_VERSION "3.4"       /* AdvanSys Driver Version */
3
4 /*
5  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6  *
7  * Copyright (c) 1995-2000 Advanced System Products, Inc.
8  * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
9  * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
10  * All Rights Reserved.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  */
17
18 /*
19  * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
20  * changed its name to ConnectCom Solutions, Inc.
21  * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
22  */
23
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/kernel.h>
27 #include <linux/types.h>
28 #include <linux/ioport.h>
29 #include <linux/interrupt.h>
30 #include <linux/delay.h>
31 #include <linux/slab.h>
32 #include <linux/mm.h>
33 #include <linux/proc_fs.h>
34 #include <linux/init.h>
35 #include <linux/blkdev.h>
36 #include <linux/isa.h>
37 #include <linux/eisa.h>
38 #include <linux/pci.h>
39 #include <linux/spinlock.h>
40 #include <linux/dma-mapping.h>
41
42 #include <asm/io.h>
43 #include <asm/system.h>
44 #include <asm/dma.h>
45
46 #include <scsi/scsi_cmnd.h>
47 #include <scsi/scsi_device.h>
48 #include <scsi/scsi_tcq.h>
49 #include <scsi/scsi.h>
50 #include <scsi/scsi_host.h>
51
52 /* FIXME:
53  *
54  *  1. Although all of the necessary command mapping places have the
55  *     appropriate dma_map.. APIs, the driver still processes its internal
56  *     queue using bus_to_virt() and virt_to_bus() which are illegal under
57  *     the API.  The entire queue processing structure will need to be
58  *     altered to fix this.
59  *  2. Need to add memory mapping workaround. Test the memory mapping.
60  *     If it doesn't work revert to I/O port access. Can a test be done
61  *     safely?
62  *  3. Handle an interrupt not working. Keep an interrupt counter in
63  *     the interrupt handler. In the timeout function if the interrupt
64  *     has not occurred then print a message and run in polled mode.
65  *  4. Need to add support for target mode commands, cf. CAM XPT.
66  *  5. check DMA mapping functions for failure
67  *  6. Use scsi_transport_spi
68  *  7. advansys_info is not safe against multiple simultaneous callers
69  *  8. Kill boardp->id
70  *  9. Add module_param to override ISA/VLB ioport array
71  */
72 #warning this driver is still not properly converted to the DMA API
73
74 /* Enable driver /proc statistics. */
75 #define ADVANSYS_STATS
76
77 /* Enable driver tracing. */
78 /* #define ADVANSYS_DEBUG */
79
80 #define ASC_LIB_VERSION_MAJOR  1
81 #define ASC_LIB_VERSION_MINOR  24
82 #define ASC_LIB_SERIAL_NUMBER  123
83
84 /*
85  * Portable Data Types
86  *
87  * Any instance where a 32-bit long or pointer type is assumed
88  * for precision or HW defined structures, the following define
89  * types must be used. In Linux the char, short, and int types
90  * are all consistent at 8, 16, and 32 bits respectively. Pointers
91  * and long types are 64 bits on Alpha and UltraSPARC.
92  */
93 #define ASC_PADDR __u32         /* Physical/Bus address data type. */
94 #define ASC_VADDR __u32         /* Virtual address data type. */
95 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
96 #define ASC_SDCNT __s32         /* Signed Data count type. */
97
98 /*
99  * These macros are used to convert a virtual address to a
100  * 32-bit value. This currently can be used on Linux Alpha
101  * which uses 64-bit virtual address but a 32-bit bus address.
102  * This is likely to break in the future, but doing this now
103  * will give us time to change the HW and FW to handle 64-bit
104  * addresses.
105  */
106 #define ASC_VADDR_TO_U32   virt_to_bus
107 #define ASC_U32_TO_VADDR   bus_to_virt
108
109 typedef unsigned char uchar;
110
111 #ifndef TRUE
112 #define TRUE     (1)
113 #endif
114 #ifndef FALSE
115 #define FALSE    (0)
116 #endif
117
118 #define ERR      (-1)
119 #define UW_ERR   (uint)(0xFFFF)
120 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
121
122 #define PCI_VENDOR_ID_ASP               0x10cd
123 #define PCI_DEVICE_ID_ASP_1200A         0x1100
124 #define PCI_DEVICE_ID_ASP_ABP940        0x1200
125 #define PCI_DEVICE_ID_ASP_ABP940U       0x1300
126 #define PCI_DEVICE_ID_ASP_ABP940UW      0x2300
127 #define PCI_DEVICE_ID_38C0800_REV1      0x2500
128 #define PCI_DEVICE_ID_38C1600_REV1      0x2700
129
130 /*
131  * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
132  * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
133  * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
134  * SRB structure.
135  */
136 #define CC_VERY_LONG_SG_LIST 0
137 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
138
139 #define PortAddr                 unsigned short /* port address size  */
140 #define inp(port)                inb(port)
141 #define outp(port, byte)         outb((byte), (port))
142
143 #define inpw(port)               inw(port)
144 #define outpw(port, word)        outw((word), (port))
145
146 #define ASC_MAX_SG_QUEUE    7
147 #define ASC_MAX_SG_LIST     255
148
149 #define ASC_CS_TYPE  unsigned short
150
151 #define ASC_IS_ISA          (0x0001)
152 #define ASC_IS_ISAPNP       (0x0081)
153 #define ASC_IS_EISA         (0x0002)
154 #define ASC_IS_PCI          (0x0004)
155 #define ASC_IS_PCI_ULTRA    (0x0104)
156 #define ASC_IS_PCMCIA       (0x0008)
157 #define ASC_IS_MCA          (0x0020)
158 #define ASC_IS_VL           (0x0040)
159 #define ASC_IS_WIDESCSI_16  (0x0100)
160 #define ASC_IS_WIDESCSI_32  (0x0200)
161 #define ASC_IS_BIG_ENDIAN   (0x8000)
162
163 #define ASC_CHIP_MIN_VER_VL      (0x01)
164 #define ASC_CHIP_MAX_VER_VL      (0x07)
165 #define ASC_CHIP_MIN_VER_PCI     (0x09)
166 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
167 #define ASC_CHIP_VER_PCI_BIT     (0x08)
168 #define ASC_CHIP_MIN_VER_ISA     (0x11)
169 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
170 #define ASC_CHIP_MAX_VER_ISA     (0x27)
171 #define ASC_CHIP_VER_ISA_BIT     (0x30)
172 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
173 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
174 #define ASC_CHIP_VER_PCI             0x08
175 #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
176 #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
177 #define ASC_CHIP_MIN_VER_EISA (0x41)
178 #define ASC_CHIP_MAX_VER_EISA (0x47)
179 #define ASC_CHIP_VER_EISA_BIT (0x40)
180 #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
181 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
182 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
183 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
184
185 #define ASC_SCSI_ID_BITS  3
186 #define ASC_SCSI_TIX_TYPE     uchar
187 #define ASC_ALL_DEVICE_BIT_SET  0xFF
188 #define ASC_SCSI_BIT_ID_TYPE  uchar
189 #define ASC_MAX_TID       7
190 #define ASC_MAX_LUN       7
191 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
192 #define ASC_MAX_SENSE_LEN   32
193 #define ASC_MIN_SENSE_LEN   14
194 #define ASC_SCSI_RESET_HOLD_TIME_US  60
195
196 /*
197  * Narrow boards only support 12-byte commands, while wide boards
198  * extend to 16-byte commands.
199  */
200 #define ASC_MAX_CDB_LEN     12
201 #define ADV_MAX_CDB_LEN     16
202
203 #define MS_SDTR_LEN    0x03
204 #define MS_WDTR_LEN    0x02
205
206 #define ASC_SG_LIST_PER_Q   7
207 #define QS_FREE        0x00
208 #define QS_READY       0x01
209 #define QS_DISC1       0x02
210 #define QS_DISC2       0x04
211 #define QS_BUSY        0x08
212 #define QS_ABORTED     0x40
213 #define QS_DONE        0x80
214 #define QC_NO_CALLBACK   0x01
215 #define QC_SG_SWAP_QUEUE 0x02
216 #define QC_SG_HEAD       0x04
217 #define QC_DATA_IN       0x08
218 #define QC_DATA_OUT      0x10
219 #define QC_URGENT        0x20
220 #define QC_MSG_OUT       0x40
221 #define QC_REQ_SENSE     0x80
222 #define QCSG_SG_XFER_LIST  0x02
223 #define QCSG_SG_XFER_MORE  0x04
224 #define QCSG_SG_XFER_END   0x08
225 #define QD_IN_PROGRESS       0x00
226 #define QD_NO_ERROR          0x01
227 #define QD_ABORTED_BY_HOST   0x02
228 #define QD_WITH_ERROR        0x04
229 #define QD_INVALID_REQUEST   0x80
230 #define QD_INVALID_HOST_NUM  0x81
231 #define QD_INVALID_DEVICE    0x82
232 #define QD_ERR_INTERNAL      0xFF
233 #define QHSTA_NO_ERROR               0x00
234 #define QHSTA_M_SEL_TIMEOUT          0x11
235 #define QHSTA_M_DATA_OVER_RUN        0x12
236 #define QHSTA_M_DATA_UNDER_RUN       0x12
237 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
238 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
239 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
240 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
241 #define QHSTA_D_HOST_ABORT_FAILED       0x23
242 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
243 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
244 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
245 #define QHSTA_M_WTM_TIMEOUT         0x41
246 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
247 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
248 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
249 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
250 #define QHSTA_M_BAD_TAG_CODE        0x46
251 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
252 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
253 #define QHSTA_D_LRAM_CMP_ERROR        0x81
254 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
255 #define ASC_FLAG_SCSIQ_REQ        0x01
256 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
257 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
258 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
259 #define ASC_FLAG_WIN16            0x10
260 #define ASC_FLAG_WIN32            0x20
261 #define ASC_FLAG_ISA_OVER_16MB    0x40
262 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
263 #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
264 #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
265 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
266 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
267 #define ASC_SCSIQ_CPY_BEG              4
268 #define ASC_SCSIQ_SGHD_CPY_BEG         2
269 #define ASC_SCSIQ_B_FWD                0
270 #define ASC_SCSIQ_B_BWD                1
271 #define ASC_SCSIQ_B_STATUS             2
272 #define ASC_SCSIQ_B_QNO                3
273 #define ASC_SCSIQ_B_CNTL               4
274 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
275 #define ASC_SCSIQ_D_DATA_ADDR          8
276 #define ASC_SCSIQ_D_DATA_CNT          12
277 #define ASC_SCSIQ_B_SENSE_LEN         20
278 #define ASC_SCSIQ_DONE_INFO_BEG       22
279 #define ASC_SCSIQ_D_SRBPTR            22
280 #define ASC_SCSIQ_B_TARGET_IX         26
281 #define ASC_SCSIQ_B_CDB_LEN           28
282 #define ASC_SCSIQ_B_TAG_CODE          29
283 #define ASC_SCSIQ_W_VM_ID             30
284 #define ASC_SCSIQ_DONE_STATUS         32
285 #define ASC_SCSIQ_HOST_STATUS         33
286 #define ASC_SCSIQ_SCSI_STATUS         34
287 #define ASC_SCSIQ_CDB_BEG             36
288 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
289 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
290 #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
291 #define ASC_SCSIQ_B_SG_WK_QP          49
292 #define ASC_SCSIQ_B_SG_WK_IX          50
293 #define ASC_SCSIQ_W_ALT_DC1           52
294 #define ASC_SCSIQ_B_LIST_CNT          6
295 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
296 #define ASC_SGQ_B_SG_CNTL             4
297 #define ASC_SGQ_B_SG_HEAD_QP          5
298 #define ASC_SGQ_B_SG_LIST_CNT         6
299 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
300 #define ASC_SGQ_LIST_BEG              8
301 #define ASC_DEF_SCSI1_QNG    4
302 #define ASC_MAX_SCSI1_QNG    4
303 #define ASC_DEF_SCSI2_QNG    16
304 #define ASC_MAX_SCSI2_QNG    32
305 #define ASC_TAG_CODE_MASK    0x23
306 #define ASC_STOP_REQ_RISC_STOP      0x01
307 #define ASC_STOP_ACK_RISC_STOP      0x03
308 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
309 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
310 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
311 #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
312 #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
313 #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
314 #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
315 #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
316 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
317 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
318
319 typedef struct asc_scsiq_1 {
320         uchar status;
321         uchar q_no;
322         uchar cntl;
323         uchar sg_queue_cnt;
324         uchar target_id;
325         uchar target_lun;
326         ASC_PADDR data_addr;
327         ASC_DCNT data_cnt;
328         ASC_PADDR sense_addr;
329         uchar sense_len;
330         uchar extra_bytes;
331 } ASC_SCSIQ_1;
332
333 typedef struct asc_scsiq_2 {
334         ASC_VADDR srb_ptr;
335         uchar target_ix;
336         uchar flag;
337         uchar cdb_len;
338         uchar tag_code;
339         ushort vm_id;
340 } ASC_SCSIQ_2;
341
342 typedef struct asc_scsiq_3 {
343         uchar done_stat;
344         uchar host_stat;
345         uchar scsi_stat;
346         uchar scsi_msg;
347 } ASC_SCSIQ_3;
348
349 typedef struct asc_scsiq_4 {
350         uchar cdb[ASC_MAX_CDB_LEN];
351         uchar y_first_sg_list_qp;
352         uchar y_working_sg_qp;
353         uchar y_working_sg_ix;
354         uchar y_res;
355         ushort x_req_count;
356         ushort x_reconnect_rtn;
357         ASC_PADDR x_saved_data_addr;
358         ASC_DCNT x_saved_data_cnt;
359 } ASC_SCSIQ_4;
360
361 typedef struct asc_q_done_info {
362         ASC_SCSIQ_2 d2;
363         ASC_SCSIQ_3 d3;
364         uchar q_status;
365         uchar q_no;
366         uchar cntl;
367         uchar sense_len;
368         uchar extra_bytes;
369         uchar res;
370         ASC_DCNT remain_bytes;
371 } ASC_QDONE_INFO;
372
373 typedef struct asc_sg_list {
374         ASC_PADDR addr;
375         ASC_DCNT bytes;
376 } ASC_SG_LIST;
377
378 typedef struct asc_sg_head {
379         ushort entry_cnt;
380         ushort queue_cnt;
381         ushort entry_to_copy;
382         ushort res;
383         ASC_SG_LIST sg_list[0];
384 } ASC_SG_HEAD;
385
386 typedef struct asc_scsi_q {
387         ASC_SCSIQ_1 q1;
388         ASC_SCSIQ_2 q2;
389         uchar *cdbptr;
390         ASC_SG_HEAD *sg_head;
391         ushort remain_sg_entry_cnt;
392         ushort next_sg_index;
393 } ASC_SCSI_Q;
394
395 typedef struct asc_scsi_req_q {
396         ASC_SCSIQ_1 r1;
397         ASC_SCSIQ_2 r2;
398         uchar *cdbptr;
399         ASC_SG_HEAD *sg_head;
400         uchar *sense_ptr;
401         ASC_SCSIQ_3 r3;
402         uchar cdb[ASC_MAX_CDB_LEN];
403         uchar sense[ASC_MIN_SENSE_LEN];
404 } ASC_SCSI_REQ_Q;
405
406 typedef struct asc_scsi_bios_req_q {
407         ASC_SCSIQ_1 r1;
408         ASC_SCSIQ_2 r2;
409         uchar *cdbptr;
410         ASC_SG_HEAD *sg_head;
411         uchar *sense_ptr;
412         ASC_SCSIQ_3 r3;
413         uchar cdb[ASC_MAX_CDB_LEN];
414         uchar sense[ASC_MIN_SENSE_LEN];
415 } ASC_SCSI_BIOS_REQ_Q;
416
417 typedef struct asc_risc_q {
418         uchar fwd;
419         uchar bwd;
420         ASC_SCSIQ_1 i1;
421         ASC_SCSIQ_2 i2;
422         ASC_SCSIQ_3 i3;
423         ASC_SCSIQ_4 i4;
424 } ASC_RISC_Q;
425
426 typedef struct asc_sg_list_q {
427         uchar seq_no;
428         uchar q_no;
429         uchar cntl;
430         uchar sg_head_qp;
431         uchar sg_list_cnt;
432         uchar sg_cur_list_cnt;
433 } ASC_SG_LIST_Q;
434
435 typedef struct asc_risc_sg_list_q {
436         uchar fwd;
437         uchar bwd;
438         ASC_SG_LIST_Q sg;
439         ASC_SG_LIST sg_list[7];
440 } ASC_RISC_SG_LIST_Q;
441
442 #define ASCQ_ERR_Q_STATUS             0x0D
443 #define ASCQ_ERR_CUR_QNG              0x17
444 #define ASCQ_ERR_SG_Q_LINKS           0x18
445 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
446 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
447 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
448
449 /*
450  * Warning code values are set in ASC_DVC_VAR  'warn_code'.
451  */
452 #define ASC_WARN_NO_ERROR             0x0000
453 #define ASC_WARN_IO_PORT_ROTATE       0x0001
454 #define ASC_WARN_EEPROM_CHKSUM        0x0002
455 #define ASC_WARN_IRQ_MODIFIED         0x0004
456 #define ASC_WARN_AUTO_CONFIG          0x0008
457 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
458 #define ASC_WARN_EEPROM_RECOVER       0x0020
459 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
460
461 /*
462  * Error code values are set in ASC_DVC_VAR  'err_code'.
463  */
464 #define ASC_IERR_MCODE_CHKSUM         0x0002
465 #define ASC_IERR_SET_PC_ADDR          0x0004
466 #define ASC_IERR_START_STOP_CHIP      0x0008
467 #define ASC_IERR_SET_SCSI_ID          0x0080
468 #define ASC_IERR_BAD_SIGNATURE        0x0200
469 #define ASC_IERR_NO_BUS_TYPE          0x0400
470
471 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
472 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
473 #define ASC_MIN_FREE_Q        (0x02)
474 #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
475 #define ASC_MAX_TOTAL_QNG 240
476 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
477 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
478 #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
479 #define ASC_MAX_INRAM_TAG_QNG   16
480 #define ASC_IOADR_GAP   0x10
481 #define ASC_MAX_SYN_XFER_NO        16
482 #define ASC_SYN_MAX_OFFSET         0x0F
483 #define ASC_DEF_SDTR_OFFSET        0x0F
484 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
485 #define SYN_XFER_NS_0  25
486 #define SYN_XFER_NS_1  30
487 #define SYN_XFER_NS_2  35
488 #define SYN_XFER_NS_3  40
489 #define SYN_XFER_NS_4  50
490 #define SYN_XFER_NS_5  60
491 #define SYN_XFER_NS_6  70
492 #define SYN_XFER_NS_7  85
493 #define SYN_ULTRA_XFER_NS_0    12
494 #define SYN_ULTRA_XFER_NS_1    19
495 #define SYN_ULTRA_XFER_NS_2    25
496 #define SYN_ULTRA_XFER_NS_3    32
497 #define SYN_ULTRA_XFER_NS_4    38
498 #define SYN_ULTRA_XFER_NS_5    44
499 #define SYN_ULTRA_XFER_NS_6    50
500 #define SYN_ULTRA_XFER_NS_7    57
501 #define SYN_ULTRA_XFER_NS_8    63
502 #define SYN_ULTRA_XFER_NS_9    69
503 #define SYN_ULTRA_XFER_NS_10   75
504 #define SYN_ULTRA_XFER_NS_11   82
505 #define SYN_ULTRA_XFER_NS_12   88
506 #define SYN_ULTRA_XFER_NS_13   94
507 #define SYN_ULTRA_XFER_NS_14  100
508 #define SYN_ULTRA_XFER_NS_15  107
509
510 typedef struct ext_msg {
511         uchar msg_type;
512         uchar msg_len;
513         uchar msg_req;
514         union {
515                 struct {
516                         uchar sdtr_xfer_period;
517                         uchar sdtr_req_ack_offset;
518                 } sdtr;
519                 struct {
520                         uchar wdtr_width;
521                 } wdtr;
522                 struct {
523                         uchar mdp_b3;
524                         uchar mdp_b2;
525                         uchar mdp_b1;
526                         uchar mdp_b0;
527                 } mdp;
528         } u_ext_msg;
529         uchar res;
530 } EXT_MSG;
531
532 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
533 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
534 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
535 #define mdp_b3          u_ext_msg.mdp_b3
536 #define mdp_b2          u_ext_msg.mdp_b2
537 #define mdp_b1          u_ext_msg.mdp_b1
538 #define mdp_b0          u_ext_msg.mdp_b0
539
540 typedef struct asc_dvc_cfg {
541         ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
542         ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
543         ASC_SCSI_BIT_ID_TYPE disc_enable;
544         ASC_SCSI_BIT_ID_TYPE sdtr_enable;
545         uchar chip_scsi_id;
546         uchar isa_dma_speed;
547         uchar isa_dma_channel;
548         uchar chip_version;
549         ushort lib_serial_no;
550         ushort lib_version;
551         ushort mcode_date;
552         ushort mcode_version;
553         uchar max_tag_qng[ASC_MAX_TID + 1];
554         uchar *overrun_buf;
555         uchar sdtr_period_offset[ASC_MAX_TID + 1];
556         uchar adapter_info[6];
557 } ASC_DVC_CFG;
558
559 #define ASC_DEF_DVC_CNTL       0xFFFF
560 #define ASC_DEF_CHIP_SCSI_ID   7
561 #define ASC_DEF_ISA_DMA_SPEED  4
562 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
563 #define ASC_INIT_STATE_END_GET_CFG   0x0002
564 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
565 #define ASC_INIT_STATE_END_SET_CFG   0x0008
566 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
567 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
568 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
569 #define ASC_INIT_STATE_END_INQUIRY   0x0080
570 #define ASC_INIT_RESET_SCSI_DONE     0x0100
571 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
572 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
573 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
574 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
575 #define ASC_MIN_TAGGED_CMD  7
576 #define ASC_MAX_SCSI_RESET_WAIT      30
577
578 struct asc_dvc_var;             /* Forward Declaration. */
579
580 typedef struct asc_dvc_var {
581         PortAddr iop_base;
582         ushort err_code;
583         ushort dvc_cntl;
584         ushort bug_fix_cntl;
585         ushort bus_type;
586         ASC_SCSI_BIT_ID_TYPE init_sdtr;
587         ASC_SCSI_BIT_ID_TYPE sdtr_done;
588         ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
589         ASC_SCSI_BIT_ID_TYPE unit_not_ready;
590         ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
591         ASC_SCSI_BIT_ID_TYPE start_motor;
592         uchar scsi_reset_wait;
593         uchar chip_no;
594         char is_in_int;
595         uchar max_total_qng;
596         uchar cur_total_qng;
597         uchar in_critical_cnt;
598         uchar last_q_shortage;
599         ushort init_state;
600         uchar cur_dvc_qng[ASC_MAX_TID + 1];
601         uchar max_dvc_qng[ASC_MAX_TID + 1];
602         ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
603         ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
604         uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
605         ASC_DVC_CFG *cfg;
606         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
607         char redo_scam;
608         ushort res2;
609         uchar dos_int13_table[ASC_MAX_TID + 1];
610         ASC_DCNT max_dma_count;
611         ASC_SCSI_BIT_ID_TYPE no_scam;
612         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
613         uchar max_sdtr_index;
614         uchar host_init_sdtr_index;
615         struct asc_board *drv_ptr;
616         ASC_DCNT uc_break;
617 } ASC_DVC_VAR;
618
619 typedef struct asc_dvc_inq_info {
620         uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
621 } ASC_DVC_INQ_INFO;
622
623 typedef struct asc_cap_info {
624         ASC_DCNT lba;
625         ASC_DCNT blk_size;
626 } ASC_CAP_INFO;
627
628 typedef struct asc_cap_info_array {
629         ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
630 } ASC_CAP_INFO_ARRAY;
631
632 #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
633 #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
634 #define ASC_CNTL_INITIATOR         (ushort)0x0001
635 #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
636 #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
637 #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
638 #define ASC_CNTL_NO_SCAM           (ushort)0x0010
639 #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
640 #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
641 #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
642 #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
643 #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
644 #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
645 #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
646 #define ASC_CNTL_BURST_MODE        (ushort)0x2000
647 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
648 #define ASC_EEP_DVC_CFG_BEG_VL    2
649 #define ASC_EEP_MAX_DVC_ADDR_VL   15
650 #define ASC_EEP_DVC_CFG_BEG      32
651 #define ASC_EEP_MAX_DVC_ADDR     45
652 #define ASC_EEP_MAX_RETRY        20
653
654 /*
655  * These macros keep the chip SCSI id and ISA DMA speed
656  * bitfields in board order. C bitfields aren't portable
657  * between big and little-endian platforms so they are
658  * not used.
659  */
660
661 #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
662 #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
663 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
664    ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
665 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
666    ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
667
668 typedef struct asceep_config {
669         ushort cfg_lsw;
670         ushort cfg_msw;
671         uchar init_sdtr;
672         uchar disc_enable;
673         uchar use_cmd_qng;
674         uchar start_motor;
675         uchar max_total_qng;
676         uchar max_tag_qng;
677         uchar bios_scan;
678         uchar power_up_wait;
679         uchar no_scam;
680         uchar id_speed;         /* low order 4 bits is chip scsi id */
681         /* high order 4 bits is isa dma speed */
682         uchar dos_int13_table[ASC_MAX_TID + 1];
683         uchar adapter_info[6];
684         ushort cntl;
685         ushort chksum;
686 } ASCEEP_CONFIG;
687
688 #define ASC_EEP_CMD_READ          0x80
689 #define ASC_EEP_CMD_WRITE         0x40
690 #define ASC_EEP_CMD_WRITE_ABLE    0x30
691 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
692 #define ASC_OVERRUN_BSIZE  0x00000048UL
693 #define ASCV_MSGOUT_BEG         0x0000
694 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
695 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
696 #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
697 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
698 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
699 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
700 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
701 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
702 #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
703 #define ASCV_BREAK_ADDR           (ushort)0x0028
704 #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
705 #define ASCV_BREAK_CONTROL        (ushort)0x002C
706 #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
707
708 #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
709 #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
710 #define ASCV_MCODE_SIZE_W     (ushort)0x0034
711 #define ASCV_STOP_CODE_B      (ushort)0x0036
712 #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
713 #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
714 #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
715 #define ASCV_HALTCODE_W       (ushort)0x0040
716 #define ASCV_CHKSUM_W         (ushort)0x0042
717 #define ASCV_MC_DATE_W        (ushort)0x0044
718 #define ASCV_MC_VER_W         (ushort)0x0046
719 #define ASCV_NEXTRDY_B        (ushort)0x0048
720 #define ASCV_DONENEXT_B       (ushort)0x0049
721 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
722 #define ASCV_SCSIBUSY_B       (ushort)0x004B
723 #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
724 #define ASCV_CURCDB_B         (ushort)0x004D
725 #define ASCV_RCLUN_B          (ushort)0x004E
726 #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
727 #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
728 #define ASCV_DISC_ENABLE_B    (ushort)0x0052
729 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
730 #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
731 #define ASCV_MCODE_CNTL_B     (ushort)0x0056
732 #define ASCV_NULL_TARGET_B    (ushort)0x0057
733 #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
734 #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
735 #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
736 #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
737 #define ASCV_HOST_FLAG_B      (ushort)0x005D
738 #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
739 #define ASCV_VER_SERIAL_B     (ushort)0x0065
740 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
741 #define ASCV_WTM_FLAG_B       (ushort)0x0068
742 #define ASCV_RISC_FLAG_B      (ushort)0x006A
743 #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
744 #define ASC_HOST_FLAG_IN_ISR        0x01
745 #define ASC_HOST_FLAG_ACK_INT       0x02
746 #define ASC_RISC_FLAG_GEN_INT      0x01
747 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
748 #define IOP_CTRL         (0x0F)
749 #define IOP_STATUS       (0x0E)
750 #define IOP_INT_ACK      IOP_STATUS
751 #define IOP_REG_IFC      (0x0D)
752 #define IOP_SYN_OFFSET    (0x0B)
753 #define IOP_EXTRA_CONTROL (0x0D)
754 #define IOP_REG_PC        (0x0C)
755 #define IOP_RAM_ADDR      (0x0A)
756 #define IOP_RAM_DATA      (0x08)
757 #define IOP_EEP_DATA      (0x06)
758 #define IOP_EEP_CMD       (0x07)
759 #define IOP_VERSION       (0x03)
760 #define IOP_CONFIG_HIGH   (0x04)
761 #define IOP_CONFIG_LOW    (0x02)
762 #define IOP_SIG_BYTE      (0x01)
763 #define IOP_SIG_WORD      (0x00)
764 #define IOP_REG_DC1      (0x0E)
765 #define IOP_REG_DC0      (0x0C)
766 #define IOP_REG_SB       (0x0B)
767 #define IOP_REG_DA1      (0x0A)
768 #define IOP_REG_DA0      (0x08)
769 #define IOP_REG_SC       (0x09)
770 #define IOP_DMA_SPEED    (0x07)
771 #define IOP_REG_FLAG     (0x07)
772 #define IOP_FIFO_H       (0x06)
773 #define IOP_FIFO_L       (0x04)
774 #define IOP_REG_ID       (0x05)
775 #define IOP_REG_QP       (0x03)
776 #define IOP_REG_IH       (0x02)
777 #define IOP_REG_IX       (0x01)
778 #define IOP_REG_AX       (0x00)
779 #define IFC_REG_LOCK      (0x00)
780 #define IFC_REG_UNLOCK    (0x09)
781 #define IFC_WR_EN_FILTER  (0x10)
782 #define IFC_RD_NO_EEPROM  (0x10)
783 #define IFC_SLEW_RATE     (0x20)
784 #define IFC_ACT_NEG       (0x40)
785 #define IFC_INP_FILTER    (0x80)
786 #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
787 #define SC_SEL   (uchar)(0x80)
788 #define SC_BSY   (uchar)(0x40)
789 #define SC_ACK   (uchar)(0x20)
790 #define SC_REQ   (uchar)(0x10)
791 #define SC_ATN   (uchar)(0x08)
792 #define SC_IO    (uchar)(0x04)
793 #define SC_CD    (uchar)(0x02)
794 #define SC_MSG   (uchar)(0x01)
795 #define SEC_SCSI_CTL         (uchar)(0x80)
796 #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
797 #define SEC_SLEW_RATE        (uchar)(0x20)
798 #define SEC_ENABLE_FILTER    (uchar)(0x10)
799 #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
800 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
801 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
802 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
803 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
804 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
805 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
806 #define ASC_MAX_QNO        0xF8
807 #define ASC_DATA_SEC_BEG   (ushort)0x0080
808 #define ASC_DATA_SEC_END   (ushort)0x0080
809 #define ASC_CODE_SEC_BEG   (ushort)0x0080
810 #define ASC_CODE_SEC_END   (ushort)0x0080
811 #define ASC_QADR_BEG       (0x4000)
812 #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
813 #define ASC_QADR_END       (ushort)0x7FFF
814 #define ASC_QLAST_ADR      (ushort)0x7FC0
815 #define ASC_QBLK_SIZE      0x40
816 #define ASC_BIOS_DATA_QBEG 0xF8
817 #define ASC_MIN_ACTIVE_QNO 0x01
818 #define ASC_QLINK_END      0xFF
819 #define ASC_EEPROM_WORDS   0x10
820 #define ASC_MAX_MGS_LEN    0x10
821 #define ASC_BIOS_ADDR_DEF  0xDC00
822 #define ASC_BIOS_SIZE      0x3800
823 #define ASC_BIOS_RAM_OFF   0x3800
824 #define ASC_BIOS_RAM_SIZE  0x800
825 #define ASC_BIOS_MIN_ADDR  0xC000
826 #define ASC_BIOS_MAX_ADDR  0xEC00
827 #define ASC_BIOS_BANK_SIZE 0x0400
828 #define ASC_MCODE_START_ADDR  0x0080
829 #define ASC_CFG0_HOST_INT_ON    0x0020
830 #define ASC_CFG0_BIOS_ON        0x0040
831 #define ASC_CFG0_VERA_BURST_ON  0x0080
832 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
833 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
834 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
835 #define ASC_CFG_MSW_CLR_MASK    0x3080
836 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
837 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
838 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
839 #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
840 #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
841 #define CSW_TEST2             (ASC_CS_TYPE)0x0400
842 #define CSW_TEST3             (ASC_CS_TYPE)0x0200
843 #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
844 #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
845 #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
846 #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
847 #define CSW_HALTED            (ASC_CS_TYPE)0x0010
848 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
849 #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
850 #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
851 #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
852 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
853 #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
854 #define CIW_TEST1        (ASC_CS_TYPE)0x0200
855 #define CIW_TEST2        (ASC_CS_TYPE)0x0400
856 #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
857 #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
858 #define CC_CHIP_RESET   (uchar)0x80
859 #define CC_SCSI_RESET   (uchar)0x40
860 #define CC_HALT         (uchar)0x20
861 #define CC_SINGLE_STEP  (uchar)0x10
862 #define CC_DMA_ABLE     (uchar)0x08
863 #define CC_TEST         (uchar)0x04
864 #define CC_BANK_ONE     (uchar)0x02
865 #define CC_DIAG         (uchar)0x01
866 #define ASC_1000_ID0W      0x04C1
867 #define ASC_1000_ID0W_FIX  0x00C1
868 #define ASC_1000_ID1B      0x25
869 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
870 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
871 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
872 #define INS_HALTINT        (ushort)0x6281
873 #define INS_HALT           (ushort)0x6280
874 #define INS_SINT           (ushort)0x6200
875 #define INS_RFLAG_WTM      (ushort)0x7380
876 #define ASC_MC_SAVE_CODE_WSIZE  0x500
877 #define ASC_MC_SAVE_DATA_WSIZE  0x40
878
879 typedef struct asc_mc_saved {
880         ushort data[ASC_MC_SAVE_DATA_WSIZE];
881         ushort code[ASC_MC_SAVE_CODE_WSIZE];
882 } ASC_MC_SAVED;
883
884 #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
885 #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
886 #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
887 #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
888 #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
889 #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
890 #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
891 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
892 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
893 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
894 #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
895 #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
896 #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
897 #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
898 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
899 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
900 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
901 #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
902 #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
903 #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
904 #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
905 #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
906 #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
907 #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
908 #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
909 #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
910 #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
911 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
912 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
913 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
914 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
915 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
916 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
917 #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
918 #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
919 #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
920 #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
921 #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
922 #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
923 #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
924 #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
925 #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
926 #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
927 #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
928 #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
929 #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
930 #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
931 #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
932 #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
933 #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
934 #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
935 #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
936 #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
937 #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
938 #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
939 #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
940 #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
941 #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
942 #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
943 #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
944 #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
945 #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
946 #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
947 #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
948 #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
949 #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
950 #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
951 #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
952
953 #define ADV_LIB_VERSION_MAJOR  5
954 #define ADV_LIB_VERSION_MINOR  14
955
956 /*
957  * Define Adv Library required special types.
958  */
959
960 /*
961  * Portable Data Types
962  *
963  * Any instance where a 32-bit long or pointer type is assumed
964  * for precision or HW defined structures, the following define
965  * types must be used. In Linux the char, short, and int types
966  * are all consistent at 8, 16, and 32 bits respectively. Pointers
967  * and long types are 64 bits on Alpha and UltraSPARC.
968  */
969 #define ADV_PADDR __u32         /* Physical address data type. */
970 #define ADV_VADDR __u32         /* Virtual address data type. */
971 #define ADV_DCNT  __u32         /* Unsigned Data count type. */
972 #define ADV_SDCNT __s32         /* Signed Data count type. */
973
974 /*
975  * These macros are used to convert a virtual address to a
976  * 32-bit value. This currently can be used on Linux Alpha
977  * which uses 64-bit virtual address but a 32-bit bus address.
978  * This is likely to break in the future, but doing this now
979  * will give us time to change the HW and FW to handle 64-bit
980  * addresses.
981  */
982 #define ADV_VADDR_TO_U32   virt_to_bus
983 #define ADV_U32_TO_VADDR   bus_to_virt
984
985 #define AdvPortAddr  void __iomem *     /* Virtual memory address size */
986
987 /*
988  * Define Adv Library required memory access macros.
989  */
990 #define ADV_MEM_READB(addr) readb(addr)
991 #define ADV_MEM_READW(addr) readw(addr)
992 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
993 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
994 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
995
996 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
997
998 /*
999  * Define total number of simultaneous maximum element scatter-gather
1000  * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1001  * maximum number of outstanding commands per wide host adapter. Each
1002  * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1003  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1004  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1005  * structures or 255 scatter-gather elements.
1006  *
1007  */
1008 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
1009
1010 /*
1011  * Define Adv Library required maximum number of scatter-gather
1012  * elements per request.
1013  */
1014 #define ADV_MAX_SG_LIST         255
1015
1016 /* Number of SG blocks needed. */
1017 #define ADV_NUM_SG_BLOCK \
1018     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1019
1020 /* Total contiguous memory needed for SG blocks. */
1021 #define ADV_SG_TOTAL_MEM_SIZE \
1022     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
1023
1024 #define ADV_PAGE_SIZE PAGE_SIZE
1025
1026 #define ADV_NUM_PAGE_CROSSING \
1027     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1028
1029 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
1030 #define ADV_EEP_DVC_CFG_END             (0x15)
1031 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
1032 #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
1033
1034 #define ADV_EEP_DELAY_MS                100
1035
1036 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
1037 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
1038 /*
1039  * For the ASC3550 Bit 13 is Termination Polarity control bit.
1040  * For later ICs Bit 13 controls whether the CIS (Card Information
1041  * Service Section) is loaded from EEPROM.
1042  */
1043 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
1044 #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
1045 /*
1046  * ASC38C1600 Bit 11
1047  *
1048  * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1049  * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1050  * Function 0 will specify INT B.
1051  *
1052  * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1053  * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1054  * Function 1 will specify INT A.
1055  */
1056 #define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
1057
1058 typedef struct adveep_3550_config {
1059         /* Word Offset, Description */
1060
1061         ushort cfg_lsw;         /* 00 power up initialization */
1062         /*  bit 13 set - Term Polarity Control */
1063         /*  bit 14 set - BIOS Enable */
1064         /*  bit 15 set - Big Endian Mode */
1065         ushort cfg_msw;         /* 01 unused      */
1066         ushort disc_enable;     /* 02 disconnect enable */
1067         ushort wdtr_able;       /* 03 Wide DTR able */
1068         ushort sdtr_able;       /* 04 Synchronous DTR able */
1069         ushort start_motor;     /* 05 send start up motor */
1070         ushort tagqng_able;     /* 06 tag queuing able */
1071         ushort bios_scan;       /* 07 BIOS device control */
1072         ushort scam_tolerant;   /* 08 no scam */
1073
1074         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1075         uchar bios_boot_delay;  /*    power up wait */
1076
1077         uchar scsi_reset_delay; /* 10 reset delay */
1078         uchar bios_id_lun;      /*    first boot device scsi id & lun */
1079         /*    high nibble is lun */
1080         /*    low nibble is scsi id */
1081
1082         uchar termination;      /* 11 0 - automatic */
1083         /*    1 - low off / high off */
1084         /*    2 - low off / high on */
1085         /*    3 - low on  / high on */
1086         /*    There is no low on  / high off */
1087
1088         uchar reserved1;        /*    reserved byte (not used) */
1089
1090         ushort bios_ctrl;       /* 12 BIOS control bits */
1091         /*  bit 0  BIOS don't act as initiator. */
1092         /*  bit 1  BIOS > 1 GB support */
1093         /*  bit 2  BIOS > 2 Disk Support */
1094         /*  bit 3  BIOS don't support removables */
1095         /*  bit 4  BIOS support bootable CD */
1096         /*  bit 5  BIOS scan enabled */
1097         /*  bit 6  BIOS support multiple LUNs */
1098         /*  bit 7  BIOS display of message */
1099         /*  bit 8  SCAM disabled */
1100         /*  bit 9  Reset SCSI bus during init. */
1101         /*  bit 10 */
1102         /*  bit 11 No verbose initialization. */
1103         /*  bit 12 SCSI parity enabled */
1104         /*  bit 13 */
1105         /*  bit 14 */
1106         /*  bit 15 */
1107         ushort ultra_able;      /* 13 ULTRA speed able */
1108         ushort reserved2;       /* 14 reserved */
1109         uchar max_host_qng;     /* 15 maximum host queuing */
1110         uchar max_dvc_qng;      /*    maximum per device queuing */
1111         ushort dvc_cntl;        /* 16 control bit for driver */
1112         ushort bug_fix;         /* 17 control bit for bug fix */
1113         ushort serial_number_word1;     /* 18 Board serial number word 1 */
1114         ushort serial_number_word2;     /* 19 Board serial number word 2 */
1115         ushort serial_number_word3;     /* 20 Board serial number word 3 */
1116         ushort check_sum;       /* 21 EEP check sum */
1117         uchar oem_name[16];     /* 22 OEM name */
1118         ushort dvc_err_code;    /* 30 last device driver error code */
1119         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1120         ushort adv_err_addr;    /* 32 last uc error address */
1121         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1122         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1123         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1124         ushort num_of_err;      /* 36 number of error */
1125 } ADVEEP_3550_CONFIG;
1126
1127 typedef struct adveep_38C0800_config {
1128         /* Word Offset, Description */
1129
1130         ushort cfg_lsw;         /* 00 power up initialization */
1131         /*  bit 13 set - Load CIS */
1132         /*  bit 14 set - BIOS Enable */
1133         /*  bit 15 set - Big Endian Mode */
1134         ushort cfg_msw;         /* 01 unused      */
1135         ushort disc_enable;     /* 02 disconnect enable */
1136         ushort wdtr_able;       /* 03 Wide DTR able */
1137         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
1138         ushort start_motor;     /* 05 send start up motor */
1139         ushort tagqng_able;     /* 06 tag queuing able */
1140         ushort bios_scan;       /* 07 BIOS device control */
1141         ushort scam_tolerant;   /* 08 no scam */
1142
1143         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1144         uchar bios_boot_delay;  /*    power up wait */
1145
1146         uchar scsi_reset_delay; /* 10 reset delay */
1147         uchar bios_id_lun;      /*    first boot device scsi id & lun */
1148         /*    high nibble is lun */
1149         /*    low nibble is scsi id */
1150
1151         uchar termination_se;   /* 11 0 - automatic */
1152         /*    1 - low off / high off */
1153         /*    2 - low off / high on */
1154         /*    3 - low on  / high on */
1155         /*    There is no low on  / high off */
1156
1157         uchar termination_lvd;  /* 11 0 - automatic */
1158         /*    1 - low off / high off */
1159         /*    2 - low off / high on */
1160         /*    3 - low on  / high on */
1161         /*    There is no low on  / high off */
1162
1163         ushort bios_ctrl;       /* 12 BIOS control bits */
1164         /*  bit 0  BIOS don't act as initiator. */
1165         /*  bit 1  BIOS > 1 GB support */
1166         /*  bit 2  BIOS > 2 Disk Support */
1167         /*  bit 3  BIOS don't support removables */
1168         /*  bit 4  BIOS support bootable CD */
1169         /*  bit 5  BIOS scan enabled */
1170         /*  bit 6  BIOS support multiple LUNs */
1171         /*  bit 7  BIOS display of message */
1172         /*  bit 8  SCAM disabled */
1173         /*  bit 9  Reset SCSI bus during init. */
1174         /*  bit 10 */
1175         /*  bit 11 No verbose initialization. */
1176         /*  bit 12 SCSI parity enabled */
1177         /*  bit 13 */
1178         /*  bit 14 */
1179         /*  bit 15 */
1180         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
1181         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
1182         uchar max_host_qng;     /* 15 maximum host queueing */
1183         uchar max_dvc_qng;      /*    maximum per device queuing */
1184         ushort dvc_cntl;        /* 16 control bit for driver */
1185         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
1186         ushort serial_number_word1;     /* 18 Board serial number word 1 */
1187         ushort serial_number_word2;     /* 19 Board serial number word 2 */
1188         ushort serial_number_word3;     /* 20 Board serial number word 3 */
1189         ushort check_sum;       /* 21 EEP check sum */
1190         uchar oem_name[16];     /* 22 OEM name */
1191         ushort dvc_err_code;    /* 30 last device driver error code */
1192         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1193         ushort adv_err_addr;    /* 32 last uc error address */
1194         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1195         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1196         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1197         ushort reserved36;      /* 36 reserved */
1198         ushort reserved37;      /* 37 reserved */
1199         ushort reserved38;      /* 38 reserved */
1200         ushort reserved39;      /* 39 reserved */
1201         ushort reserved40;      /* 40 reserved */
1202         ushort reserved41;      /* 41 reserved */
1203         ushort reserved42;      /* 42 reserved */
1204         ushort reserved43;      /* 43 reserved */
1205         ushort reserved44;      /* 44 reserved */
1206         ushort reserved45;      /* 45 reserved */
1207         ushort reserved46;      /* 46 reserved */
1208         ushort reserved47;      /* 47 reserved */
1209         ushort reserved48;      /* 48 reserved */
1210         ushort reserved49;      /* 49 reserved */
1211         ushort reserved50;      /* 50 reserved */
1212         ushort reserved51;      /* 51 reserved */
1213         ushort reserved52;      /* 52 reserved */
1214         ushort reserved53;      /* 53 reserved */
1215         ushort reserved54;      /* 54 reserved */
1216         ushort reserved55;      /* 55 reserved */
1217         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
1218         ushort cisprt_msw;      /* 57 CIS PTR MSW */
1219         ushort subsysvid;       /* 58 SubSystem Vendor ID */
1220         ushort subsysid;        /* 59 SubSystem ID */
1221         ushort reserved60;      /* 60 reserved */
1222         ushort reserved61;      /* 61 reserved */
1223         ushort reserved62;      /* 62 reserved */
1224         ushort reserved63;      /* 63 reserved */
1225 } ADVEEP_38C0800_CONFIG;
1226
1227 typedef struct adveep_38C1600_config {
1228         /* Word Offset, Description */
1229
1230         ushort cfg_lsw;         /* 00 power up initialization */
1231         /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
1232         /*       clear - Func. 0 INTA, Func. 1 INTB */
1233         /*  bit 13 set - Load CIS */
1234         /*  bit 14 set - BIOS Enable */
1235         /*  bit 15 set - Big Endian Mode */
1236         ushort cfg_msw;         /* 01 unused */
1237         ushort disc_enable;     /* 02 disconnect enable */
1238         ushort wdtr_able;       /* 03 Wide DTR able */
1239         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
1240         ushort start_motor;     /* 05 send start up motor */
1241         ushort tagqng_able;     /* 06 tag queuing able */
1242         ushort bios_scan;       /* 07 BIOS device control */
1243         ushort scam_tolerant;   /* 08 no scam */
1244
1245         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1246         uchar bios_boot_delay;  /*    power up wait */
1247
1248         uchar scsi_reset_delay; /* 10 reset delay */
1249         uchar bios_id_lun;      /*    first boot device scsi id & lun */
1250         /*    high nibble is lun */
1251         /*    low nibble is scsi id */
1252
1253         uchar termination_se;   /* 11 0 - automatic */
1254         /*    1 - low off / high off */
1255         /*    2 - low off / high on */
1256         /*    3 - low on  / high on */
1257         /*    There is no low on  / high off */
1258
1259         uchar termination_lvd;  /* 11 0 - automatic */
1260         /*    1 - low off / high off */
1261         /*    2 - low off / high on */
1262         /*    3 - low on  / high on */
1263         /*    There is no low on  / high off */
1264
1265         ushort bios_ctrl;       /* 12 BIOS control bits */
1266         /*  bit 0  BIOS don't act as initiator. */
1267         /*  bit 1  BIOS > 1 GB support */
1268         /*  bit 2  BIOS > 2 Disk Support */
1269         /*  bit 3  BIOS don't support removables */
1270         /*  bit 4  BIOS support bootable CD */
1271         /*  bit 5  BIOS scan enabled */
1272         /*  bit 6  BIOS support multiple LUNs */
1273         /*  bit 7  BIOS display of message */
1274         /*  bit 8  SCAM disabled */
1275         /*  bit 9  Reset SCSI bus during init. */
1276         /*  bit 10 Basic Integrity Checking disabled */
1277         /*  bit 11 No verbose initialization. */
1278         /*  bit 12 SCSI parity enabled */
1279         /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1280         /*  bit 14 */
1281         /*  bit 15 */
1282         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
1283         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
1284         uchar max_host_qng;     /* 15 maximum host queueing */
1285         uchar max_dvc_qng;      /*    maximum per device queuing */
1286         ushort dvc_cntl;        /* 16 control bit for driver */
1287         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
1288         ushort serial_number_word1;     /* 18 Board serial number word 1 */
1289         ushort serial_number_word2;     /* 19 Board serial number word 2 */
1290         ushort serial_number_word3;     /* 20 Board serial number word 3 */
1291         ushort check_sum;       /* 21 EEP check sum */
1292         uchar oem_name[16];     /* 22 OEM name */
1293         ushort dvc_err_code;    /* 30 last device driver error code */
1294         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1295         ushort adv_err_addr;    /* 32 last uc error address */
1296         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1297         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1298         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1299         ushort reserved36;      /* 36 reserved */
1300         ushort reserved37;      /* 37 reserved */
1301         ushort reserved38;      /* 38 reserved */
1302         ushort reserved39;      /* 39 reserved */
1303         ushort reserved40;      /* 40 reserved */
1304         ushort reserved41;      /* 41 reserved */
1305         ushort reserved42;      /* 42 reserved */
1306         ushort reserved43;      /* 43 reserved */
1307         ushort reserved44;      /* 44 reserved */
1308         ushort reserved45;      /* 45 reserved */
1309         ushort reserved46;      /* 46 reserved */
1310         ushort reserved47;      /* 47 reserved */
1311         ushort reserved48;      /* 48 reserved */
1312         ushort reserved49;      /* 49 reserved */
1313         ushort reserved50;      /* 50 reserved */
1314         ushort reserved51;      /* 51 reserved */
1315         ushort reserved52;      /* 52 reserved */
1316         ushort reserved53;      /* 53 reserved */
1317         ushort reserved54;      /* 54 reserved */
1318         ushort reserved55;      /* 55 reserved */
1319         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
1320         ushort cisprt_msw;      /* 57 CIS PTR MSW */
1321         ushort subsysvid;       /* 58 SubSystem Vendor ID */
1322         ushort subsysid;        /* 59 SubSystem ID */
1323         ushort reserved60;      /* 60 reserved */
1324         ushort reserved61;      /* 61 reserved */
1325         ushort reserved62;      /* 62 reserved */
1326         ushort reserved63;      /* 63 reserved */
1327 } ADVEEP_38C1600_CONFIG;
1328
1329 /*
1330  * EEPROM Commands
1331  */
1332 #define ASC_EEP_CMD_DONE             0x0200
1333
1334 /* bios_ctrl */
1335 #define BIOS_CTRL_BIOS               0x0001
1336 #define BIOS_CTRL_EXTENDED_XLAT      0x0002
1337 #define BIOS_CTRL_GT_2_DISK          0x0004
1338 #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
1339 #define BIOS_CTRL_BOOTABLE_CD        0x0010
1340 #define BIOS_CTRL_MULTIPLE_LUN       0x0040
1341 #define BIOS_CTRL_DISPLAY_MSG        0x0080
1342 #define BIOS_CTRL_NO_SCAM            0x0100
1343 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
1344 #define BIOS_CTRL_INIT_VERBOSE       0x0800
1345 #define BIOS_CTRL_SCSI_PARITY        0x1000
1346 #define BIOS_CTRL_AIPP_DIS           0x2000
1347
1348 #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
1349
1350 #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
1351
1352 /*
1353  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1354  * a special 16K Adv Library and Microcode version. After the issue is
1355  * resolved, should restore 32K support.
1356  *
1357  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
1358  */
1359 #define ADV_38C1600_MEMSIZE  0x4000     /* 16 KB Internal Memory */
1360
1361 /*
1362  * Byte I/O register address from base of 'iop_base'.
1363  */
1364 #define IOPB_INTR_STATUS_REG    0x00
1365 #define IOPB_CHIP_ID_1          0x01
1366 #define IOPB_INTR_ENABLES       0x02
1367 #define IOPB_CHIP_TYPE_REV      0x03
1368 #define IOPB_RES_ADDR_4         0x04
1369 #define IOPB_RES_ADDR_5         0x05
1370 #define IOPB_RAM_DATA           0x06
1371 #define IOPB_RES_ADDR_7         0x07
1372 #define IOPB_FLAG_REG           0x08
1373 #define IOPB_RES_ADDR_9         0x09
1374 #define IOPB_RISC_CSR           0x0A
1375 #define IOPB_RES_ADDR_B         0x0B
1376 #define IOPB_RES_ADDR_C         0x0C
1377 #define IOPB_RES_ADDR_D         0x0D
1378 #define IOPB_SOFT_OVER_WR       0x0E
1379 #define IOPB_RES_ADDR_F         0x0F
1380 #define IOPB_MEM_CFG            0x10
1381 #define IOPB_RES_ADDR_11        0x11
1382 #define IOPB_GPIO_DATA          0x12
1383 #define IOPB_RES_ADDR_13        0x13
1384 #define IOPB_FLASH_PAGE         0x14
1385 #define IOPB_RES_ADDR_15        0x15
1386 #define IOPB_GPIO_CNTL          0x16
1387 #define IOPB_RES_ADDR_17        0x17
1388 #define IOPB_FLASH_DATA         0x18
1389 #define IOPB_RES_ADDR_19        0x19
1390 #define IOPB_RES_ADDR_1A        0x1A
1391 #define IOPB_RES_ADDR_1B        0x1B
1392 #define IOPB_RES_ADDR_1C        0x1C
1393 #define IOPB_RES_ADDR_1D        0x1D
1394 #define IOPB_RES_ADDR_1E        0x1E
1395 #define IOPB_RES_ADDR_1F        0x1F
1396 #define IOPB_DMA_CFG0           0x20
1397 #define IOPB_DMA_CFG1           0x21
1398 #define IOPB_TICKLE             0x22
1399 #define IOPB_DMA_REG_WR         0x23
1400 #define IOPB_SDMA_STATUS        0x24
1401 #define IOPB_SCSI_BYTE_CNT      0x25
1402 #define IOPB_HOST_BYTE_CNT      0x26
1403 #define IOPB_BYTE_LEFT_TO_XFER  0x27
1404 #define IOPB_BYTE_TO_XFER_0     0x28
1405 #define IOPB_BYTE_TO_XFER_1     0x29
1406 #define IOPB_BYTE_TO_XFER_2     0x2A
1407 #define IOPB_BYTE_TO_XFER_3     0x2B
1408 #define IOPB_ACC_GRP            0x2C
1409 #define IOPB_RES_ADDR_2D        0x2D
1410 #define IOPB_DEV_ID             0x2E
1411 #define IOPB_RES_ADDR_2F        0x2F
1412 #define IOPB_SCSI_DATA          0x30
1413 #define IOPB_RES_ADDR_31        0x31
1414 #define IOPB_RES_ADDR_32        0x32
1415 #define IOPB_SCSI_DATA_HSHK     0x33
1416 #define IOPB_SCSI_CTRL          0x34
1417 #define IOPB_RES_ADDR_35        0x35
1418 #define IOPB_RES_ADDR_36        0x36
1419 #define IOPB_RES_ADDR_37        0x37
1420 #define IOPB_RAM_BIST           0x38
1421 #define IOPB_PLL_TEST           0x39
1422 #define IOPB_PCI_INT_CFG        0x3A
1423 #define IOPB_RES_ADDR_3B        0x3B
1424 #define IOPB_RFIFO_CNT          0x3C
1425 #define IOPB_RES_ADDR_3D        0x3D
1426 #define IOPB_RES_ADDR_3E        0x3E
1427 #define IOPB_RES_ADDR_3F        0x3F
1428
1429 /*
1430  * Word I/O register address from base of 'iop_base'.
1431  */
1432 #define IOPW_CHIP_ID_0          0x00    /* CID0  */
1433 #define IOPW_CTRL_REG           0x02    /* CC    */
1434 #define IOPW_RAM_ADDR           0x04    /* LA    */
1435 #define IOPW_RAM_DATA           0x06    /* LD    */
1436 #define IOPW_RES_ADDR_08        0x08
1437 #define IOPW_RISC_CSR           0x0A    /* CSR   */
1438 #define IOPW_SCSI_CFG0          0x0C    /* CFG0  */
1439 #define IOPW_SCSI_CFG1          0x0E    /* CFG1  */
1440 #define IOPW_RES_ADDR_10        0x10
1441 #define IOPW_SEL_MASK           0x12    /* SM    */
1442 #define IOPW_RES_ADDR_14        0x14
1443 #define IOPW_FLASH_ADDR         0x16    /* FA    */
1444 #define IOPW_RES_ADDR_18        0x18
1445 #define IOPW_EE_CMD             0x1A    /* EC    */
1446 #define IOPW_EE_DATA            0x1C    /* ED    */
1447 #define IOPW_SFIFO_CNT          0x1E    /* SFC   */
1448 #define IOPW_RES_ADDR_20        0x20
1449 #define IOPW_Q_BASE             0x22    /* QB    */
1450 #define IOPW_QP                 0x24    /* QP    */
1451 #define IOPW_IX                 0x26    /* IX    */
1452 #define IOPW_SP                 0x28    /* SP    */
1453 #define IOPW_PC                 0x2A    /* PC    */
1454 #define IOPW_RES_ADDR_2C        0x2C
1455 #define IOPW_RES_ADDR_2E        0x2E
1456 #define IOPW_SCSI_DATA          0x30    /* SD    */
1457 #define IOPW_SCSI_DATA_HSHK     0x32    /* SDH   */
1458 #define IOPW_SCSI_CTRL          0x34    /* SC    */
1459 #define IOPW_HSHK_CFG           0x36    /* HCFG  */
1460 #define IOPW_SXFR_STATUS        0x36    /* SXS   */
1461 #define IOPW_SXFR_CNTL          0x38    /* SXL   */
1462 #define IOPW_SXFR_CNTH          0x3A    /* SXH   */
1463 #define IOPW_RES_ADDR_3C        0x3C
1464 #define IOPW_RFIFO_DATA         0x3E    /* RFD   */
1465
1466 /*
1467  * Doubleword I/O register address from base of 'iop_base'.
1468  */
1469 #define IOPDW_RES_ADDR_0         0x00
1470 #define IOPDW_RAM_DATA           0x04
1471 #define IOPDW_RES_ADDR_8         0x08
1472 #define IOPDW_RES_ADDR_C         0x0C
1473 #define IOPDW_RES_ADDR_10        0x10
1474 #define IOPDW_COMMA              0x14
1475 #define IOPDW_COMMB              0x18
1476 #define IOPDW_RES_ADDR_1C        0x1C
1477 #define IOPDW_SDMA_ADDR0         0x20
1478 #define IOPDW_SDMA_ADDR1         0x24
1479 #define IOPDW_SDMA_COUNT         0x28
1480 #define IOPDW_SDMA_ERROR         0x2C
1481 #define IOPDW_RDMA_ADDR0         0x30
1482 #define IOPDW_RDMA_ADDR1         0x34
1483 #define IOPDW_RDMA_COUNT         0x38
1484 #define IOPDW_RDMA_ERROR         0x3C
1485
1486 #define ADV_CHIP_ID_BYTE         0x25
1487 #define ADV_CHIP_ID_WORD         0x04C1
1488
1489 #define ADV_INTR_ENABLE_HOST_INTR                   0x01
1490 #define ADV_INTR_ENABLE_SEL_INTR                    0x02
1491 #define ADV_INTR_ENABLE_DPR_INTR                    0x04
1492 #define ADV_INTR_ENABLE_RTA_INTR                    0x08
1493 #define ADV_INTR_ENABLE_RMA_INTR                    0x10
1494 #define ADV_INTR_ENABLE_RST_INTR                    0x20
1495 #define ADV_INTR_ENABLE_DPE_INTR                    0x40
1496 #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
1497
1498 #define ADV_INTR_STATUS_INTRA            0x01
1499 #define ADV_INTR_STATUS_INTRB            0x02
1500 #define ADV_INTR_STATUS_INTRC            0x04
1501
1502 #define ADV_RISC_CSR_STOP           (0x0000)
1503 #define ADV_RISC_TEST_COND          (0x2000)
1504 #define ADV_RISC_CSR_RUN            (0x4000)
1505 #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
1506
1507 #define ADV_CTRL_REG_HOST_INTR      0x0100
1508 #define ADV_CTRL_REG_SEL_INTR       0x0200
1509 #define ADV_CTRL_REG_DPR_INTR       0x0400
1510 #define ADV_CTRL_REG_RTA_INTR       0x0800
1511 #define ADV_CTRL_REG_RMA_INTR       0x1000
1512 #define ADV_CTRL_REG_RES_BIT14      0x2000
1513 #define ADV_CTRL_REG_DPE_INTR       0x4000
1514 #define ADV_CTRL_REG_POWER_DONE     0x8000
1515 #define ADV_CTRL_REG_ANY_INTR       0xFF00
1516
1517 #define ADV_CTRL_REG_CMD_RESET             0x00C6
1518 #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
1519 #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
1520 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
1521 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
1522
1523 #define ADV_TICKLE_NOP                      0x00
1524 #define ADV_TICKLE_A                        0x01
1525 #define ADV_TICKLE_B                        0x02
1526 #define ADV_TICKLE_C                        0x03
1527
1528 #define AdvIsIntPending(port) \
1529     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1530
1531 /*
1532  * SCSI_CFG0 Register bit definitions
1533  */
1534 #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
1535 #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
1536 #define EVEN_PARITY     0x1000  /* Select Even Parity */
1537 #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1538 #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
1539 #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
1540 #define SCAM_EN         0x0080  /* Enable SCAM selection */
1541 #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1542 #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1543 #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
1544 #define OUR_ID          0x000F  /* SCSI ID */
1545
1546 /*
1547  * SCSI_CFG1 Register bit definitions
1548  */
1549 #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
1550 #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1551 #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
1552 #define FILTER_SEL      0x0C00  /* Filter Period Selection */
1553 #define  FLTR_DISABLE    0x0000 /* Input Filtering Disabled */
1554 #define  FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1555 #define  FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1556 #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
1557 #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
1558 #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
1559 #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
1560 #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
1561 #define  TERM_CTL_H      0x0020 /* Enable External SCSI Upper Termination */
1562 #define  TERM_CTL_L      0x0010 /* Enable External SCSI Lower Termination */
1563 #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
1564
1565 /*
1566  * Addendum for ASC-38C0800 Chip
1567  *
1568  * The ASC-38C1600 Chip uses the same definitions except that the
1569  * bus mode override bits [12:10] have been moved to byte register
1570  * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1571  * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1572  * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1573  * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1574  * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1575  */
1576 #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
1577 #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
1578 #define  HVD             0x1000 /* HVD Device Detect */
1579 #define  LVD             0x0800 /* LVD Device Detect */
1580 #define  SE              0x0400 /* SE Device Detect */
1581 #define TERM_LVD        0x00C0  /* LVD Termination Bits */
1582 #define  TERM_LVD_HI     0x0080 /* Enable LVD Upper Termination */
1583 #define  TERM_LVD_LO     0x0040 /* Enable LVD Lower Termination */
1584 #define TERM_SE         0x0030  /* SE Termination Bits */
1585 #define  TERM_SE_HI      0x0020 /* Enable SE Upper Termination */
1586 #define  TERM_SE_LO      0x0010 /* Enable SE Lower Termination */
1587 #define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
1588 #define  C_DET3          0x0008 /* Cable Detect for LVD External Wide */
1589 #define  C_DET2          0x0004 /* Cable Detect for LVD Internal Wide */
1590 #define C_DET_SE        0x0003  /* SE Cable Detect Bits */
1591 #define  C_DET1          0x0002 /* Cable Detect for SE Internal Wide */
1592 #define  C_DET0          0x0001 /* Cable Detect for SE Internal Narrow */
1593
1594 #define CABLE_ILLEGAL_A 0x7
1595     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
1596
1597 #define CABLE_ILLEGAL_B 0xB
1598     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
1599
1600 /*
1601  * MEM_CFG Register bit definitions
1602  */
1603 #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
1604 #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
1605 #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
1606 #define  RAM_SZ_2KB      0x00   /* 2 KB */
1607 #define  RAM_SZ_4KB      0x04   /* 4 KB */
1608 #define  RAM_SZ_8KB      0x08   /* 8 KB */
1609 #define  RAM_SZ_16KB     0x0C   /* 16 KB */
1610 #define  RAM_SZ_32KB     0x10   /* 32 KB */
1611 #define  RAM_SZ_64KB     0x14   /* 64 KB */
1612
1613 /*
1614  * DMA_CFG0 Register bit definitions
1615  *
1616  * This register is only accessible to the host.
1617  */
1618 #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
1619 #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
1620 #define  FIFO_THRESH_16B  0x00  /* 16 bytes */
1621 #define  FIFO_THRESH_32B  0x20  /* 32 bytes */
1622 #define  FIFO_THRESH_48B  0x30  /* 48 bytes */
1623 #define  FIFO_THRESH_64B  0x40  /* 64 bytes */
1624 #define  FIFO_THRESH_80B  0x50  /* 80 bytes (default) */
1625 #define  FIFO_THRESH_96B  0x60  /* 96 bytes */
1626 #define  FIFO_THRESH_112B 0x70  /* 112 bytes */
1627 #define START_CTL       0x0C    /* DMA start conditions */
1628 #define  START_CTL_TH    0x00   /* Wait threshold level (default) */
1629 #define  START_CTL_ID    0x04   /* Wait SDMA/SBUS idle */
1630 #define  START_CTL_THID  0x08   /* Wait threshold and SDMA/SBUS idle */
1631 #define  START_CTL_EMFU  0x0C   /* Wait SDMA FIFO empty/full */
1632 #define READ_CMD        0x03    /* Memory Read Method */
1633 #define  READ_CMD_MR     0x00   /* Memory Read */
1634 #define  READ_CMD_MRL    0x02   /* Memory Read Long */
1635 #define  READ_CMD_MRM    0x03   /* Memory Read Multiple (default) */
1636
1637 /*
1638  * ASC-38C0800 RAM BIST Register bit definitions
1639  */
1640 #define RAM_TEST_MODE         0x80
1641 #define PRE_TEST_MODE         0x40
1642 #define NORMAL_MODE           0x00
1643 #define RAM_TEST_DONE         0x10
1644 #define RAM_TEST_STATUS       0x0F
1645 #define  RAM_TEST_HOST_ERROR   0x08
1646 #define  RAM_TEST_INTRAM_ERROR 0x04
1647 #define  RAM_TEST_RISC_ERROR   0x02
1648 #define  RAM_TEST_SCSI_ERROR   0x01
1649 #define  RAM_TEST_SUCCESS      0x00
1650 #define PRE_TEST_VALUE        0x05
1651 #define NORMAL_VALUE          0x00
1652
1653 /*
1654  * ASC38C1600 Definitions
1655  *
1656  * IOPB_PCI_INT_CFG Bit Field Definitions
1657  */
1658
1659 #define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
1660
1661 /*
1662  * Bit 1 can be set to change the interrupt for the Function to operate in
1663  * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1664  * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1665  * mode, otherwise the operating mode is undefined.
1666  */
1667 #define TOTEMPOLE       0x02
1668
1669 /*
1670  * Bit 0 can be used to change the Int Pin for the Function. The value is
1671  * 0 by default for both Functions with Function 0 using INT A and Function
1672  * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1673  * INT A is used.
1674  *
1675  * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1676  * value specified in the PCI Configuration Space.
1677  */
1678 #define INTAB           0x01
1679
1680 /*
1681  * Adv Library Status Definitions
1682  */
1683 #define ADV_TRUE        1
1684 #define ADV_FALSE       0
1685 #define ADV_SUCCESS     1
1686 #define ADV_BUSY        0
1687 #define ADV_ERROR       (-1)
1688
1689 /*
1690  * ADV_DVC_VAR 'warn_code' values
1691  */
1692 #define ASC_WARN_BUSRESET_ERROR         0x0001  /* SCSI Bus Reset error */
1693 #define ASC_WARN_EEPROM_CHKSUM          0x0002  /* EEP check sum error */
1694 #define ASC_WARN_EEPROM_TERMINATION     0x0004  /* EEP termination bad field */
1695 #define ASC_WARN_ERROR                  0xFFFF  /* ADV_ERROR return */
1696
1697 #define ADV_MAX_TID                     15      /* max. target identifier */
1698 #define ADV_MAX_LUN                     7       /* max. logical unit number */
1699
1700 /*
1701  * Error code values are set in ADV_DVC_VAR 'err_code'.
1702  */
1703 #define ASC_IERR_MCODE_CHKSUM       0x0002      /* micro code check sum error */
1704 #define ASC_IERR_NO_CARRIER         0x0004      /* No more carrier memory. */
1705 #define ASC_IERR_START_STOP_CHIP    0x0008      /* start/stop chip failed */
1706 #define ASC_IERR_SET_SCSI_ID        0x0080      /* set SCSI ID failed */
1707 #define ASC_IERR_HVD_DEVICE         0x0100      /* HVD attached to LVD connector. */
1708 #define ASC_IERR_BAD_SIGNATURE      0x0200      /* signature not found */
1709 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400      /* Illegal cable connection */
1710 #define ASC_IERR_SINGLE_END_DEVICE  0x0800      /* Single-end used w/differential */
1711 #define ASC_IERR_REVERSED_CABLE     0x1000      /* Narrow flat cable reversed */
1712 #define ASC_IERR_BIST_PRE_TEST      0x2000      /* BIST pre-test error */
1713 #define ASC_IERR_BIST_RAM_TEST      0x4000      /* BIST RAM test error */
1714 #define ASC_IERR_BAD_CHIPTYPE       0x8000      /* Invalid 'chip_type' setting. */
1715
1716 /*
1717  * Fixed locations of microcode operating variables.
1718  */
1719 #define ASC_MC_CODE_BEGIN_ADDR          0x0028  /* microcode start address */
1720 #define ASC_MC_CODE_END_ADDR            0x002A  /* microcode end address */
1721 #define ASC_MC_CODE_CHK_SUM             0x002C  /* microcode code checksum */
1722 #define ASC_MC_VERSION_DATE             0x0038  /* microcode version */
1723 #define ASC_MC_VERSION_NUM              0x003A  /* microcode number */
1724 #define ASC_MC_BIOSMEM                  0x0040  /* BIOS RISC Memory Start */
1725 #define ASC_MC_BIOSLEN                  0x0050  /* BIOS RISC Memory Length */
1726 #define ASC_MC_BIOS_SIGNATURE           0x0058  /* BIOS Signature 0x55AA */
1727 #define ASC_MC_BIOS_VERSION             0x005A  /* BIOS Version (2 bytes) */
1728 #define ASC_MC_SDTR_SPEED1              0x0090  /* SDTR Speed for TID 0-3 */
1729 #define ASC_MC_SDTR_SPEED2              0x0092  /* SDTR Speed for TID 4-7 */
1730 #define ASC_MC_SDTR_SPEED3              0x0094  /* SDTR Speed for TID 8-11 */
1731 #define ASC_MC_SDTR_SPEED4              0x0096  /* SDTR Speed for TID 12-15 */
1732 #define ASC_MC_CHIP_TYPE                0x009A
1733 #define ASC_MC_INTRB_CODE               0x009B
1734 #define ASC_MC_WDTR_ABLE                0x009C
1735 #define ASC_MC_SDTR_ABLE                0x009E
1736 #define ASC_MC_TAGQNG_ABLE              0x00A0
1737 #define ASC_MC_DISC_ENABLE              0x00A2
1738 #define ASC_MC_IDLE_CMD_STATUS          0x00A4
1739 #define ASC_MC_IDLE_CMD                 0x00A6
1740 #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
1741 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
1742 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
1743 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
1744 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
1745 #define ASC_MC_SDTR_DONE                0x00B6
1746 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
1747 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
1748 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
1749 #define ASC_MC_CONTROL_FLAG             0x0122  /* Microcode control flag. */
1750 #define ASC_MC_WDTR_DONE                0x0124
1751 #define ASC_MC_CAM_MODE_MASK            0x015E  /* CAM mode TID bitmask. */
1752 #define ASC_MC_ICQ                      0x0160
1753 #define ASC_MC_IRQ                      0x0164
1754 #define ASC_MC_PPR_ABLE                 0x017A
1755
1756 /*
1757  * BIOS LRAM variable absolute offsets.
1758  */
1759 #define BIOS_CODESEG    0x54
1760 #define BIOS_CODELEN    0x56
1761 #define BIOS_SIGNATURE  0x58
1762 #define BIOS_VERSION    0x5A
1763
1764 /*
1765  * Microcode Control Flags
1766  *
1767  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1768  * and handled by the microcode.
1769  */
1770 #define CONTROL_FLAG_IGNORE_PERR        0x0001  /* Ignore DMA Parity Errors */
1771 #define CONTROL_FLAG_ENABLE_AIPP        0x0002  /* Enabled AIPP checking. */
1772
1773 /*
1774  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1775  */
1776 #define HSHK_CFG_WIDE_XFR       0x8000
1777 #define HSHK_CFG_RATE           0x0F00
1778 #define HSHK_CFG_OFFSET         0x001F
1779
1780 #define ASC_DEF_MAX_HOST_QNG    0xFD    /* Max. number of host commands (253) */
1781 #define ASC_DEF_MIN_HOST_QNG    0x10    /* Min. number of host commands (16) */
1782 #define ASC_DEF_MAX_DVC_QNG     0x3F    /* Max. number commands per device (63) */
1783 #define ASC_DEF_MIN_DVC_QNG     0x04    /* Min. number commands per device (4) */
1784
1785 #define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1786 #define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
1787 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1788 #define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
1789 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1790
1791 #define ASC_QSC_NO_DISC     0x01        /* Don't allow disconnect for request. */
1792 #define ASC_QSC_NO_TAGMSG   0x02        /* Don't allow tag queuing for request. */
1793 #define ASC_QSC_NO_SYNC     0x04        /* Don't use Synch. transfer on request. */
1794 #define ASC_QSC_NO_WIDE     0x08        /* Don't use Wide transfer on request. */
1795 #define ASC_QSC_REDO_DTR    0x10        /* Renegotiate WDTR/SDTR before request. */
1796 /*
1797  * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1798  * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1799  */
1800 #define ASC_QSC_HEAD_TAG    0x40        /* Use Head Tag Message (0x21). */
1801 #define ASC_QSC_ORDERED_TAG 0x80        /* Use Ordered Tag Message (0x22). */
1802
1803 /*
1804  * All fields here are accessed by the board microcode and need to be
1805  * little-endian.
1806  */
1807 typedef struct adv_carr_t {
1808         ADV_VADDR carr_va;      /* Carrier Virtual Address */
1809         ADV_PADDR carr_pa;      /* Carrier Physical Address */
1810         ADV_VADDR areq_vpa;     /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1811         /*
1812          * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
1813          *
1814          * next_vpa [3:1]             Reserved Bits
1815          * next_vpa [0]               Done Flag set in Response Queue.
1816          */
1817         ADV_VADDR next_vpa;
1818 } ADV_CARR_T;
1819
1820 /*
1821  * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1822  */
1823 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
1824
1825 #define ASC_RQ_DONE             0x00000001
1826 #define ASC_RQ_GOOD             0x00000002
1827 #define ASC_CQ_STOPPER          0x00000000
1828
1829 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1830
1831 #define ADV_CARRIER_NUM_PAGE_CROSSING \
1832     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
1833         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1834
1835 #define ADV_CARRIER_BUFSIZE \
1836     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1837
1838 /*
1839  * ASC_SCSI_REQ_Q 'a_flag' definitions
1840  *
1841  * The Adv Library should limit use to the lower nibble (4 bits) of
1842  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1843  */
1844 #define ADV_POLL_REQUEST                0x01    /* poll for request completion */
1845 #define ADV_SCSIQ_DONE                  0x02    /* request done */
1846 #define ADV_DONT_RETRY                  0x08    /* don't do retry */
1847
1848 #define ADV_CHIP_ASC3550          0x01  /* Ultra-Wide IC */
1849 #define ADV_CHIP_ASC38C0800       0x02  /* Ultra2-Wide/LVD IC */
1850 #define ADV_CHIP_ASC38C1600       0x03  /* Ultra3-Wide/LVD2 IC */
1851
1852 /*
1853  * Adapter temporary configuration structure
1854  *
1855  * This structure can be discarded after initialization. Don't add
1856  * fields here needed after initialization.
1857  *
1858  * Field naming convention:
1859  *
1860  *  *_enable indicates the field enables or disables a feature. The
1861  *  value of the field is never reset.
1862  */
1863 typedef struct adv_dvc_cfg {
1864         ushort disc_enable;     /* enable disconnection */
1865         uchar chip_version;     /* chip version */
1866         uchar termination;      /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1867         ushort lib_version;     /* Adv Library version number */
1868         ushort control_flag;    /* Microcode Control Flag */
1869         ushort mcode_date;      /* Microcode date */
1870         ushort mcode_version;   /* Microcode version */
1871         ushort serial1;         /* EEPROM serial number word 1 */
1872         ushort serial2;         /* EEPROM serial number word 2 */
1873         ushort serial3;         /* EEPROM serial number word 3 */
1874 } ADV_DVC_CFG;
1875
1876 struct adv_dvc_var;
1877 struct adv_scsi_req_q;
1878
1879 /*
1880  * Adapter operation variable structure.
1881  *
1882  * One structure is required per host adapter.
1883  *
1884  * Field naming convention:
1885  *
1886  *  *_able indicates both whether a feature should be enabled or disabled
1887  *  and whether a device isi capable of the feature. At initialization
1888  *  this field may be set, but later if a device is found to be incapable
1889  *  of the feature, the field is cleared.
1890  */
1891 typedef struct adv_dvc_var {
1892         AdvPortAddr iop_base;   /* I/O port address */
1893         ushort err_code;        /* fatal error code */
1894         ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
1895         ushort wdtr_able;       /* try WDTR for a device */
1896         ushort sdtr_able;       /* try SDTR for a device */
1897         ushort ultra_able;      /* try SDTR Ultra speed for a device */
1898         ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
1899         ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
1900         ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
1901         ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
1902         ushort tagqng_able;     /* try tagged queuing with a device */
1903         ushort ppr_able;        /* PPR message capable per TID bitmask. */
1904         uchar max_dvc_qng;      /* maximum number of tagged commands per device */
1905         ushort start_motor;     /* start motor command allowed */
1906         uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
1907         uchar chip_no;          /* should be assigned by caller */
1908         uchar max_host_qng;     /* maximum number of Q'ed command allowed */
1909         ushort no_scam;         /* scam_tolerant of EEPROM */
1910         struct asc_board *drv_ptr;      /* driver pointer to private structure */
1911         uchar chip_scsi_id;     /* chip SCSI target ID */
1912         uchar chip_type;
1913         uchar bist_err_code;
1914         ADV_CARR_T *carrier_buf;
1915         ADV_CARR_T *carr_freelist;      /* Carrier free list. */
1916         ADV_CARR_T *icq_sp;     /* Initiator command queue stopper pointer. */
1917         ADV_CARR_T *irq_sp;     /* Initiator response queue stopper pointer. */
1918         ushort carr_pending_cnt;        /* Count of pending carriers. */
1919         /*
1920          * Note: The following fields will not be used after initialization. The
1921          * driver may discard the buffer after initialization is done.
1922          */
1923         ADV_DVC_CFG *cfg;       /* temporary configuration structure  */
1924 } ADV_DVC_VAR;
1925
1926 #define NO_OF_SG_PER_BLOCK              15
1927
1928 typedef struct asc_sg_block {
1929         uchar reserved1;
1930         uchar reserved2;
1931         uchar reserved3;
1932         uchar sg_cnt;           /* Valid entries in block. */
1933         ADV_PADDR sg_ptr;       /* Pointer to next sg block. */
1934         struct {
1935                 ADV_PADDR sg_addr;      /* SG element address. */
1936                 ADV_DCNT sg_count;      /* SG element count. */
1937         } sg_list[NO_OF_SG_PER_BLOCK];
1938 } ADV_SG_BLOCK;
1939
1940 /*
1941  * ADV_SCSI_REQ_Q - microcode request structure
1942  *
1943  * All fields in this structure up to byte 60 are used by the microcode.
1944  * The microcode makes assumptions about the size and ordering of fields
1945  * in this structure. Do not change the structure definition here without
1946  * coordinating the change with the microcode.
1947  *
1948  * All fields accessed by microcode must be maintained in little_endian
1949  * order.
1950  */
1951 typedef struct adv_scsi_req_q {
1952         uchar cntl;             /* Ucode flags and state (ASC_MC_QC_*). */
1953         uchar target_cmd;
1954         uchar target_id;        /* Device target identifier. */
1955         uchar target_lun;       /* Device target logical unit number. */
1956         ADV_PADDR data_addr;    /* Data buffer physical address. */
1957         ADV_DCNT data_cnt;      /* Data count. Ucode sets to residual. */
1958         ADV_PADDR sense_addr;
1959         ADV_PADDR carr_pa;
1960         uchar mflag;
1961         uchar sense_len;
1962         uchar cdb_len;          /* SCSI CDB length. Must <= 16 bytes. */
1963         uchar scsi_cntl;
1964         uchar done_status;      /* Completion status. */
1965         uchar scsi_status;      /* SCSI status byte. */
1966         uchar host_status;      /* Ucode host status. */
1967         uchar sg_working_ix;
1968         uchar cdb[12];          /* SCSI CDB bytes 0-11. */
1969         ADV_PADDR sg_real_addr; /* SG list physical address. */
1970         ADV_PADDR scsiq_rptr;
1971         uchar cdb16[4];         /* SCSI CDB bytes 12-15. */
1972         ADV_VADDR scsiq_ptr;
1973         ADV_VADDR carr_va;
1974         /*
1975          * End of microcode structure - 60 bytes. The rest of the structure
1976          * is used by the Adv Library and ignored by the microcode.
1977          */
1978         ADV_VADDR srb_ptr;
1979         ADV_SG_BLOCK *sg_list_ptr;      /* SG list virtual address. */
1980         char *vdata_addr;       /* Data buffer virtual address. */
1981         uchar a_flag;
1982         uchar pad[2];           /* Pad out to a word boundary. */
1983 } ADV_SCSI_REQ_Q;
1984
1985 /*
1986  * Microcode idle loop commands
1987  */
1988 #define IDLE_CMD_COMPLETED           0
1989 #define IDLE_CMD_STOP_CHIP           0x0001
1990 #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
1991 #define IDLE_CMD_SEND_INT            0x0004
1992 #define IDLE_CMD_ABORT               0x0008
1993 #define IDLE_CMD_DEVICE_RESET        0x0010
1994 #define IDLE_CMD_SCSI_RESET_START    0x0020     /* Assert SCSI Bus Reset */
1995 #define IDLE_CMD_SCSI_RESET_END      0x0040     /* Deassert SCSI Bus Reset */
1996 #define IDLE_CMD_SCSIREQ             0x0080
1997
1998 #define IDLE_CMD_STATUS_SUCCESS      0x0001
1999 #define IDLE_CMD_STATUS_FAILURE      0x0002
2000
2001 /*
2002  * AdvSendIdleCmd() flag definitions.
2003  */
2004 #define ADV_NOWAIT     0x01
2005
2006 /*
2007  * Wait loop time out values.
2008  */
2009 #define SCSI_WAIT_100_MSEC           100UL      /* 100 milliseconds */
2010 #define SCSI_US_PER_MSEC             1000       /* microseconds per millisecond */
2011 #define SCSI_MAX_RETRY               10 /* retry count */
2012
2013 #define ADV_ASYNC_RDMA_FAILURE          0x01    /* Fatal RDMA failure. */
2014 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02    /* Detected SCSI Bus Reset. */
2015 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03    /* Carrier Ready failure. */
2016 #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04    /* RDMAed-in data invalid. */
2017
2018 #define ADV_HOST_SCSI_BUS_RESET      0x80       /* Host Initiated SCSI Bus Reset. */
2019
2020 /* Read byte from a register. */
2021 #define AdvReadByteRegister(iop_base, reg_off) \
2022      (ADV_MEM_READB((iop_base) + (reg_off)))
2023
2024 /* Write byte to a register. */
2025 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
2026      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2027
2028 /* Read word (2 bytes) from a register. */
2029 #define AdvReadWordRegister(iop_base, reg_off) \
2030      (ADV_MEM_READW((iop_base) + (reg_off)))
2031
2032 /* Write word (2 bytes) to a register. */
2033 #define AdvWriteWordRegister(iop_base, reg_off, word) \
2034      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2035
2036 /* Write dword (4 bytes) to a register. */
2037 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2038      (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2039
2040 /* Read byte from LRAM. */
2041 #define AdvReadByteLram(iop_base, addr, byte) \
2042 do { \
2043     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2044     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2045 } while (0)
2046
2047 /* Write byte to LRAM. */
2048 #define AdvWriteByteLram(iop_base, addr, byte) \
2049     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2050      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2051
2052 /* Read word (2 bytes) from LRAM. */
2053 #define AdvReadWordLram(iop_base, addr, word) \
2054 do { \
2055     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2056     (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2057 } while (0)
2058
2059 /* Write word (2 bytes) to LRAM. */
2060 #define AdvWriteWordLram(iop_base, addr, word) \
2061     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2062      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2063
2064 /* Write little-endian double word (4 bytes) to LRAM */
2065 /* Because of unspecified C language ordering don't use auto-increment. */
2066 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2067     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2068       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2069                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2070      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2071       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2072                      cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2073
2074 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
2075 #define AdvReadWordAutoIncLram(iop_base) \
2076      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2077
2078 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
2079 #define AdvWriteWordAutoIncLram(iop_base, word) \
2080      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2081
2082 /*
2083  * Define macro to check for Condor signature.
2084  *
2085  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2086  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2087  */
2088 #define AdvFindSignature(iop_base) \
2089     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2090     ADV_CHIP_ID_BYTE) && \
2091      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2092     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
2093
2094 /*
2095  * Define macro to Return the version number of the chip at 'iop_base'.
2096  *
2097  * The second parameter 'bus_type' is currently unused.
2098  */
2099 #define AdvGetChipVersion(iop_base, bus_type) \
2100     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2101
2102 /*
2103  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2104  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2105  *
2106  * If the request has not yet been sent to the device it will simply be
2107  * aborted from RISC memory. If the request is disconnected it will be
2108  * aborted on reselection by sending an Abort Message to the target ID.
2109  *
2110  * Return value:
2111  *      ADV_TRUE(1) - Queue was successfully aborted.
2112  *      ADV_FALSE(0) - Queue was not found on the active queue list.
2113  */
2114 #define AdvAbortQueue(asc_dvc, scsiq) \
2115         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2116                        (ADV_DCNT) (scsiq))
2117
2118 /*
2119  * Send a Bus Device Reset Message to the specified target ID.
2120  *
2121  * All outstanding commands will be purged if sending the
2122  * Bus Device Reset Message is successful.
2123  *
2124  * Return Value:
2125  *      ADV_TRUE(1) - All requests on the target are purged.
2126  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2127  *                     are not purged.
2128  */
2129 #define AdvResetDevice(asc_dvc, target_id) \
2130         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2131                     (ADV_DCNT) (target_id))
2132
2133 /*
2134  * SCSI Wide Type definition.
2135  */
2136 #define ADV_SCSI_BIT_ID_TYPE   ushort
2137
2138 /*
2139  * AdvInitScsiTarget() 'cntl_flag' options.
2140  */
2141 #define ADV_SCAN_LUN           0x01
2142 #define ADV_CAPINFO_NOLUN      0x02
2143
2144 /*
2145  * Convert target id to target id bit mask.
2146  */
2147 #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
2148
2149 /*
2150  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2151  */
2152
2153 #define QD_NO_STATUS         0x00       /* Request not completed yet. */
2154 #define QD_NO_ERROR          0x01
2155 #define QD_ABORTED_BY_HOST   0x02
2156 #define QD_WITH_ERROR        0x04
2157
2158 #define QHSTA_NO_ERROR              0x00
2159 #define QHSTA_M_SEL_TIMEOUT         0x11
2160 #define QHSTA_M_DATA_OVER_RUN       0x12
2161 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2162 #define QHSTA_M_QUEUE_ABORTED       0x15
2163 #define QHSTA_M_SXFR_SDMA_ERR       0x16        /* SXFR_STATUS SCSI DMA Error */
2164 #define QHSTA_M_SXFR_SXFR_PERR      0x17        /* SXFR_STATUS SCSI Bus Parity Error */
2165 #define QHSTA_M_RDMA_PERR           0x18        /* RISC PCI DMA parity error */
2166 #define QHSTA_M_SXFR_OFF_UFLW       0x19        /* SXFR_STATUS Offset Underflow */
2167 #define QHSTA_M_SXFR_OFF_OFLW       0x20        /* SXFR_STATUS Offset Overflow */
2168 #define QHSTA_M_SXFR_WD_TMO         0x21        /* SXFR_STATUS Watchdog Timeout */
2169 #define QHSTA_M_SXFR_DESELECTED     0x22        /* SXFR_STATUS Deselected */
2170 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
2171 #define QHSTA_M_SXFR_XFR_OFLW       0x12        /* SXFR_STATUS Transfer Overflow */
2172 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24        /* SXFR_STATUS Transfer Phase Error */
2173 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25        /* SXFR_STATUS Unknown Error */
2174 #define QHSTA_M_SCSI_BUS_RESET      0x30        /* Request aborted from SBR */
2175 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31       /* Request aborted from unsol. SBR */
2176 #define QHSTA_M_BUS_DEVICE_RESET    0x32        /* Request aborted from BDR */
2177 #define QHSTA_M_DIRECTION_ERR       0x35        /* Data Phase mismatch */
2178 #define QHSTA_M_DIRECTION_ERR_HUNG  0x36        /* Data Phase mismatch and bus hang */
2179 #define QHSTA_M_WTM_TIMEOUT         0x41
2180 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
2181 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
2182 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2183 #define QHSTA_M_INVALID_DEVICE      0x45        /* Bad target ID */
2184 #define QHSTA_M_FROZEN_TIDQ         0x46        /* TID Queue frozen. */
2185 #define QHSTA_M_SGBACKUP_ERROR      0x47        /* Scatter-Gather backup error */
2186
2187 /*
2188  * DvcGetPhyAddr() flag arguments
2189  */
2190 #define ADV_IS_SCSIQ_FLAG       0x01    /* 'addr' is ASC_SCSI_REQ_Q pointer */
2191 #define ADV_ASCGETSGLIST_VADDR  0x02    /* 'addr' is AscGetSGList() virtual addr */
2192 #define ADV_IS_SENSE_FLAG       0x04    /* 'addr' is sense virtual pointer */
2193 #define ADV_IS_DATA_FLAG        0x08    /* 'addr' is data virtual pointer */
2194 #define ADV_IS_SGLIST_FLAG      0x10    /* 'addr' is sglist virtual pointer */
2195 #define ADV_IS_CARRIER_FLAG     0x20    /* 'addr' is ADV_CARR_T pointer */
2196
2197 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
2198 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
2199 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
2200 #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
2201
2202 /*
2203  * Total contiguous memory needed for driver SG blocks.
2204  *
2205  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2206  * number of scatter-gather elements the driver supports in a
2207  * single request.
2208  */
2209
2210 #define ADV_SG_LIST_MAX_BYTE_SIZE \
2211          (sizeof(ADV_SG_BLOCK) * \
2212           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2213
2214 /* Reference Scsi_Host hostdata */
2215 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2216
2217 /* asc_board_t flags */
2218 #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
2219
2220 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2221
2222 #define NO_ISA_DMA              0xff    /* No ISA DMA Channel Used */
2223
2224 #define ASC_INFO_SIZE           128     /* advansys_info() line size */
2225
2226 #ifdef CONFIG_PROC_FS
2227 /* /proc/scsi/advansys/[0...] related definitions */
2228 #define ASC_PRTBUF_SIZE         2048
2229 #define ASC_PRTLINE_SIZE        160
2230
2231 #define ASC_PRT_NEXT() \
2232     if (cp) { \
2233         totlen += len; \
2234         leftlen -= len; \
2235         if (leftlen == 0) { \
2236             return totlen; \
2237         } \
2238         cp += len; \
2239     }
2240 #endif /* CONFIG_PROC_FS */
2241
2242 /* Asc Library return codes */
2243 #define ASC_TRUE        1
2244 #define ASC_FALSE       0
2245 #define ASC_NOERROR     1
2246 #define ASC_BUSY        0
2247 #define ASC_ERROR       (-1)
2248
2249 /* struct scsi_cmnd function return codes */
2250 #define STATUS_BYTE(byte)   (byte)
2251 #define MSG_BYTE(byte)      ((byte) << 8)
2252 #define HOST_BYTE(byte)     ((byte) << 16)
2253 #define DRIVER_BYTE(byte)   ((byte) << 24)
2254
2255 #ifndef ADVANSYS_STATS
2256 #define ASC_STATS(shost, counter)
2257 #define ASC_STATS_ADD(shost, counter, count)
2258 #else /* ADVANSYS_STATS */
2259 #define ASC_STATS(shost, counter) \
2260     (ASC_BOARDP(shost)->asc_stats.counter++)
2261
2262 #define ASC_STATS_ADD(shost, counter, count) \
2263     (ASC_BOARDP(shost)->asc_stats.counter += (count))
2264 #endif /* ADVANSYS_STATS */
2265
2266 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2267
2268 /* If the result wraps when calculating tenths, return 0. */
2269 #define ASC_TENTHS(num, den) \
2270     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2271     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2272
2273 /*
2274  * Display a message to the console.
2275  */
2276 #define ASC_PRINT(s) \
2277     { \
2278         printk("advansys: "); \
2279         printk(s); \
2280     }
2281
2282 #define ASC_PRINT1(s, a1) \
2283     { \
2284         printk("advansys: "); \
2285         printk((s), (a1)); \
2286     }
2287
2288 #define ASC_PRINT2(s, a1, a2) \
2289     { \
2290         printk("advansys: "); \
2291         printk((s), (a1), (a2)); \
2292     }
2293
2294 #define ASC_PRINT3(s, a1, a2, a3) \
2295     { \
2296         printk("advansys: "); \
2297         printk((s), (a1), (a2), (a3)); \
2298     }
2299
2300 #define ASC_PRINT4(s, a1, a2, a3, a4) \
2301     { \
2302         printk("advansys: "); \
2303         printk((s), (a1), (a2), (a3), (a4)); \
2304     }
2305
2306 #ifndef ADVANSYS_DEBUG
2307
2308 #define ASC_DBG(lvl, s)
2309 #define ASC_DBG1(lvl, s, a1)
2310 #define ASC_DBG2(lvl, s, a1, a2)
2311 #define ASC_DBG3(lvl, s, a1, a2, a3)
2312 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2313 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2314 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2315 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2316 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2317 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2318 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2319 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2320 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2321 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2322 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2323
2324 #else /* ADVANSYS_DEBUG */
2325
2326 /*
2327  * Debugging Message Levels:
2328  * 0: Errors Only
2329  * 1: High-Level Tracing
2330  * 2-N: Verbose Tracing
2331  */
2332
2333 #define ASC_DBG(lvl, s) \
2334     { \
2335         if (asc_dbglvl >= (lvl)) { \
2336             printk(s); \
2337         } \
2338     }
2339
2340 #define ASC_DBG1(lvl, s, a1) \
2341     { \
2342         if (asc_dbglvl >= (lvl)) { \
2343             printk((s), (a1)); \
2344         } \
2345     }
2346
2347 #define ASC_DBG2(lvl, s, a1, a2) \
2348     { \
2349         if (asc_dbglvl >= (lvl)) { \
2350             printk((s), (a1), (a2)); \
2351         } \
2352     }
2353
2354 #define ASC_DBG3(lvl, s, a1, a2, a3) \
2355     { \
2356         if (asc_dbglvl >= (lvl)) { \
2357             printk((s), (a1), (a2), (a3)); \
2358         } \
2359     }
2360
2361 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2362     { \
2363         if (asc_dbglvl >= (lvl)) { \
2364             printk((s), (a1), (a2), (a3), (a4)); \
2365         } \
2366     }
2367
2368 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2369     { \
2370         if (asc_dbglvl >= (lvl)) { \
2371             asc_prt_scsi_host(s); \
2372         } \
2373     }
2374
2375 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2376     { \
2377         if (asc_dbglvl >= (lvl)) { \
2378             asc_prt_scsi_cmnd(s); \
2379         } \
2380     }
2381
2382 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2383     { \
2384         if (asc_dbglvl >= (lvl)) { \
2385             asc_prt_asc_scsi_q(scsiqp); \
2386         } \
2387     }
2388
2389 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2390     { \
2391         if (asc_dbglvl >= (lvl)) { \
2392             asc_prt_asc_qdone_info(qdone); \
2393         } \
2394     }
2395
2396 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2397     { \
2398         if (asc_dbglvl >= (lvl)) { \
2399             asc_prt_adv_scsi_req_q(scsiqp); \
2400         } \
2401     }
2402
2403 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2404     { \
2405         if (asc_dbglvl >= (lvl)) { \
2406             asc_prt_hex((name), (start), (length)); \
2407         } \
2408     }
2409
2410 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2411         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2412
2413 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2414         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2415
2416 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2417         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2418 #endif /* ADVANSYS_DEBUG */
2419
2420 #ifdef ADVANSYS_STATS
2421
2422 /* Per board statistics structure */
2423 struct asc_stats {
2424         /* Driver Entrypoint Statistics */
2425         ADV_DCNT queuecommand;  /* # calls to advansys_queuecommand() */
2426         ADV_DCNT reset;         /* # calls to advansys_eh_bus_reset() */
2427         ADV_DCNT biosparam;     /* # calls to advansys_biosparam() */
2428         ADV_DCNT interrupt;     /* # advansys_interrupt() calls */
2429         ADV_DCNT callback;      /* # calls to asc/adv_isr_callback() */
2430         ADV_DCNT done;          /* # calls to request's scsi_done function */
2431         ADV_DCNT build_error;   /* # asc/adv_build_req() ASC_ERROR returns. */
2432         ADV_DCNT adv_build_noreq;       /* # adv_build_req() adv_req_t alloc. fail. */
2433         ADV_DCNT adv_build_nosg;        /* # adv_build_req() adv_sgblk_t alloc. fail. */
2434         /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2435         ADV_DCNT exe_noerror;   /* # ASC_NOERROR returns. */
2436         ADV_DCNT exe_busy;      /* # ASC_BUSY returns. */
2437         ADV_DCNT exe_error;     /* # ASC_ERROR returns. */
2438         ADV_DCNT exe_unknown;   /* # unknown returns. */
2439         /* Data Transfer Statistics */
2440         ADV_DCNT cont_cnt;      /* # non-scatter-gather I/O requests received */
2441         ADV_DCNT cont_xfer;     /* # contiguous transfer 512-bytes */
2442         ADV_DCNT sg_cnt;        /* # scatter-gather I/O requests received */
2443         ADV_DCNT sg_elem;       /* # scatter-gather elements */
2444         ADV_DCNT sg_xfer;       /* # scatter-gather transfer 512-bytes */
2445 };
2446 #endif /* ADVANSYS_STATS */
2447
2448 /*
2449  * Adv Library Request Structures
2450  *
2451  * The following two structures are used to process Wide Board requests.
2452  *
2453  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2454  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2455  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2456  * Mid-Level SCSI request structure.
2457  *
2458  * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2459  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2460  * up to 255 scatter-gather elements may be used per request or
2461  * ADV_SCSI_REQ_Q.
2462  *
2463  * Both structures must be 32 byte aligned.
2464  */
2465 typedef struct adv_sgblk {
2466         ADV_SG_BLOCK sg_block;  /* Sgblock structure. */
2467         uchar align[32];        /* Sgblock structure padding. */
2468         struct adv_sgblk *next_sgblkp;  /* Next scatter-gather structure. */
2469 } adv_sgblk_t;
2470
2471 typedef struct adv_req {
2472         ADV_SCSI_REQ_Q scsi_req_q;      /* Adv Library request structure. */
2473         uchar align[32];        /* Request structure padding. */
2474         struct scsi_cmnd *cmndp;        /* Mid-Level SCSI command pointer. */
2475         adv_sgblk_t *sgblkp;    /* Adv Library scatter-gather pointer. */
2476         struct adv_req *next_reqp;      /* Next Request Structure. */
2477 } adv_req_t;
2478
2479 /*
2480  * Structure allocated for each board.
2481  *
2482  * This structure is allocated by scsi_host_alloc() at the end
2483  * of the 'Scsi_Host' structure starting at the 'hostdata'
2484  * field. It is guaranteed to be allocated from DMA-able memory.
2485  */
2486 typedef struct asc_board {
2487         struct device *dev;
2488         int id;                 /* Board Id */
2489         uint flags;             /* Board flags */
2490         unsigned int irq;
2491         union {
2492                 ASC_DVC_VAR asc_dvc_var;        /* Narrow board */
2493                 ADV_DVC_VAR adv_dvc_var;        /* Wide board */
2494         } dvc_var;
2495         union {
2496                 ASC_DVC_CFG asc_dvc_cfg;        /* Narrow board */
2497                 ADV_DVC_CFG adv_dvc_cfg;        /* Wide board */
2498         } dvc_cfg;
2499         ushort asc_n_io_port;   /* Number I/O ports. */
2500         ADV_SCSI_BIT_ID_TYPE init_tidmask;      /* Target init./valid mask */
2501         ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2502         ADV_SCSI_BIT_ID_TYPE queue_full;        /* Queue full mask */
2503         ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2504         union {
2505                 ASCEEP_CONFIG asc_eep;  /* Narrow EEPROM config. */
2506                 ADVEEP_3550_CONFIG adv_3550_eep;        /* 3550 EEPROM config. */
2507                 ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
2508                 ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
2509         } eep_config;
2510         ulong last_reset;       /* Saved last reset time */
2511         spinlock_t lock;        /* Board spinlock */
2512         /* /proc/scsi/advansys/[0...] */
2513         char *prtbuf;           /* /proc print buffer */
2514 #ifdef ADVANSYS_STATS
2515         struct asc_stats asc_stats;     /* Board statistics */
2516 #endif                          /* ADVANSYS_STATS */
2517         /*
2518          * The following fields are used only for Narrow Boards.
2519          */
2520         uchar sdtr_data[ASC_MAX_TID + 1];       /* SDTR information */
2521         /*
2522          * The following fields are used only for Wide Boards.
2523          */
2524         void __iomem *ioremap_addr;     /* I/O Memory remap address. */
2525         ushort ioport;          /* I/O Port address. */
2526         ADV_CARR_T *carrp;      /* ADV_CARR_T memory block. */
2527         adv_req_t *orig_reqp;   /* adv_req_t memory block. */
2528         adv_req_t *adv_reqp;    /* Request structures. */
2529         adv_sgblk_t *adv_sgblkp;        /* Scatter-gather structures. */
2530         ushort bios_signature;  /* BIOS Signature. */
2531         ushort bios_version;    /* BIOS Version. */
2532         ushort bios_codeseg;    /* BIOS Code Segment. */
2533         ushort bios_codelen;    /* BIOS Code Segment Length. */
2534 } asc_board_t;
2535
2536 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2537                                                         dvc_var.adv_dvc_var)
2538 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2539
2540 /* Number of boards detected in system. */
2541 static int asc_board_count;
2542
2543 /* Overrun buffer used by all narrow boards. */
2544 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
2545
2546 #ifdef ADVANSYS_DEBUG
2547 static int asc_dbglvl = 3;
2548
2549 /*
2550  * asc_prt_scsi_host()
2551  */
2552 static void asc_prt_scsi_host(struct Scsi_Host *s)
2553 {
2554         asc_board_t *boardp;
2555
2556         boardp = ASC_BOARDP(s);
2557
2558         printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
2559         printk(" host_busy %u, host_no %d, last_reset %d,\n",
2560                s->host_busy, s->host_no, (unsigned)s->last_reset);
2561
2562         printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
2563                (ulong)s->base, (ulong)s->io_port, boardp->irq);
2564
2565         printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2566                s->dma_channel, s->this_id, s->can_queue);
2567
2568         printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
2569                s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
2570
2571         if (ASC_NARROW_BOARD(boardp)) {
2572                 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
2573                 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
2574         } else {
2575                 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
2576                 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
2577         }
2578 }
2579
2580 /*
2581  * asc_prt_scsi_cmnd()
2582  */
2583 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
2584 {
2585         printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
2586
2587         printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
2588                (ulong)s->device->host, (ulong)s->device, s->device->id,
2589                s->device->lun, s->device->channel);
2590
2591         asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
2592
2593         printk("sc_data_direction %u, resid %d\n",
2594                s->sc_data_direction, s->resid);
2595
2596         printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
2597
2598         printk(" serial_number 0x%x, retries %d, allowed %d\n",
2599                (unsigned)s->serial_number, s->retries, s->allowed);
2600
2601         printk(" timeout_per_command %d\n", s->timeout_per_command);
2602
2603         printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
2604                 s->scsi_done, s->done, s->host_scribble, s->result);
2605
2606         printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
2607 }
2608
2609 /*
2610  * asc_prt_asc_dvc_var()
2611  */
2612 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2613 {
2614         printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
2615
2616         printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2617                "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2618
2619         printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2620                 (unsigned)h->init_sdtr);
2621
2622         printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2623                "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2624                (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2625                (unsigned)h->chip_no);
2626
2627         printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2628                "%u,\n", (unsigned)h->queue_full_or_busy,
2629                (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2630
2631         printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2632                "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2633                (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2634                (unsigned)h->in_critical_cnt);
2635
2636         printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2637                "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2638                (unsigned)h->init_state, (unsigned)h->no_scam,
2639                (unsigned)h->pci_fix_asyn_xfer);
2640
2641         printk(" cfg 0x%lx\n", (ulong)h->cfg);
2642 }
2643
2644 /*
2645  * asc_prt_asc_dvc_cfg()
2646  */
2647 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
2648 {
2649         printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
2650
2651         printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2652                h->can_tagged_qng, h->cmd_qng_enabled);
2653         printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2654                h->disc_enable, h->sdtr_enable);
2655
2656         printk
2657             (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
2658              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
2659              h->chip_version);
2660
2661         printk
2662             (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
2663              to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
2664              h->mcode_date);
2665
2666         printk(" mcode_version %d, overrun_buf 0x%lx\n",
2667                h->mcode_version, (ulong)h->overrun_buf);
2668 }
2669
2670 /*
2671  * asc_prt_asc_scsi_q()
2672  */
2673 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2674 {
2675         ASC_SG_HEAD *sgp;
2676         int i;
2677
2678         printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2679
2680         printk
2681             (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
2682              q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
2683              q->q2.tag_code);
2684
2685         printk
2686             (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2687              (ulong)le32_to_cpu(q->q1.data_addr),
2688              (ulong)le32_to_cpu(q->q1.data_cnt),
2689              (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2690
2691         printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2692                (ulong)q->cdbptr, q->q2.cdb_len,
2693                (ulong)q->sg_head, q->q1.sg_queue_cnt);
2694
2695         if (q->sg_head) {
2696                 sgp = q->sg_head;
2697                 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2698                 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2699                        sgp->queue_cnt);
2700                 for (i = 0; i < sgp->entry_cnt; i++) {
2701                         printk(" [%u]: addr 0x%lx, bytes %lu\n",
2702                                i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2703                                (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2704                 }
2705
2706         }
2707 }
2708
2709 /*
2710  * asc_prt_asc_qdone_info()
2711  */
2712 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2713 {
2714         printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2715         printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
2716                (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
2717                q->d2.tag_code);
2718         printk
2719             (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2720              q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
2721 }
2722
2723 /*
2724  * asc_prt_adv_dvc_var()
2725  *
2726  * Display an ADV_DVC_VAR structure.
2727  */
2728 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2729 {
2730         printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
2731
2732         printk("  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2733                (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
2734
2735         printk("  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
2736                (ulong)h->isr_callback, (unsigned)h->sdtr_able,
2737                (unsigned)h->wdtr_able);
2738
2739         printk("  start_motor 0x%x, scsi_reset_wait 0x%x\n",
2740                (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2741
2742         printk("  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2743                (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2744                (ulong)h->carr_freelist);
2745
2746         printk("  icq_sp 0x%lx, irq_sp 0x%lx\n",
2747                (ulong)h->icq_sp, (ulong)h->irq_sp);
2748
2749         printk("  no_scam 0x%x, tagqng_able 0x%x\n",
2750                (unsigned)h->no_scam, (unsigned)h->tagqng_able);
2751
2752         printk("  chip_scsi_id 0x%x, cfg 0x%lx\n",
2753                (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2754 }
2755
2756 /*
2757  * asc_prt_adv_dvc_cfg()
2758  *
2759  * Display an ADV_DVC_CFG structure.
2760  */
2761 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2762 {
2763         printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
2764
2765         printk("  disc_enable 0x%x, termination 0x%x\n",
2766                h->disc_enable, h->termination);
2767
2768         printk("  chip_version 0x%x, mcode_date 0x%x\n",
2769                h->chip_version, h->mcode_date);
2770
2771         printk("  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
2772                h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
2773
2774         printk("  control_flag 0x%x\n", h->control_flag);
2775 }
2776
2777 /*
2778  * asc_prt_adv_scsi_req_q()
2779  *
2780  * Display an ADV_SCSI_REQ_Q structure.
2781  */
2782 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2783 {
2784         int sg_blk_cnt;
2785         struct asc_sg_block *sg_ptr;
2786
2787         printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2788
2789         printk("  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
2790                q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
2791
2792         printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
2793                q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
2794
2795         printk("  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2796                (ulong)le32_to_cpu(q->data_cnt),
2797                (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2798
2799         printk
2800             ("  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2801              q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2802
2803         printk("  sg_working_ix 0x%x, target_cmd %u\n",
2804                q->sg_working_ix, q->target_cmd);
2805
2806         printk("  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2807                (ulong)le32_to_cpu(q->scsiq_rptr),
2808                (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2809
2810         /* Display the request's ADV_SG_BLOCK structures. */
2811         if (q->sg_list_ptr != NULL) {
2812                 sg_blk_cnt = 0;
2813                 while (1) {
2814                         /*
2815                          * 'sg_ptr' is a physical address. Convert it to a virtual
2816                          * address by indexing 'sg_blk_cnt' into the virtual address
2817                          * array 'sg_list_ptr'.
2818                          *
2819                          * XXX - Assumes all SG physical blocks are virtually contiguous.
2820                          */
2821                         sg_ptr =
2822                             &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
2823                         asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2824                         if (sg_ptr->sg_ptr == 0) {
2825                                 break;
2826                         }
2827                         sg_blk_cnt++;
2828                 }
2829         }
2830 }
2831
2832 /*
2833  * asc_prt_adv_sgblock()
2834  *
2835  * Display an ADV_SG_BLOCK structure.
2836  */
2837 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2838 {
2839         int i;
2840
2841         printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2842                (ulong)b, sgblockno);
2843         printk("  sg_cnt %u, sg_ptr 0x%lx\n",
2844                b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
2845         BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2846         if (b->sg_ptr != 0)
2847                 BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2848         for (i = 0; i < b->sg_cnt; i++) {
2849                 printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
2850                        i, (ulong)b->sg_list[i].sg_addr,
2851                        (ulong)b->sg_list[i].sg_count);
2852         }
2853 }
2854
2855 /*
2856  * asc_prt_hex()
2857  *
2858  * Print hexadecimal output in 4 byte groupings 32 bytes
2859  * or 8 double-words per line.
2860  */
2861 static void asc_prt_hex(char *f, uchar *s, int l)
2862 {
2863         int i;
2864         int j;
2865         int k;
2866         int m;
2867
2868         printk("%s: (%d bytes)\n", f, l);
2869
2870         for (i = 0; i < l; i += 32) {
2871
2872                 /* Display a maximum of 8 double-words per line. */
2873                 if ((k = (l - i) / 4) >= 8) {
2874                         k = 8;
2875                         m = 0;
2876                 } else {
2877                         m = (l - i) % 4;
2878                 }
2879
2880                 for (j = 0; j < k; j++) {
2881                         printk(" %2.2X%2.2X%2.2X%2.2X",
2882                                (unsigned)s[i + (j * 4)],
2883                                (unsigned)s[i + (j * 4) + 1],
2884                                (unsigned)s[i + (j * 4) + 2],
2885                                (unsigned)s[i + (j * 4) + 3]);
2886                 }
2887
2888                 switch (m) {
2889                 case 0:
2890                 default:
2891                         break;
2892                 case 1:
2893                         printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2894                         break;
2895                 case 2:
2896                         printk(" %2.2X%2.2X",
2897                                (unsigned)s[i + (j * 4)],
2898                                (unsigned)s[i + (j * 4) + 1]);
2899                         break;
2900                 case 3:
2901                         printk(" %2.2X%2.2X%2.2X",
2902                                (unsigned)s[i + (j * 4) + 1],
2903                                (unsigned)s[i + (j * 4) + 2],
2904                                (unsigned)s[i + (j * 4) + 3]);
2905                         break;
2906                 }
2907
2908                 printk("\n");
2909         }
2910 }
2911 #endif /* ADVANSYS_DEBUG */
2912
2913 /*
2914  * advansys_info()
2915  *
2916  * Return suitable for printing on the console with the argument
2917  * adapter's configuration information.
2918  *
2919  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2920  * otherwise the static 'info' array will be overrun.
2921  */
2922 static const char *advansys_info(struct Scsi_Host *shost)
2923 {
2924         static char info[ASC_INFO_SIZE];
2925         asc_board_t *boardp;
2926         ASC_DVC_VAR *asc_dvc_varp;
2927         ADV_DVC_VAR *adv_dvc_varp;
2928         char *busname;
2929         char *widename = NULL;
2930
2931         boardp = ASC_BOARDP(shost);
2932         if (ASC_NARROW_BOARD(boardp)) {
2933                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2934                 ASC_DBG(1, "advansys_info: begin\n");
2935                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2936                         if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2937                             ASC_IS_ISAPNP) {
2938                                 busname = "ISA PnP";
2939                         } else {
2940                                 busname = "ISA";
2941                         }
2942                         sprintf(info,
2943                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2944                                 ASC_VERSION, busname,
2945                                 (ulong)shost->io_port,
2946                                 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2947                                 boardp->irq, shost->dma_channel);
2948                 } else {
2949                         if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2950                                 busname = "VL";
2951                         } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2952                                 busname = "EISA";
2953                         } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2954                                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2955                                     == ASC_IS_PCI_ULTRA) {
2956                                         busname = "PCI Ultra";
2957                                 } else {
2958                                         busname = "PCI";
2959                                 }
2960                         } else {
2961                                 busname = "?";
2962                                 ASC_PRINT2("advansys_info: board %d: unknown "
2963                                            "bus type %d\n", boardp->id,
2964                                            asc_dvc_varp->bus_type);
2965                         }
2966                         sprintf(info,
2967                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2968                                 ASC_VERSION, busname, (ulong)shost->io_port,
2969                                 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2970                                 boardp->irq);
2971                 }
2972         } else {
2973                 /*
2974                  * Wide Adapter Information
2975                  *
2976                  * Memory-mapped I/O is used instead of I/O space to access
2977                  * the adapter, but display the I/O Port range. The Memory
2978                  * I/O address is displayed through the driver /proc file.
2979                  */
2980                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2981                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2982                         widename = "Ultra-Wide";
2983                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2984                         widename = "Ultra2-Wide";
2985                 } else {
2986                         widename = "Ultra3-Wide";
2987                 }
2988                 sprintf(info,
2989                         "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2990                         ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
2991                         (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
2992         }
2993         BUG_ON(strlen(info) >= ASC_INFO_SIZE);
2994         ASC_DBG(1, "advansys_info: end\n");
2995         return info;
2996 }
2997
2998 #ifdef CONFIG_PROC_FS
2999 /*
3000  * asc_prt_line()
3001  *
3002  * If 'cp' is NULL print to the console, otherwise print to a buffer.
3003  *
3004  * Return 0 if printing to the console, otherwise return the number of
3005  * bytes written to the buffer.
3006  *
3007  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
3008  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
3009  */
3010 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
3011 {
3012         va_list args;
3013         int ret;
3014         char s[ASC_PRTLINE_SIZE];
3015
3016         va_start(args, fmt);
3017         ret = vsprintf(s, fmt, args);
3018         BUG_ON(ret >= ASC_PRTLINE_SIZE);
3019         if (buf == NULL) {
3020                 (void)printk(s);
3021                 ret = 0;
3022         } else {
3023                 ret = min(buflen, ret);
3024                 memcpy(buf, s, ret);
3025         }
3026         va_end(args);
3027         return ret;
3028 }
3029
3030 /*
3031  * asc_prt_board_devices()
3032  *
3033  * Print driver information for devices attached to the board.
3034  *
3035  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3036  * cf. asc_prt_line().
3037  *
3038  * Return the number of characters copied into 'cp'. No more than
3039  * 'cplen' characters will be copied to 'cp'.
3040  */
3041 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
3042 {
3043         asc_board_t *boardp;
3044         int leftlen;
3045         int totlen;
3046         int len;
3047         int chip_scsi_id;
3048         int i;
3049
3050         boardp = ASC_BOARDP(shost);
3051         leftlen = cplen;
3052         totlen = len = 0;
3053
3054         len = asc_prt_line(cp, leftlen,
3055                            "\nDevice Information for AdvanSys SCSI Host %d:\n",
3056                            shost->host_no);
3057         ASC_PRT_NEXT();
3058
3059         if (ASC_NARROW_BOARD(boardp)) {
3060                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3061         } else {
3062                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3063         }
3064
3065         len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
3066         ASC_PRT_NEXT();
3067         for (i = 0; i <= ADV_MAX_TID; i++) {
3068                 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
3069                         len = asc_prt_line(cp, leftlen, " %X,", i);
3070                         ASC_PRT_NEXT();
3071                 }
3072         }
3073         len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
3074         ASC_PRT_NEXT();
3075
3076         return totlen;
3077 }
3078
3079 /*
3080  * Display Wide Board BIOS Information.
3081  */
3082 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
3083 {
3084         asc_board_t *boardp;
3085         int leftlen;
3086         int totlen;
3087         int len;
3088         ushort major, minor, letter;
3089
3090         boardp = ASC_BOARDP(shost);
3091         leftlen = cplen;
3092         totlen = len = 0;
3093
3094         len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
3095         ASC_PRT_NEXT();
3096
3097         /*
3098          * If the BIOS saved a valid signature, then fill in
3099          * the BIOS code segment base address.
3100          */
3101         if (boardp->bios_signature != 0x55AA) {
3102                 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
3103                 ASC_PRT_NEXT();
3104                 len = asc_prt_line(cp, leftlen,
3105                                    "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
3106                 ASC_PRT_NEXT();
3107                 len = asc_prt_line(cp, leftlen,
3108                                    "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
3109                 ASC_PRT_NEXT();
3110         } else {
3111                 major = (boardp->bios_version >> 12) & 0xF;
3112                 minor = (boardp->bios_version >> 8) & 0xF;
3113                 letter = (boardp->bios_version & 0xFF);
3114
3115                 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
3116                                    major, minor,
3117                                    letter >= 26 ? '?' : letter + 'A');
3118                 ASC_PRT_NEXT();
3119
3120                 /*
3121                  * Current available ROM BIOS release is 3.1I for UW
3122                  * and 3.2I for U2W. This code doesn't differentiate
3123                  * UW and U2W boards.
3124                  */
3125                 if (major < 3 || (major <= 3 && minor < 1) ||
3126                     (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
3127                         len = asc_prt_line(cp, leftlen,
3128                                            "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
3129                         ASC_PRT_NEXT();
3130                         len = asc_prt_line(cp, leftlen,
3131                                            "ftp://ftp.connectcom.net/pub\n");
3132                         ASC_PRT_NEXT();
3133                 }
3134         }
3135
3136         return totlen;
3137 }
3138
3139 /*
3140  * Add serial number to information bar if signature AAh
3141  * is found in at bit 15-9 (7 bits) of word 1.
3142  *
3143  * Serial Number consists fo 12 alpha-numeric digits.
3144  *
3145  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
3146  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
3147  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
3148  *       5 - Product revision (A-J)    Word0:  "         "
3149  *
3150  *           Signature                 Word1: 15-9 (7 bits)
3151  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
3152  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
3153  *
3154  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
3155  *
3156  * Note 1: Only production cards will have a serial number.
3157  *
3158  * Note 2: Signature is most significant 7 bits (0xFE).
3159  *
3160  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
3161  */
3162 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
3163 {
3164         ushort w, num;
3165
3166         if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3167                 return ASC_FALSE;
3168         } else {
3169                 /*
3170                  * First word - 6 digits.
3171                  */
3172                 w = serialnum[0];
3173
3174                 /* Product type - 1st digit. */
3175                 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3176                         /* Product type is P=Prototype */
3177                         *cp += 0x8;
3178                 }
3179                 cp++;
3180
3181                 /* Manufacturing location - 2nd digit. */
3182                 *cp++ = 'A' + ((w & 0x1C00) >> 10);
3183
3184                 /* Product ID - 3rd, 4th digits. */
3185                 num = w & 0x3FF;
3186                 *cp++ = '0' + (num / 100);
3187                 num %= 100;
3188                 *cp++ = '0' + (num / 10);
3189
3190                 /* Product revision - 5th digit. */
3191                 *cp++ = 'A' + (num % 10);
3192
3193                 /*
3194                  * Second word
3195                  */
3196                 w = serialnum[1];
3197
3198                 /*
3199                  * Year - 6th digit.
3200                  *
3201                  * If bit 15 of third word is set, then the
3202                  * last digit of the year is greater than 7.
3203                  */
3204                 if (serialnum[2] & 0x8000) {
3205                         *cp++ = '8' + ((w & 0x1C0) >> 6);
3206                 } else {
3207                         *cp++ = '0' + ((w & 0x1C0) >> 6);
3208                 }
3209
3210                 /* Week of year - 7th, 8th digits. */
3211                 num = w & 0x003F;
3212                 *cp++ = '0' + num / 10;
3213                 num %= 10;
3214                 *cp++ = '0' + num;
3215
3216                 /*
3217                  * Third word
3218                  */
3219                 w = serialnum[2] & 0x7FFF;
3220
3221                 /* Serial number - 9th digit. */
3222                 *cp++ = 'A' + (w / 1000);
3223
3224                 /* 10th, 11th, 12th digits. */
3225                 num = w % 1000;
3226                 *cp++ = '0' + num / 100;
3227                 num %= 100;
3228                 *cp++ = '0' + num / 10;
3229                 num %= 10;
3230                 *cp++ = '0' + num;
3231
3232                 *cp = '\0';     /* Null Terminate the string. */
3233                 return ASC_TRUE;
3234         }
3235 }
3236
3237 /*
3238  * asc_prt_asc_board_eeprom()
3239  *
3240  * Print board EEPROM configuration.
3241  *
3242  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3243  * cf. asc_prt_line().
3244  *
3245  * Return the number of characters copied into 'cp'. No more than
3246  * 'cplen' characters will be copied to 'cp'.
3247  */
3248 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3249 {
3250         asc_board_t *boardp;
3251         ASC_DVC_VAR *asc_dvc_varp;
3252         int leftlen;
3253         int totlen;
3254         int len;
3255         ASCEEP_CONFIG *ep;
3256         int i;
3257 #ifdef CONFIG_ISA
3258         int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
3259 #endif /* CONFIG_ISA */
3260         uchar serialstr[13];
3261
3262         boardp = ASC_BOARDP(shost);
3263         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3264         ep = &boardp->eep_config.asc_eep;
3265
3266         leftlen = cplen;
3267         totlen = len = 0;
3268
3269         len = asc_prt_line(cp, leftlen,
3270                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3271                            shost->host_no);
3272         ASC_PRT_NEXT();
3273
3274         if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
3275             == ASC_TRUE) {
3276                 len =
3277                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3278                                  serialstr);
3279                 ASC_PRT_NEXT();
3280         } else {
3281                 if (ep->adapter_info[5] == 0xBB) {
3282                         len = asc_prt_line(cp, leftlen,
3283                                            " Default Settings Used for EEPROM-less Adapter.\n");
3284                         ASC_PRT_NEXT();
3285                 } else {
3286                         len = asc_prt_line(cp, leftlen,
3287                                            " Serial Number Signature Not Present.\n");
3288                         ASC_PRT_NEXT();
3289                 }
3290         }
3291
3292         len = asc_prt_line(cp, leftlen,
3293                            " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3294                            ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
3295                            ep->max_tag_qng);
3296         ASC_PRT_NEXT();
3297
3298         len = asc_prt_line(cp, leftlen,
3299                            " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
3300         ASC_PRT_NEXT();
3301
3302         len = asc_prt_line(cp, leftlen, " Target ID:           ");
3303         ASC_PRT_NEXT();
3304         for (i = 0; i <= ASC_MAX_TID; i++) {
3305                 len = asc_prt_line(cp, leftlen, " %d", i);
3306                 ASC_PRT_NEXT();
3307         }
3308         len = asc_prt_line(cp, leftlen, "\n");
3309         ASC_PRT_NEXT();
3310
3311         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
3312         ASC_PRT_NEXT();
3313         for (i = 0; i <= ASC_MAX_TID; i++) {
3314                 len = asc_prt_line(cp, leftlen, " %c",
3315                                    (ep->
3316                                     disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3317                                    'N');
3318                 ASC_PRT_NEXT();
3319         }
3320         len = asc_prt_line(cp, leftlen, "\n");
3321         ASC_PRT_NEXT();
3322
3323         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
3324         ASC_PRT_NEXT();
3325         for (i = 0; i <= ASC_MAX_TID; i++) {
3326                 len = asc_prt_line(cp, leftlen, " %c",
3327                                    (ep->
3328                                     use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3329                                    'N');
3330                 ASC_PRT_NEXT();
3331         }
3332         len = asc_prt_line(cp, leftlen, "\n");
3333         ASC_PRT_NEXT();
3334
3335         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
3336         ASC_PRT_NEXT();
3337         for (i = 0; i <= ASC_MAX_TID; i++) {
3338                 len = asc_prt_line(cp, leftlen, " %c",
3339                                    (ep->
3340                                     start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3341                                    'N');
3342                 ASC_PRT_NEXT();
3343         }
3344         len = asc_prt_line(cp, leftlen, "\n");
3345         ASC_PRT_NEXT();
3346
3347         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3348         ASC_PRT_NEXT();
3349         for (i = 0; i <= ASC_MAX_TID; i++) {
3350                 len = asc_prt_line(cp, leftlen, " %c",
3351                                    (ep->
3352                                     init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3353                                    'N');
3354                 ASC_PRT_NEXT();
3355         }
3356         len = asc_prt_line(cp, leftlen, "\n");
3357         ASC_PRT_NEXT();
3358
3359 #ifdef CONFIG_ISA
3360         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3361                 len = asc_prt_line(cp, leftlen,
3362                                    " Host ISA DMA speed:   %d MB/S\n",
3363                                    isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
3364                 ASC_PRT_NEXT();
3365         }
3366 #endif /* CONFIG_ISA */
3367
3368         return totlen;
3369 }
3370
3371 /*
3372  * asc_prt_adv_board_eeprom()
3373  *
3374  * Print board EEPROM configuration.
3375  *
3376  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3377  * cf. asc_prt_line().
3378  *
3379  * Return the number of characters copied into 'cp'. No more than
3380  * 'cplen' characters will be copied to 'cp'.
3381  */
3382 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3383 {
3384         asc_board_t *boardp;
3385         ADV_DVC_VAR *adv_dvc_varp;
3386         int leftlen;
3387         int totlen;
3388         int len;
3389         int i;
3390         char *termstr;
3391         uchar serialstr[13];
3392         ADVEEP_3550_CONFIG *ep_3550 = NULL;
3393         ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
3394         ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
3395         ushort word;
3396         ushort *wordp;
3397         ushort sdtr_speed = 0;
3398
3399         boardp = ASC_BOARDP(shost);
3400         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3401         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3402                 ep_3550 = &boardp->eep_config.adv_3550_eep;
3403         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3404                 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
3405         } else {
3406                 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
3407         }
3408
3409         leftlen = cplen;
3410         totlen = len = 0;
3411
3412         len = asc_prt_line(cp, leftlen,
3413                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3414                            shost->host_no);
3415         ASC_PRT_NEXT();
3416
3417         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3418                 wordp = &ep_3550->serial_number_word1;
3419         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3420                 wordp = &ep_38C0800->serial_number_word1;
3421         } else {
3422                 wordp = &ep_38C1600->serial_number_word1;
3423         }
3424
3425         if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
3426                 len =
3427                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3428                                  serialstr);
3429                 ASC_PRT_NEXT();
3430         } else {
3431                 len = asc_prt_line(cp, leftlen,
3432                                    " Serial Number Signature Not Present.\n");
3433                 ASC_PRT_NEXT();
3434         }
3435
3436         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3437                 len = asc_prt_line(cp, leftlen,
3438                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3439                                    ep_3550->adapter_scsi_id,
3440                                    ep_3550->max_host_qng, ep_3550->max_dvc_qng);
3441                 ASC_PRT_NEXT();
3442         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3443                 len = asc_prt_line(cp, leftlen,
3444                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3445                                    ep_38C0800->adapter_scsi_id,
3446                                    ep_38C0800->max_host_qng,
3447                                    ep_38C0800->max_dvc_qng);
3448                 ASC_PRT_NEXT();
3449         } else {
3450                 len = asc_prt_line(cp, leftlen,
3451                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3452                                    ep_38C1600->adapter_scsi_id,
3453                                    ep_38C1600->max_host_qng,
3454                                    ep_38C1600->max_dvc_qng);
3455                 ASC_PRT_NEXT();
3456         }
3457         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3458                 word = ep_3550->termination;
3459         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3460                 word = ep_38C0800->termination_lvd;
3461         } else {
3462                 word = ep_38C1600->termination_lvd;
3463         }
3464         switch (word) {
3465         case 1:
3466                 termstr = "Low Off/High Off";
3467                 break;
3468         case 2:
3469                 termstr = "Low Off/High On";
3470                 break;
3471         case 3:
3472                 termstr = "Low On/High On";
3473                 break;
3474         default:
3475         case 0:
3476                 termstr = "Automatic";
3477                 break;
3478         }
3479
3480         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3481                 len = asc_prt_line(cp, leftlen,
3482                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
3483                                    ep_3550->termination, termstr,
3484                                    ep_3550->bios_ctrl);
3485                 ASC_PRT_NEXT();
3486         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3487                 len = asc_prt_line(cp, leftlen,
3488                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
3489                                    ep_38C0800->termination_lvd, termstr,
3490                                    ep_38C0800->bios_ctrl);
3491                 ASC_PRT_NEXT();
3492         } else {
3493                 len = asc_prt_line(cp, leftlen,
3494                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
3495                                    ep_38C1600->termination_lvd, termstr,
3496                                    ep_38C1600->bios_ctrl);
3497                 ASC_PRT_NEXT();
3498         }
3499
3500         len = asc_prt_line(cp, leftlen, " Target ID:           ");
3501         ASC_PRT_NEXT();
3502         for (i = 0; i <= ADV_MAX_TID; i++) {
3503                 len = asc_prt_line(cp, leftlen, " %X", i);
3504                 ASC_PRT_NEXT();
3505         }
3506         len = asc_prt_line(cp, leftlen, "\n");
3507         ASC_PRT_NEXT();
3508
3509         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3510                 word = ep_3550->disc_enable;
3511         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3512                 word = ep_38C0800->disc_enable;
3513         } else {
3514                 word = ep_38C1600->disc_enable;
3515         }
3516         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
3517         ASC_PRT_NEXT();
3518         for (i = 0; i <= ADV_MAX_TID; i++) {
3519                 len = asc_prt_line(cp, leftlen, " %c",
3520                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3521                 ASC_PRT_NEXT();
3522         }
3523         len = asc_prt_line(cp, leftlen, "\n");
3524         ASC_PRT_NEXT();
3525
3526         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3527                 word = ep_3550->tagqng_able;
3528         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3529                 word = ep_38C0800->tagqng_able;
3530         } else {
3531                 word = ep_38C1600->tagqng_able;
3532         }
3533         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
3534         ASC_PRT_NEXT();
3535         for (i = 0; i <= ADV_MAX_TID; i++) {
3536                 len = asc_prt_line(cp, leftlen, " %c",
3537                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3538                 ASC_PRT_NEXT();
3539         }
3540         len = asc_prt_line(cp, leftlen, "\n");
3541         ASC_PRT_NEXT();
3542
3543         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3544                 word = ep_3550->start_motor;
3545         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3546                 word = ep_38C0800->start_motor;
3547         } else {
3548                 word = ep_38C1600->start_motor;
3549         }
3550         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
3551         ASC_PRT_NEXT();
3552         for (i = 0; i <= ADV_MAX_TID; i++) {
3553                 len = asc_prt_line(cp, leftlen, " %c",
3554                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3555                 ASC_PRT_NEXT();
3556         }
3557         len = asc_prt_line(cp, leftlen, "\n");
3558         ASC_PRT_NEXT();
3559
3560         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3561                 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3562                 ASC_PRT_NEXT();
3563                 for (i = 0; i <= ADV_MAX_TID; i++) {
3564                         len = asc_prt_line(cp, leftlen, " %c",
3565                                            (ep_3550->
3566                                             sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3567                                            'Y' : 'N');
3568                         ASC_PRT_NEXT();
3569                 }
3570                 len = asc_prt_line(cp, leftlen, "\n");
3571                 ASC_PRT_NEXT();
3572         }
3573
3574         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3575                 len = asc_prt_line(cp, leftlen, " Ultra Transfer:      ");
3576                 ASC_PRT_NEXT();
3577                 for (i = 0; i <= ADV_MAX_TID; i++) {
3578                         len = asc_prt_line(cp, leftlen, " %c",
3579                                            (ep_3550->
3580                                             ultra_able & ADV_TID_TO_TIDMASK(i))
3581                                            ? 'Y' : 'N');
3582                         ASC_PRT_NEXT();
3583                 }
3584                 len = asc_prt_line(cp, leftlen, "\n");
3585                 ASC_PRT_NEXT();
3586         }
3587
3588         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3589                 word = ep_3550->wdtr_able;
3590         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3591                 word = ep_38C0800->wdtr_able;
3592         } else {
3593                 word = ep_38C1600->wdtr_able;
3594         }
3595         len = asc_prt_line(cp, leftlen, " Wide Transfer:       ");
3596         ASC_PRT_NEXT();
3597         for (i = 0; i <= ADV_MAX_TID; i++) {
3598                 len = asc_prt_line(cp, leftlen, " %c",
3599                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3600                 ASC_PRT_NEXT();
3601         }
3602         len = asc_prt_line(cp, leftlen, "\n");
3603         ASC_PRT_NEXT();
3604
3605         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3606             adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3607                 len = asc_prt_line(cp, leftlen,
3608                                    " Synchronous Transfer Speed (Mhz):\n  ");
3609                 ASC_PRT_NEXT();
3610                 for (i = 0; i <= ADV_MAX_TID; i++) {
3611                         char *speed_str;
3612
3613                         if (i == 0) {
3614                                 sdtr_speed = adv_dvc_varp->sdtr_speed1;
3615                         } else if (i == 4) {
3616                                 sdtr_speed = adv_dvc_varp->sdtr_speed2;
3617                         } else if (i == 8) {
3618                                 sdtr_speed = adv_dvc_varp->sdtr_speed3;
3619                         } else if (i == 12) {
3620                                 sdtr_speed = adv_dvc_varp->sdtr_speed4;
3621                         }
3622                         switch (sdtr_speed & ADV_MAX_TID) {
3623                         case 0:
3624                                 speed_str = "Off";
3625                                 break;
3626                         case 1:
3627                                 speed_str = "  5";
3628                                 break;
3629                         case 2:
3630                                 speed_str = " 10";
3631                                 break;
3632                         case 3:
3633                                 speed_str = " 20";
3634                                 break;
3635                         case 4:
3636                                 speed_str = " 40";
3637                                 break;
3638                         case 5:
3639                                 speed_str = " 80";
3640                                 break;
3641                         default:
3642                                 speed_str = "Unk";
3643                                 break;
3644                         }
3645                         len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
3646                         ASC_PRT_NEXT();
3647                         if (i == 7) {
3648                                 len = asc_prt_line(cp, leftlen, "\n  ");
3649                                 ASC_PRT_NEXT();
3650                         }
3651                         sdtr_speed >>= 4;
3652                 }
3653                 len = asc_prt_line(cp, leftlen, "\n");
3654                 ASC_PRT_NEXT();
3655         }
3656
3657         return totlen;
3658 }
3659
3660 /*
3661  * asc_prt_driver_conf()
3662  *
3663  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3664  * cf. asc_prt_line().
3665  *
3666  * Return the number of characters copied into 'cp'. No more than
3667  * 'cplen' characters will be copied to 'cp'.
3668  */
3669 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
3670 {
3671         asc_board_t *boardp;
3672         int leftlen;
3673         int totlen;
3674         int len;
3675         int chip_scsi_id;
3676
3677         boardp = ASC_BOARDP(shost);
3678
3679         leftlen = cplen;
3680         totlen = len = 0;
3681
3682         len = asc_prt_line(cp, leftlen,
3683                            "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3684                            shost->host_no);
3685         ASC_PRT_NEXT();
3686
3687         len = asc_prt_line(cp, leftlen,
3688                            " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
3689                            shost->host_busy, shost->last_reset, shost->max_id,
3690                            shost->max_lun, shost->max_channel);
3691         ASC_PRT_NEXT();
3692
3693         len = asc_prt_line(cp, leftlen,
3694                            " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3695                            shost->unique_id, shost->can_queue, shost->this_id,
3696                            shost->sg_tablesize, shost->cmd_per_lun);
3697         ASC_PRT_NEXT();
3698
3699         len = asc_prt_line(cp, leftlen,
3700                            " unchecked_isa_dma %d, use_clustering %d\n",
3701                            shost->unchecked_isa_dma, shost->use_clustering);
3702         ASC_PRT_NEXT();
3703
3704         len = asc_prt_line(cp, leftlen,
3705                            " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
3706                            boardp->flags, boardp->last_reset, jiffies,
3707                            boardp->asc_n_io_port);
3708         ASC_PRT_NEXT();
3709
3710         len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3711         ASC_PRT_NEXT();
3712
3713         if (ASC_NARROW_BOARD(boardp)) {
3714                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3715         } else {
3716                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3717         }
3718
3719         return totlen;
3720 }
3721
3722 /*
3723  * asc_prt_asc_board_info()
3724  *
3725  * Print dynamic board configuration information.
3726  *
3727  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3728  * cf. asc_prt_line().
3729  *
3730  * Return the number of characters copied into 'cp'. No more than
3731  * 'cplen' characters will be copied to 'cp'.
3732  */
3733 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3734 {
3735         asc_board_t *boardp;
3736         int chip_scsi_id;
3737         int leftlen;
3738         int totlen;
3739         int len;
3740         ASC_DVC_VAR *v;
3741         ASC_DVC_CFG *c;
3742         int i;
3743         int renegotiate = 0;
3744
3745         boardp = ASC_BOARDP(shost);
3746         v = &boardp->dvc_var.asc_dvc_var;
3747         c = &boardp->dvc_cfg.asc_dvc_cfg;
3748         chip_scsi_id = c->chip_scsi_id;
3749
3750         leftlen = cplen;
3751         totlen = len = 0;
3752
3753         len = asc_prt_line(cp, leftlen,
3754                            "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3755                            shost->host_no);
3756         ASC_PRT_NEXT();
3757
3758         len = asc_prt_line(cp, leftlen,
3759                            " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
3760                            c->chip_version, c->lib_version, c->lib_serial_no,
3761                            c->mcode_date);
3762         ASC_PRT_NEXT();
3763
3764         len = asc_prt_line(cp, leftlen,
3765                            " mcode_version 0x%x, err_code %u\n",
3766                            c->mcode_version, v->err_code);
3767         ASC_PRT_NEXT();
3768
3769         /* Current number of commands waiting for the host. */
3770         len = asc_prt_line(cp, leftlen,
3771                            " Total Command Pending: %d\n", v->cur_total_qng);
3772         ASC_PRT_NEXT();
3773
3774         len = asc_prt_line(cp, leftlen, " Command Queuing:");
3775         ASC_PRT_NEXT();
3776         for (i = 0; i <= ASC_MAX_TID; i++) {
3777                 if ((chip_scsi_id == i) ||
3778                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3779                         continue;
3780                 }
3781                 len = asc_prt_line(cp, leftlen, " %X:%c",
3782                                    i,
3783                                    (v->
3784                                     use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3785                                    'Y' : 'N');
3786                 ASC_PRT_NEXT();
3787         }
3788         len = asc_prt_line(cp, leftlen, "\n");
3789         ASC_PRT_NEXT();
3790
3791         /* Current number of commands waiting for a device. */
3792         len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
3793         ASC_PRT_NEXT();
3794         for (i = 0; i <= ASC_MAX_TID; i++) {
3795                 if ((chip_scsi_id == i) ||
3796                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3797                         continue;
3798                 }
3799                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3800                 ASC_PRT_NEXT();
3801         }
3802         len = asc_prt_line(cp, leftlen, "\n");
3803         ASC_PRT_NEXT();
3804
3805         /* Current limit on number of commands that can be sent to a device. */
3806         len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
3807         ASC_PRT_NEXT();
3808         for (i = 0; i <= ASC_MAX_TID; i++) {
3809                 if ((chip_scsi_id == i) ||
3810                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3811                         continue;
3812                 }
3813                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3814                 ASC_PRT_NEXT();
3815         }
3816         len = asc_prt_line(cp, leftlen, "\n");
3817         ASC_PRT_NEXT();
3818
3819         /* Indicate whether the device has returned queue full status. */
3820         len = asc_prt_line(cp, leftlen, " Command Queue Full:");
3821         ASC_PRT_NEXT();
3822         for (i = 0; i <= ASC_MAX_TID; i++) {
3823                 if ((chip_scsi_id == i) ||
3824                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3825                         continue;
3826                 }
3827                 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
3828                         len = asc_prt_line(cp, leftlen, " %X:Y-%d",
3829                                            i, boardp->queue_full_cnt[i]);
3830                 } else {
3831                         len = asc_prt_line(cp, leftlen, " %X:N", i);
3832                 }
3833                 ASC_PRT_NEXT();
3834         }
3835         len = asc_prt_line(cp, leftlen, "\n");
3836         ASC_PRT_NEXT();
3837
3838         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3839         ASC_PRT_NEXT();
3840         for (i = 0; i <= ASC_MAX_TID; i++) {
3841                 if ((chip_scsi_id == i) ||
3842                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3843                         continue;
3844                 }
3845                 len = asc_prt_line(cp, leftlen, " %X:%c",
3846                                    i,
3847                                    (v->
3848                                     sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3849                                    'N');
3850                 ASC_PRT_NEXT();
3851         }
3852         len = asc_prt_line(cp, leftlen, "\n");
3853         ASC_PRT_NEXT();
3854
3855         for (i = 0; i <= ASC_MAX_TID; i++) {
3856                 uchar syn_period_ix;
3857
3858                 if ((chip_scsi_id == i) ||
3859                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3860                     ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3861                         continue;
3862                 }
3863
3864                 len = asc_prt_line(cp, leftlen, "  %X:", i);
3865                 ASC_PRT_NEXT();
3866
3867                 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3868                         len = asc_prt_line(cp, leftlen, " Asynchronous");
3869                         ASC_PRT_NEXT();
3870                 } else {
3871                         syn_period_ix =
3872                             (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3873                                                            1);
3874
3875                         len = asc_prt_line(cp, leftlen,
3876                                            " Transfer Period Factor: %d (%d.%d Mhz),",
3877                                            v->sdtr_period_tbl[syn_period_ix],
3878                                            250 /
3879                                            v->sdtr_period_tbl[syn_period_ix],
3880                                            ASC_TENTHS(250,
3881                                                       v->
3882                                                       sdtr_period_tbl
3883                                                       [syn_period_ix]));
3884                         ASC_PRT_NEXT();
3885
3886                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3887                                            boardp->
3888                                            sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3889                         ASC_PRT_NEXT();
3890                 }
3891
3892                 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3893                         len = asc_prt_line(cp, leftlen, "*\n");
3894                         renegotiate = 1;
3895                 } else {
3896                         len = asc_prt_line(cp, leftlen, "\n");
3897                 }
3898                 ASC_PRT_NEXT();
3899         }
3900
3901         if (renegotiate) {
3902                 len = asc_prt_line(cp, leftlen,
3903                                    " * = Re-negotiation pending before next command.\n");
3904                 ASC_PRT_NEXT();
3905         }
3906
3907         return totlen;
3908 }
3909
3910 /*
3911  * asc_prt_adv_board_info()
3912  *
3913  * Print dynamic board configuration information.
3914  *
3915  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3916  * cf. asc_prt_line().
3917  *
3918  * Return the number of characters copied into 'cp'. No more than
3919  * 'cplen' characters will be copied to 'cp'.
3920  */
3921 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3922 {
3923         asc_board_t *boardp;
3924         int leftlen;
3925         int totlen;
3926         int len;
3927         int i;
3928         ADV_DVC_VAR *v;
3929         ADV_DVC_CFG *c;
3930         AdvPortAddr iop_base;
3931         ushort chip_scsi_id;
3932         ushort lramword;
3933         uchar lrambyte;
3934         ushort tagqng_able;
3935         ushort sdtr_able, wdtr_able;
3936         ushort wdtr_done, sdtr_done;
3937         ushort period = 0;
3938         int renegotiate = 0;
3939
3940         boardp = ASC_BOARDP(shost);
3941         v = &boardp->dvc_var.adv_dvc_var;
3942         c = &boardp->dvc_cfg.adv_dvc_cfg;
3943         iop_base = v->iop_base;
3944         chip_scsi_id = v->chip_scsi_id;
3945
3946         leftlen = cplen;
3947         totlen = len = 0;
3948
3949         len = asc_prt_line(cp, leftlen,
3950                            "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3951                            shost->host_no);
3952         ASC_PRT_NEXT();
3953
3954         len = asc_prt_line(cp, leftlen,
3955                            " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3956                            v->iop_base,
3957                            AdvReadWordRegister(iop_base,
3958                                                IOPW_SCSI_CFG1) & CABLE_DETECT,
3959                            v->err_code);
3960         ASC_PRT_NEXT();
3961
3962         len = asc_prt_line(cp, leftlen,
3963                            " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
3964                            c->chip_version, c->lib_version, c->mcode_date,
3965                            c->mcode_version);
3966         ASC_PRT_NEXT();
3967
3968         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3969         len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
3970         ASC_PRT_NEXT();
3971         for (i = 0; i <= ADV_MAX_TID; i++) {
3972                 if ((chip_scsi_id == i) ||
3973                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3974                         continue;
3975                 }
3976
3977                 len = asc_prt_line(cp, leftlen, " %X:%c",
3978                                    i,
3979                                    (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3980                                    'N');
3981                 ASC_PRT_NEXT();
3982         }
3983         len = asc_prt_line(cp, leftlen, "\n");
3984         ASC_PRT_NEXT();
3985
3986         len = asc_prt_line(cp, leftlen, " Queue Limit:");
3987         ASC_PRT_NEXT();
3988         for (i = 0; i <= ADV_MAX_TID; i++) {
3989                 if ((chip_scsi_id == i) ||
3990                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3991                         continue;
3992                 }
3993
3994                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3995                                 lrambyte);
3996
3997                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3998                 ASC_PRT_NEXT();
3999         }
4000         len = asc_prt_line(cp, leftlen, "\n");
4001         ASC_PRT_NEXT();
4002
4003         len = asc_prt_line(cp, leftlen, " Command Pending:");
4004         ASC_PRT_NEXT();
4005         for (i = 0; i <= ADV_MAX_TID; i++) {
4006                 if ((chip_scsi_id == i) ||
4007                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4008                         continue;
4009                 }
4010
4011                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
4012                                 lrambyte);
4013
4014                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
4015                 ASC_PRT_NEXT();
4016         }
4017         len = asc_prt_line(cp, leftlen, "\n");
4018         ASC_PRT_NEXT();
4019
4020         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
4021         len = asc_prt_line(cp, leftlen, " Wide Enabled:");
4022         ASC_PRT_NEXT();
4023         for (i = 0; i <= ADV_MAX_TID; i++) {
4024                 if ((chip_scsi_id == i) ||
4025                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4026                         continue;
4027                 }
4028
4029                 len = asc_prt_line(cp, leftlen, " %X:%c",
4030                                    i,
4031                                    (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4032                                    'N');
4033                 ASC_PRT_NEXT();
4034         }
4035         len = asc_prt_line(cp, leftlen, "\n");
4036         ASC_PRT_NEXT();
4037
4038         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
4039         len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
4040         ASC_PRT_NEXT();
4041         for (i = 0; i <= ADV_MAX_TID; i++) {
4042                 if ((chip_scsi_id == i) ||
4043                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4044                         continue;
4045                 }
4046
4047                 AdvReadWordLram(iop_base,
4048                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
4049                                 lramword);
4050
4051                 len = asc_prt_line(cp, leftlen, " %X:%d",
4052                                    i, (lramword & 0x8000) ? 16 : 8);
4053                 ASC_PRT_NEXT();
4054
4055                 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
4056                     (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4057                         len = asc_prt_line(cp, leftlen, "*");
4058                         ASC_PRT_NEXT();
4059                         renegotiate = 1;
4060                 }
4061         }
4062         len = asc_prt_line(cp, leftlen, "\n");
4063         ASC_PRT_NEXT();
4064
4065         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
4066         len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
4067         ASC_PRT_NEXT();
4068         for (i = 0; i <= ADV_MAX_TID; i++) {
4069                 if ((chip_scsi_id == i) ||
4070                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
4071                         continue;
4072                 }
4073
4074                 len = asc_prt_line(cp, leftlen, " %X:%c",
4075                                    i,
4076                                    (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
4077                                    'N');
4078                 ASC_PRT_NEXT();
4079         }
4080         len = asc_prt_line(cp, leftlen, "\n");
4081         ASC_PRT_NEXT();
4082
4083         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
4084         for (i = 0; i <= ADV_MAX_TID; i++) {
4085
4086                 AdvReadWordLram(iop_base,
4087                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
4088                                 lramword);
4089                 lramword &= ~0x8000;
4090
4091                 if ((chip_scsi_id == i) ||
4092                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
4093                     ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
4094                         continue;
4095                 }
4096
4097                 len = asc_prt_line(cp, leftlen, "  %X:", i);
4098                 ASC_PRT_NEXT();
4099
4100                 if ((lramword & 0x1F) == 0) {   /* Check for REQ/ACK Offset 0. */
4101                         len = asc_prt_line(cp, leftlen, " Asynchronous");
4102                         ASC_PRT_NEXT();
4103                 } else {
4104                         len =
4105                             asc_prt_line(cp, leftlen,
4106                                          " Transfer Period Factor: ");
4107                         ASC_PRT_NEXT();
4108
4109                         if ((lramword & 0x1F00) == 0x1100) {    /* 80 Mhz */
4110                                 len =
4111                                     asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
4112                                 ASC_PRT_NEXT();
4113                         } else if ((lramword & 0x1F00) == 0x1000) {     /* 40 Mhz */
4114                                 len =
4115                                     asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
4116                                 ASC_PRT_NEXT();
4117                         } else {        /* 20 Mhz or below. */
4118
4119                                 period = (((lramword >> 8) * 25) + 50) / 4;
4120
4121                                 if (period == 0) {      /* Should never happen. */
4122                                         len =
4123                                             asc_prt_line(cp, leftlen,
4124                                                          "%d (? Mhz), ");
4125                                         ASC_PRT_NEXT();
4126                                 } else {
4127                                         len = asc_prt_line(cp, leftlen,
4128                                                            "%d (%d.%d Mhz),",
4129                                                            period, 250 / period,
4130                                                            ASC_TENTHS(250,
4131                                                                       period));
4132                                         ASC_PRT_NEXT();
4133                                 }
4134                         }
4135
4136                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
4137                                            lramword & 0x1F);
4138                         ASC_PRT_NEXT();
4139                 }
4140
4141                 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4142                         len = asc_prt_line(cp, leftlen, "*\n");
4143                         renegotiate = 1;
4144                 } else {
4145                         len = asc_prt_line(cp, leftlen, "\n");
4146                 }
4147                 ASC_PRT_NEXT();
4148         }
4149
4150         if (renegotiate) {
4151                 len = asc_prt_line(cp, leftlen,
4152                                    " * = Re-negotiation pending before next command.\n");
4153                 ASC_PRT_NEXT();
4154         }
4155
4156         return totlen;
4157 }
4158
4159 /*
4160  * asc_proc_copy()
4161  *
4162  * Copy proc information to a read buffer taking into account the current
4163  * read offset in the file and the remaining space in the read buffer.
4164  */
4165 static int
4166 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4167               char *cp, int cplen)
4168 {
4169         int cnt = 0;
4170
4171         ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
4172                  (unsigned)offset, (unsigned)advoffset, cplen);
4173         if (offset <= advoffset) {
4174                 /* Read offset below current offset, copy everything. */
4175                 cnt = min(cplen, leftlen);
4176                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4177                          (ulong)curbuf, (ulong)cp, cnt);
4178                 memcpy(curbuf, cp, cnt);
4179         } else if (offset < advoffset + cplen) {
4180                 /* Read offset within current range, partial copy. */
4181                 cnt = (advoffset + cplen) - offset;
4182                 cp = (cp + cplen) - cnt;
4183                 cnt = min(cnt, leftlen);
4184                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4185                          (ulong)curbuf, (ulong)cp, cnt);
4186                 memcpy(curbuf, cp, cnt);
4187         }
4188         return cnt;
4189 }
4190
4191 #ifdef ADVANSYS_STATS
4192 /*
4193  * asc_prt_board_stats()
4194  *
4195  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4196  * cf. asc_prt_line().
4197  *
4198  * Return the number of characters copied into 'cp'. No more than
4199  * 'cplen' characters will be copied to 'cp'.
4200  */
4201 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
4202 {
4203         int leftlen;
4204         int totlen;
4205         int len;
4206         struct asc_stats *s;
4207         asc_board_t *boardp;
4208
4209         leftlen = cplen;
4210         totlen = len = 0;
4211
4212         boardp = ASC_BOARDP(shost);
4213         s = &boardp->asc_stats;
4214
4215         len = asc_prt_line(cp, leftlen,
4216                            "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
4217                            shost->host_no);
4218         ASC_PRT_NEXT();
4219
4220         len = asc_prt_line(cp, leftlen,
4221                            " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4222                            s->queuecommand, s->reset, s->biosparam,
4223                            s->interrupt);
4224         ASC_PRT_NEXT();
4225
4226         len = asc_prt_line(cp, leftlen,
4227                            " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
4228                            s->callback, s->done, s->build_error,
4229                            s->adv_build_noreq, s->adv_build_nosg);
4230         ASC_PRT_NEXT();
4231
4232         len = asc_prt_line(cp, leftlen,
4233                            " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
4234                            s->exe_noerror, s->exe_busy, s->exe_error,
4235                            s->exe_unknown);
4236         ASC_PRT_NEXT();
4237
4238         /*
4239          * Display data transfer statistics.
4240          */
4241         if (s->cont_cnt > 0) {
4242                 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
4243                 ASC_PRT_NEXT();
4244
4245                 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
4246                                    s->cont_xfer / 2,
4247                                    ASC_TENTHS(s->cont_xfer, 2));
4248                 ASC_PRT_NEXT();
4249
4250                 /* Contiguous transfer average size */
4251                 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
4252                                    (s->cont_xfer / 2) / s->cont_cnt,
4253                                    ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
4254                 ASC_PRT_NEXT();
4255         }
4256
4257         if (s->sg_cnt > 0) {
4258
4259                 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
4260                                    s->sg_cnt, s->sg_elem);
4261                 ASC_PRT_NEXT();
4262
4263                 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
4264                                    s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
4265                 ASC_PRT_NEXT();
4266
4267                 /* Scatter gather transfer statistics */
4268                 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
4269                                    s->sg_elem / s->sg_cnt,
4270                                    ASC_TENTHS(s->sg_elem, s->sg_cnt));
4271                 ASC_PRT_NEXT();
4272
4273                 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
4274                                    (s->sg_xfer / 2) / s->sg_elem,
4275                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
4276                 ASC_PRT_NEXT();
4277
4278                 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
4279                                    (s->sg_xfer / 2) / s->sg_cnt,
4280                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
4281                 ASC_PRT_NEXT();
4282         }
4283
4284         /*
4285          * Display request queuing statistics.
4286          */
4287         len = asc_prt_line(cp, leftlen,
4288                            " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
4289                            HZ);
4290         ASC_PRT_NEXT();
4291
4292         return totlen;
4293 }
4294 #endif /* ADVANSYS_STATS */
4295
4296 /*
4297  * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
4298  *
4299  * *buffer: I/O buffer
4300  * **start: if inout == FALSE pointer into buffer where user read should start
4301  * offset: current offset into a /proc/scsi/advansys/[0...] file
4302  * length: length of buffer
4303  * hostno: Scsi_Host host_no
4304  * inout: TRUE - user is writing; FALSE - user is reading
4305  *
4306  * Return the number of bytes read from or written to a
4307  * /proc/scsi/advansys/[0...] file.
4308  *
4309  * Note: This function uses the per board buffer 'prtbuf' which is
4310  * allocated when the board is initialized in advansys_detect(). The
4311  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4312  * used to write to the buffer. The way asc_proc_copy() is written
4313  * if 'prtbuf' is too small it will not be overwritten. Instead the
4314  * user just won't get all the available statistics.
4315  */
4316 static int
4317 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4318                    off_t offset, int length, int inout)
4319 {
4320         asc_board_t *boardp;
4321         char *cp;
4322         int cplen;
4323         int cnt;
4324         int totcnt;
4325         int leftlen;
4326         char *curbuf;
4327         off_t advoffset;
4328
4329         ASC_DBG(1, "advansys_proc_info: begin\n");
4330
4331         /*
4332          * User write not supported.
4333          */
4334         if (inout == TRUE) {
4335                 return (-ENOSYS);
4336         }
4337
4338         /*
4339          * User read of /proc/scsi/advansys/[0...] file.
4340          */
4341
4342         boardp = ASC_BOARDP(shost);
4343
4344         /* Copy read data starting at the beginning of the buffer. */
4345         *start = buffer;
4346         curbuf = buffer;
4347         advoffset = 0;
4348         totcnt = 0;
4349         leftlen = length;
4350
4351         /*
4352          * Get board configuration information.
4353          *
4354          * advansys_info() returns the board string from its own static buffer.
4355          */
4356         cp = (char *)advansys_info(shost);
4357         strcat(cp, "\n");
4358         cplen = strlen(cp);
4359         /* Copy board information. */
4360         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4361         totcnt += cnt;
4362         leftlen -= cnt;
4363         if (leftlen == 0) {
4364                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4365                 return totcnt;
4366         }
4367         advoffset += cplen;
4368         curbuf += cnt;
4369
4370         /*
4371          * Display Wide Board BIOS Information.
4372          */
4373         if (!ASC_NARROW_BOARD(boardp)) {
4374                 cp = boardp->prtbuf;
4375                 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4376                 BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4377                 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4378                                   cplen);
4379                 totcnt += cnt;
4380                 leftlen -= cnt;
4381                 if (leftlen == 0) {
4382                         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4383                         return totcnt;
4384                 }
4385                 advoffset += cplen;
4386                 curbuf += cnt;
4387         }
4388
4389         /*
4390          * Display driver information for each device attached to the board.
4391          */
4392         cp = boardp->prtbuf;
4393         cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4394         BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4395         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4396         totcnt += cnt;
4397         leftlen -= cnt;
4398         if (leftlen == 0) {
4399                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4400                 return totcnt;
4401         }
4402         advoffset += cplen;
4403         curbuf += cnt;
4404
4405         /*
4406          * Display EEPROM configuration for the board.
4407          */
4408         cp = boardp->prtbuf;
4409         if (ASC_NARROW_BOARD(boardp)) {
4410                 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4411         } else {
4412                 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4413         }
4414         BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4415         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4416         totcnt += cnt;
4417         leftlen -= cnt;
4418         if (leftlen == 0) {
4419                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4420                 return totcnt;
4421         }
4422         advoffset += cplen;
4423         curbuf += cnt;
4424
4425         /*
4426          * Display driver configuration and information for the board.
4427          */
4428         cp = boardp->prtbuf;
4429         cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4430         BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4431         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4432         totcnt += cnt;
4433         leftlen -= cnt;
4434         if (leftlen == 0) {
4435                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4436                 return totcnt;
4437         }
4438         advoffset += cplen;
4439         curbuf += cnt;
4440
4441 #ifdef ADVANSYS_STATS
4442         /*
4443          * Display driver statistics for the board.
4444          */
4445         cp = boardp->prtbuf;
4446         cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4447         BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4448         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4449         totcnt += cnt;
4450         leftlen -= cnt;
4451         if (leftlen == 0) {
4452                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4453                 return totcnt;
4454         }
4455         advoffset += cplen;
4456         curbuf += cnt;
4457 #endif /* ADVANSYS_STATS */
4458
4459         /*
4460          * Display Asc Library dynamic configuration information
4461          * for the board.
4462          */
4463         cp = boardp->prtbuf;
4464         if (ASC_NARROW_BOARD(boardp)) {
4465                 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4466         } else {
4467                 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4468         }
4469         BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4470         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4471         totcnt += cnt;
4472         leftlen -= cnt;
4473         if (leftlen == 0) {
4474                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4475                 return totcnt;
4476         }
4477         advoffset += cplen;
4478         curbuf += cnt;
4479
4480         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4481
4482         return totcnt;
4483 }
4484 #endif /* CONFIG_PROC_FS */
4485
4486 static void asc_scsi_done(struct scsi_cmnd *scp)
4487 {
4488         struct asc_board *boardp = ASC_BOARDP(scp->device->host);
4489
4490         if (scp->use_sg)
4491                 dma_unmap_sg(boardp->dev,
4492                              (struct scatterlist *)scp->request_buffer,
4493                              scp->use_sg, scp->sc_data_direction);
4494         else if (scp->request_bufflen)
4495                 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
4496                                  scp->request_bufflen, scp->sc_data_direction);
4497
4498         ASC_STATS(scp->device->host, done);
4499
4500         scp->scsi_done(scp);
4501 }
4502
4503 static void AscSetBank(PortAddr iop_base, uchar bank)
4504 {
4505         uchar val;
4506
4507         val = AscGetChipControl(iop_base) &
4508             (~
4509              (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
4510               CC_CHIP_RESET));
4511         if (bank == 1) {
4512                 val |= CC_BANK_ONE;
4513         } else if (bank == 2) {
4514                 val |= CC_DIAG | CC_BANK_ONE;
4515         } else {
4516                 val &= ~CC_BANK_ONE;
4517         }
4518         AscSetChipControl(iop_base, val);
4519         return;
4520 }
4521
4522 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4523 {
4524         AscSetBank(iop_base, 1);
4525         AscWriteChipIH(iop_base, ins_code);
4526         AscSetBank(iop_base, 0);
4527         return;
4528 }
4529
4530 static int AscStartChip(PortAddr iop_base)
4531 {
4532         AscSetChipControl(iop_base, 0);
4533         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4534                 return (0);
4535         }
4536         return (1);
4537 }
4538
4539 static int AscStopChip(PortAddr iop_base)
4540 {
4541         uchar cc_val;
4542
4543         cc_val =
4544             AscGetChipControl(iop_base) &
4545             (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
4546         AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
4547         AscSetChipIH(iop_base, INS_HALT);
4548         AscSetChipIH(iop_base, INS_RFLAG_WTM);
4549         if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
4550                 return (0);
4551         }
4552         return (1);
4553 }
4554
4555 static int AscIsChipHalted(PortAddr iop_base)
4556 {
4557         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4558                 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4559                         return (1);
4560                 }
4561         }
4562         return (0);
4563 }
4564
4565 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4566 {
4567         PortAddr iop_base;
4568         int i = 10;
4569
4570         iop_base = asc_dvc->iop_base;
4571         while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4572                && (i-- > 0)) {
4573                 mdelay(100);
4574         }
4575         AscStopChip(iop_base);
4576         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
4577         udelay(60);
4578         AscSetChipIH(iop_base, INS_RFLAG_WTM);
4579         AscSetChipIH(iop_base, INS_HALT);
4580         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
4581         AscSetChipControl(iop_base, CC_HALT);
4582         mdelay(200);
4583         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
4584         AscSetChipStatus(iop_base, 0);
4585         return (AscIsChipHalted(iop_base));
4586 }
4587
4588 static int AscFindSignature(PortAddr iop_base)
4589 {
4590         ushort sig_word;
4591
4592         ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
4593                  iop_base, AscGetChipSignatureByte(iop_base));
4594         if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
4595                 ASC_DBG2(1,
4596                          "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
4597                          iop_base, AscGetChipSignatureWord(iop_base));
4598                 sig_word = AscGetChipSignatureWord(iop_base);
4599                 if ((sig_word == (ushort)ASC_1000_ID0W) ||
4600                     (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
4601                         return (1);
4602                 }
4603         }
4604         return (0);
4605 }
4606
4607 static void AscEnableInterrupt(PortAddr iop_base)
4608 {
4609         ushort cfg;
4610
4611         cfg = AscGetChipCfgLsw(iop_base);
4612         AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
4613         return;
4614 }
4615
4616 static void AscDisableInterrupt(PortAddr iop_base)
4617 {
4618         ushort cfg;
4619
4620         cfg = AscGetChipCfgLsw(iop_base);
4621         AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
4622         return;
4623 }
4624
4625 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4626 {
4627         unsigned char byte_data;
4628         unsigned short word_data;
4629
4630         if (isodd_word(addr)) {
4631                 AscSetChipLramAddr(iop_base, addr - 1);
4632                 word_data = AscGetChipLramData(iop_base);
4633                 byte_data = (word_data >> 8) & 0xFF;
4634         } else {
4635                 AscSetChipLramAddr(iop_base, addr);
4636                 word_data = AscGetChipLramData(iop_base);
4637                 byte_data = word_data & 0xFF;
4638         }
4639         return byte_data;
4640 }
4641
4642 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4643 {
4644         ushort word_data;
4645
4646         AscSetChipLramAddr(iop_base, addr);
4647         word_data = AscGetChipLramData(iop_base);
4648         return (word_data);
4649 }
4650
4651 #if CC_VERY_LONG_SG_LIST
4652 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4653 {
4654         ushort val_low, val_high;
4655         ASC_DCNT dword_data;
4656
4657         AscSetChipLramAddr(iop_base, addr);
4658         val_low = AscGetChipLramData(iop_base);
4659         val_high = AscGetChipLramData(iop_base);
4660         dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
4661         return (dword_data);
4662 }
4663 #endif /* CC_VERY_LONG_SG_LIST */
4664
4665 static void
4666 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4667 {
4668         int i;
4669
4670         AscSetChipLramAddr(iop_base, s_addr);
4671         for (i = 0; i < words; i++) {
4672                 AscSetChipLramData(iop_base, set_wval);
4673         }
4674 }
4675
4676 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4677 {
4678         AscSetChipLramAddr(iop_base, addr);
4679         AscSetChipLramData(iop_base, word_val);
4680         return;
4681 }
4682
4683 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4684 {
4685         ushort word_data;
4686
4687         if (isodd_word(addr)) {
4688                 addr--;
4689                 word_data = AscReadLramWord(iop_base, addr);
4690                 word_data &= 0x00FF;
4691                 word_data |= (((ushort)byte_val << 8) & 0xFF00);
4692         } else {
4693                 word_data = AscReadLramWord(iop_base, addr);
4694                 word_data &= 0xFF00;
4695                 word_data |= ((ushort)byte_val & 0x00FF);
4696         }
4697         AscWriteLramWord(iop_base, addr, word_data);
4698         return;
4699 }
4700
4701 /*
4702  * Copy 2 bytes to LRAM.
4703  *
4704  * The source data is assumed to be in little-endian order in memory
4705  * and is maintained in little-endian order when written to LRAM.
4706  */
4707 static void
4708 AscMemWordCopyPtrToLram(PortAddr iop_base,
4709                         ushort s_addr, uchar *s_buffer, int words)
4710 {
4711         int i;
4712
4713         AscSetChipLramAddr(iop_base, s_addr);
4714         for (i = 0; i < 2 * words; i += 2) {
4715                 /*
4716                  * On a little-endian system the second argument below
4717                  * produces a little-endian ushort which is written to
4718                  * LRAM in little-endian order. On a big-endian system
4719                  * the second argument produces a big-endian ushort which
4720                  * is "transparently" byte-swapped by outpw() and written
4721                  * in little-endian order to LRAM.
4722                  */
4723                 outpw(iop_base + IOP_RAM_DATA,
4724                       ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4725         }
4726         return;
4727 }
4728
4729 /*
4730  * Copy 4 bytes to LRAM.
4731  *
4732  * The source data is assumed to be in little-endian order in memory
4733  * and is maintained in little-endian order when writen to LRAM.
4734  */
4735 static void
4736 AscMemDWordCopyPtrToLram(PortAddr iop_base,
4737                          ushort s_addr, uchar *s_buffer, int dwords)
4738 {
4739         int i;
4740
4741         AscSetChipLramAddr(iop_base, s_addr);
4742         for (i = 0; i < 4 * dwords; i += 4) {
4743                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);   /* LSW */
4744                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);       /* MSW */
4745         }
4746         return;
4747 }
4748
4749 /*
4750  * Copy 2 bytes from LRAM.
4751  *
4752  * The source data is assumed to be in little-endian order in LRAM
4753  * and is maintained in little-endian order when written to memory.
4754  */
4755 static void
4756 AscMemWordCopyPtrFromLram(PortAddr iop_base,
4757                           ushort s_addr, uchar *d_buffer, int words)
4758 {
4759         int i;
4760         ushort word;
4761
4762         AscSetChipLramAddr(iop_base, s_addr);
4763         for (i = 0; i < 2 * words; i += 2) {
4764                 word = inpw(iop_base + IOP_RAM_DATA);
4765                 d_buffer[i] = word & 0xff;
4766                 d_buffer[i + 1] = (word >> 8) & 0xff;
4767         }
4768         return;
4769 }
4770
4771 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4772 {
4773         ASC_DCNT sum;
4774         int i;
4775
4776         sum = 0L;
4777         for (i = 0; i < words; i++, s_addr += 2) {
4778                 sum += AscReadLramWord(iop_base, s_addr);
4779         }
4780         return (sum);
4781 }
4782
4783 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4784 {
4785         uchar i;
4786         ushort s_addr;
4787         PortAddr iop_base;
4788         ushort warn_code;
4789
4790         iop_base = asc_dvc->iop_base;
4791         warn_code = 0;
4792         AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
4793                           (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
4794                                     64) >> 1));
4795         i = ASC_MIN_ACTIVE_QNO;
4796         s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
4797         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4798                          (uchar)(i + 1));
4799         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4800                          (uchar)(asc_dvc->max_total_qng));
4801         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4802                          (uchar)i);
4803         i++;
4804         s_addr += ASC_QBLK_SIZE;
4805         for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
4806                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4807                                  (uchar)(i + 1));
4808                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4809                                  (uchar)(i - 1));
4810                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4811                                  (uchar)i);
4812         }
4813         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4814                          (uchar)ASC_QLINK_END);
4815         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4816                          (uchar)(asc_dvc->max_total_qng - 1));
4817         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4818                          (uchar)asc_dvc->max_total_qng);
4819         i++;
4820         s_addr += ASC_QBLK_SIZE;
4821         for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
4822              i++, s_addr += ASC_QBLK_SIZE) {
4823                 AscWriteLramByte(iop_base,
4824                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
4825                 AscWriteLramByte(iop_base,
4826                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
4827                 AscWriteLramByte(iop_base,
4828                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
4829         }
4830         return warn_code;
4831 }
4832
4833 static ASC_DCNT
4834 AscLoadMicroCode(PortAddr iop_base,
4835                  ushort s_addr, uchar *mcode_buf, ushort mcode_size)
4836 {
4837         ASC_DCNT chksum;
4838         ushort mcode_word_size;
4839         ushort mcode_chksum;
4840
4841         /* Write the microcode buffer starting at LRAM address 0. */
4842         mcode_word_size = (ushort)(mcode_size >> 1);
4843         AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
4844         AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
4845
4846         chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
4847         ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
4848         mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
4849                                                  (ushort)ASC_CODE_SEC_BEG,
4850                                                  (ushort)((mcode_size -
4851                                                            s_addr - (ushort)
4852                                                            ASC_CODE_SEC_BEG) /
4853                                                           2));
4854         ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
4855                  (ulong)mcode_chksum);
4856         AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4857         AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
4858         return (chksum);
4859 }
4860
4861 /* Microcode buffer is kept after initialization for error recovery. */
4862 static uchar _asc_mcode_buf[] = {
4863         0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4864         0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
4865         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4866         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4867         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4868         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
4869         0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870         0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4871         0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
4872         0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
4873         0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
4874         0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
4875         0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
4876         0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
4877         0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
4878         0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
4879         0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
4880         0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
4881         0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
4882         0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
4883         0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
4884         0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
4885         0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
4886         0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
4887         0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
4888         0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
4889         0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
4890         0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
4891         0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
4892         0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
4893         0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
4894         0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
4895         0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
4896         0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
4897         0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
4898         0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
4899         0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
4900         0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
4901         0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
4902         0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
4903         0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
4904         0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
4905         0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
4906         0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
4907         0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
4908         0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
4909         0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
4910         0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
4911         0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
4912         0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
4913         0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
4914         0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
4915         0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
4916         0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
4917         0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
4918         0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
4919         0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
4920         0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
4921         0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
4922         0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
4923         0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
4924         0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
4925         0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
4926         0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
4927         0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
4928         0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
4929         0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
4930         0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
4931         0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
4932         0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
4933         0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
4934         0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
4935         0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
4936         0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
4937         0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
4938         0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
4939         0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
4940         0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
4941         0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4942         0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
4943         0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4944         0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
4945         0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
4946         0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
4947         0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
4948         0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
4949         0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
4950         0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
4951         0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
4952         0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
4953         0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
4954         0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
4955         0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
4956         0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
4957         0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
4958         0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
4959         0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
4960         0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
4961         0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
4962         0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
4963         0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
4964         0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
4965         0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
4966         0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
4967         0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
4968         0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
4969         0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
4970         0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
4971         0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
4972         0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
4973         0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
4974         0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
4975         0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
4976         0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
4977         0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
4978         0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
4979         0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
4980         0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
4981         0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
4982         0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
4983         0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
4984         0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
4985         0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
4986         0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
4987         0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
4988         0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
4989         0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
4990         0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
4991         0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
4992         0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
4993         0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
4994         0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
4995         0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
4996         0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
4997         0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
4998         0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
4999         0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
5000         0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
5001         0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
5002         0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
5003         0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
5004         0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
5005         0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
5006         0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
5007         0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
5008         0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
5009         0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
5010         0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
5011         0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
5012         0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
5013         0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
5014         0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
5015         0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
5016         0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
5017         0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
5018         0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
5019         0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
5020         0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
5021         0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
5022         0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
5023         0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
5024         0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
5025         0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
5026         0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
5027         0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
5028         0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
5029         0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
5030         0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
5031         0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
5032         0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
5033         0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
5034         0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
5035         0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
5036         0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
5037         0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
5038         0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
5039         0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
5040         0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
5041         0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
5042         0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
5043         0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
5044         0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
5045         0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
5046         0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
5047         0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
5048         0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
5049         0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
5050         0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
5051         0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
5052         0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
5053         0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
5054         0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
5055 };
5056
5057 static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
5058 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
5059
5060 /* Microcode buffer is kept after initialization for error recovery. */
5061 static unsigned char _adv_asc3550_buf[] = {
5062         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
5063         0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
5064         0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
5065         0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
5066         0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
5067         0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
5068         0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
5069         0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
5070         0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
5071         0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5072         0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5073         0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
5074         0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
5075         0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5076         0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
5077         0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
5078         0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
5079         0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
5080         0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
5081         0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
5082         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
5083         0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
5084         0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
5085         0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
5086         0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
5087         0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
5088         0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
5089         0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
5090         0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
5091         0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
5092         0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
5093         0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
5094         0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
5095         0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
5096         0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
5097         0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
5098         0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
5099         0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
5100         0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
5101         0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
5102         0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
5103         0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
5104         0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
5105         0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
5106         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5107         0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
5108         0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5109         0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
5110         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5111         0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
5112         0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
5113         0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
5114         0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
5115         0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
5116         0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5117         0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
5118         0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
5119         0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
5120         0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
5121         0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
5122         0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
5123         0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
5124         0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
5125         0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
5126         0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5127         0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
5128         0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
5129         0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
5130         0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
5131         0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
5132         0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
5133         0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
5134         0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
5135         0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
5136         0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
5137         0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
5138         0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
5139         0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
5140         0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
5141         0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
5142         0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
5143         0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
5144         0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
5145         0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
5146         0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
5147         0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
5148         0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
5149         0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
5150         0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
5151         0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
5152         0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
5153         0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
5154         0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5155         0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
5156         0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
5157         0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
5158         0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
5159         0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
5160         0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
5161         0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
5162         0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
5163         0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
5164         0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
5165         0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
5166         0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
5167         0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
5168         0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
5169         0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
5170         0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
5171         0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
5172         0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
5173         0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
5174         0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
5175         0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
5176         0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
5177         0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
5178         0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
5179         0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
5180         0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
5181         0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
5182         0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
5183         0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
5184         0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
5185         0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
5186         0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
5187         0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
5188         0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
5189         0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
5190         0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
5191         0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
5192         0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
5193         0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
5194         0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
5195         0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
5196         0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
5197         0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
5198         0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
5199         0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
5200         0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
5201         0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
5202         0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
5203         0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
5204         0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
5205         0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
5206         0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
5207         0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5208         0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
5209         0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
5210         0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
5211         0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
5212         0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
5213         0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
5214         0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
5215         0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
5216         0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
5217         0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
5218         0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
5219         0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
5220         0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
5221         0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
5222         0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
5223         0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
5224         0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
5225         0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
5226         0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
5227         0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5228         0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
5229         0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
5230         0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
5231         0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
5232         0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
5233         0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
5234         0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
5235         0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
5236         0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
5237         0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
5238         0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
5239         0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
5240         0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
5241         0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
5242         0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
5243         0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
5244         0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
5245         0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
5246         0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
5247         0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
5248         0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
5249         0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
5250         0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
5251         0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
5252         0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
5253         0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
5254         0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5255         0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
5256         0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
5257         0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
5258         0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
5259         0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
5260         0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
5261         0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
5262         0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
5263         0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
5264         0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
5265         0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
5266         0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
5267         0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
5268         0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
5269         0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
5270         0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
5271         0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
5272         0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
5273         0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
5274         0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
5275         0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
5276         0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
5277         0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
5278         0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
5279         0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
5280         0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
5281         0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
5282         0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
5283         0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
5284         0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
5285         0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
5286         0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
5287         0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
5288         0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
5289         0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
5290         0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
5291         0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
5292         0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
5293         0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
5294         0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
5295         0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
5296         0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
5297         0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
5298         0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
5299         0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
5300         0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
5301         0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
5302         0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
5303         0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
5304         0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
5305         0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
5306         0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
5307         0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
5308         0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
5309         0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5310         0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
5311         0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
5312         0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
5313         0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
5314         0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5315         0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
5316         0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5317         0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
5318         0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
5319         0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
5320         0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5321         0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
5322         0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5323         0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
5324         0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5325         0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
5326         0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5327         0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
5328         0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
5329         0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
5330         0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
5331         0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
5332         0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5333         0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
5334         0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
5335         0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
5336         0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
5337         0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
5338         0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
5339         0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
5340         0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
5341         0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
5342         0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
5343         0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
5344         0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
5345         0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
5346         0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
5347         0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
5348         0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
5349         0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
5350         0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
5351         0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
5352         0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
5353         0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
5354         0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
5355         0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
5356         0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
5357         0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
5358         0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
5359         0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
5360         0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
5361         0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
5362         0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
5363         0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
5364         0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
5365         0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
5366         0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
5367         0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
5368         0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
5369         0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
5370         0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
5371         0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
5372         0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
5373         0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
5374         0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
5375         0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
5376         0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
5377         0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
5378         0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
5379         0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
5380         0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
5381         0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
5382         0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
5383         0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
5384         0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
5385         0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
5386         0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5387         0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
5388         0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
5389         0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5390         0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
5391         0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
5392         0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
5393         0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
5394         0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
5395         0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
5396         0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
5397         0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
5398         0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
5399         0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
5400         0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
5401         0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
5402         0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
5403         0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
5404         0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
5405         0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
5406         0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
5407         0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
5408         0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
5409         0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
5410         0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
5411         0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
5412         0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
5413         0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
5414         0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
5415         0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
5416         0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
5417         0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
5418         0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
5419         0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
5420         0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
5421         0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
5422         0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
5423         0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
5424         0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
5425         0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
5426         0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
5427         0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
5428         0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
5429         0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
5430         0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
5431         0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
5432         0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
5433         0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
5434         0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
5435         0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
5436         0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
5437         0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
5438         0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
5439         0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
5440         0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
5441         0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
5442         0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
5443         0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
5444         0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
5445         0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
5446         0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
5447         0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
5448         0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
5449         0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
5450         0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
5451         0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
5452         0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
5453         0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
5454         0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
5455         0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
5456         0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
5457         0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
5458         0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
5459         0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
5460         0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
5461         0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
5462         0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
5463         0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
5464         0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
5465         0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
5466         0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
5467         0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
5468         0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
5469         0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
5470         0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
5471         0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
5472         0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
5473         0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
5474         0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
5475         0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
5476         0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
5477         0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
5478         0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
5479         0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5480         0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
5481 };
5482
5483 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf);     /* 0x13AD */
5484 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL;     /* Expanded little-endian checksum. */
5485
5486 /* Microcode buffer is kept after initialization for error recovery. */
5487 static unsigned char _adv_asc38C0800_buf[] = {
5488         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
5489         0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
5490         0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
5491         0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
5492         0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
5493         0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
5494         0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
5495         0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
5496         0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
5497         0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
5498         0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
5499         0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5500         0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
5501         0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
5502         0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
5503         0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5504         0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
5505         0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
5506         0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
5507         0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
5508         0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
5509         0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
5510         0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
5511         0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
5512         0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
5513         0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
5514         0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
5515         0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
5516         0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
5517         0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
5518         0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
5519         0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
5520         0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
5521         0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
5522         0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
5523         0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
5524         0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
5525         0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
5526         0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
5527         0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
5528         0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
5529         0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
5530         0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
5531         0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
5532         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5533         0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
5534         0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5535         0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
5536         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5537         0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
5538         0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
5539         0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
5540         0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
5541         0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
5542         0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5543         0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
5544         0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
5545         0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
5546         0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
5547         0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
5548         0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
5549         0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
5550         0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
5551         0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
5552         0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5553         0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
5554         0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
5555         0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
5556         0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
5557         0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
5558         0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
5559         0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
5560         0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
5561         0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
5562         0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
5563         0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
5564         0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
5565         0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
5566         0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
5567         0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
5568         0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
5569         0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
5570         0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
5571         0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
5572         0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
5573         0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
5574         0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
5575         0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
5576         0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
5577         0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
5578         0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
5579         0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
5580         0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
5581         0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5582         0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
5583         0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
5584         0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
5585         0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
5586         0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
5587         0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
5588         0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5589         0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5590         0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
5591         0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
5592         0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
5593         0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
5594         0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
5595         0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
5596         0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
5597         0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
5598         0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
5599         0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
5600         0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
5601         0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
5602         0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
5603         0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
5604         0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
5605         0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
5606         0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
5607         0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
5608         0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
5609         0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
5610         0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
5611         0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
5612         0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
5613         0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
5614         0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
5615         0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
5616         0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
5617         0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
5618         0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
5619         0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
5620         0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
5621         0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
5622         0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
5623         0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
5624         0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
5625         0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
5626         0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
5627         0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
5628         0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
5629         0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
5630         0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
5631         0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
5632         0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
5633         0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
5634         0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
5635         0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
5636         0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
5637         0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
5638         0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
5639         0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
5640         0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
5641         0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
5642         0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
5643         0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
5644         0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
5645         0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
5646         0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
5647         0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
5648         0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
5649         0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
5650         0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
5651         0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
5652         0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
5653         0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
5654         0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
5655         0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
5656         0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
5657         0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
5658         0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
5659         0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
5660         0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
5661         0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
5662         0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
5663         0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
5664         0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
5665         0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
5666         0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
5667         0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
5668         0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
5669         0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
5670         0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
5671         0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
5672         0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
5673         0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
5674         0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
5675         0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
5676         0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
5677         0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
5678         0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
5679         0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
5680         0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
5681         0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
5682         0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
5683         0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
5684         0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
5685         0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
5686         0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
5687         0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
5688         0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
5689         0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
5690         0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
5691         0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
5692         0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
5693         0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
5694         0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
5695         0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
5696         0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
5697         0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
5698         0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
5699         0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
5700         0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
5701         0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
5702         0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
5703         0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
5704         0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
5705         0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
5706         0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
5707         0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
5708         0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
5709         0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
5710         0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
5711         0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
5712         0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
5713         0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
5714         0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
5715         0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
5716         0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
5717         0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
5718         0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
5719         0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
5720         0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
5721         0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
5722         0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
5723         0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
5724         0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
5725         0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
5726         0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
5727         0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
5728         0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
5729         0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
5730         0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
5731         0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
5732         0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
5733         0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
5734         0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
5735         0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
5736         0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
5737         0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
5738         0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
5739         0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
5740         0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
5741         0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
5742         0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
5743         0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
5744         0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
5745         0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
5746         0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
5747         0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
5748         0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
5749         0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
5750         0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
5751         0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
5752         0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
5753         0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
5754         0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
5755         0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
5756         0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
5757         0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5758         0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
5759         0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
5760         0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
5761         0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
5762         0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5763         0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
5764         0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5765         0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
5766         0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
5767         0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
5768         0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5769         0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
5770         0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5771         0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
5772         0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5773         0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
5774         0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5775         0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
5776         0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
5777         0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
5778         0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
5779         0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
5780         0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5781         0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
5782         0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
5783         0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
5784         0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
5785         0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
5786         0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
5787         0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
5788         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
5789         0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
5790         0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
5791         0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
5792         0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
5793         0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
5794         0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
5795         0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
5796         0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
5797         0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
5798         0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
5799         0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
5800         0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
5801         0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
5802         0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
5803         0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
5804         0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
5805         0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
5806         0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
5807         0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
5808         0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
5809         0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
5810         0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
5811         0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
5812         0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
5813         0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
5814         0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
5815         0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
5816         0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
5817         0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
5818         0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
5819         0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
5820         0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
5821         0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
5822         0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
5823         0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
5824         0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
5825         0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
5826         0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
5827         0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
5828         0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
5829         0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
5830         0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
5831         0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
5832         0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
5833         0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
5834         0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5835         0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
5836         0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
5837         0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5838         0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
5839         0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
5840         0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
5841         0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
5842         0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
5843         0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
5844         0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
5845         0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
5846         0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
5847         0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
5848         0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
5849         0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
5850         0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
5851         0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
5852         0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
5853         0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
5854         0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
5855         0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
5856         0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
5857         0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
5858         0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
5859         0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
5860         0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
5861         0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
5862         0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
5863         0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
5864         0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5865         0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5866         0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
5867         0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
5868         0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
5869         0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
5870         0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
5871         0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
5872         0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
5873         0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
5874         0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
5875         0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
5876         0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
5877         0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
5878         0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
5879         0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
5880         0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
5881         0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
5882         0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
5883         0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
5884         0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
5885         0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
5886         0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
5887         0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
5888         0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
5889         0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
5890         0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
5891         0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
5892         0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
5893         0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
5894         0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
5895         0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
5896         0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
5897         0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
5898         0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
5899         0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
5900         0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
5901         0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
5902         0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
5903         0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
5904         0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
5905         0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
5906         0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
5907         0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
5908         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
5909         0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
5910         0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
5911         0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
5912         0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
5913         0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
5914         0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
5915         0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
5916         0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
5917         0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
5918         0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
5919         0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
5920         0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
5921         0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
5922         0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
5923         0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
5924         0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
5925         0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
5926         0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
5927         0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
5928         0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
5929         0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
5930         0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
5931         0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
5932         0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
5933 };
5934
5935 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf);       /* 0x14E1 */
5936 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL;  /* Expanded little-endian checksum. */
5937
5938 /* Microcode buffer is kept after initialization for error recovery. */
5939 static unsigned char _adv_asc38C1600_buf[] = {
5940         0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
5941         0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
5942         0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
5943         0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
5944         0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
5945         0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
5946         0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
5947         0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
5948         0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
5949         0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
5950         0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
5951         0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
5952         0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5953         0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
5954         0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
5955         0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
5956         0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
5957         0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
5958         0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
5959         0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
5960         0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
5961         0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
5962         0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
5963         0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
5964         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
5965         0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
5966         0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
5967         0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
5968         0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
5969         0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
5970         0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
5971         0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
5972         0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
5973         0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
5974         0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
5975         0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
5976         0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
5977         0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
5978         0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
5979         0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
5980         0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
5981         0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
5982         0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
5983         0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
5984         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5985         0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
5986         0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5987         0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
5988         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5989         0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
5990         0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
5991         0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
5992         0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
5993         0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
5994         0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
5995         0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
5996         0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
5997         0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
5998         0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
5999         0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
6000         0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
6001         0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
6002         0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
6003         0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
6004         0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
6005         0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
6006         0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
6007         0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
6008         0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
6009         0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
6010         0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
6011         0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
6012         0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
6013         0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
6014         0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
6015         0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
6016         0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
6017         0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
6018         0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
6019         0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
6020         0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
6021         0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
6022         0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
6023         0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
6024         0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
6025         0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
6026         0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
6027         0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
6028         0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
6029         0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
6030         0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
6031         0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
6032         0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
6033         0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
6034         0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
6035         0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
6036         0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
6037         0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
6038         0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
6039         0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
6040         0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
6041         0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
6042         0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
6043         0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
6044         0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
6045         0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
6046         0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
6047         0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
6048         0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
6049         0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
6050         0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
6051         0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
6052         0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
6053         0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
6054         0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
6055         0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
6056         0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
6057         0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
6058         0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
6059         0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
6060         0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
6061         0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
6062         0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
6063         0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
6064         0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
6065         0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
6066         0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
6067         0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
6068         0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
6069         0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
6070         0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
6071         0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
6072         0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
6073         0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
6074         0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
6075         0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
6076         0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
6077         0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
6078         0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
6079         0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
6080         0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
6081         0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
6082         0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
6083         0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
6084         0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
6085         0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
6086         0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
6087         0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
6088         0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
6089         0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
6090         0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
6091         0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
6092         0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
6093         0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
6094         0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
6095         0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
6096         0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
6097         0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
6098         0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
6099         0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
6100         0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
6101         0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
6102         0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
6103         0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
6104         0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
6105         0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
6106         0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
6107         0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
6108         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
6109         0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
6110         0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
6111         0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
6112         0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
6113         0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
6114         0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
6115         0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
6116         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
6117         0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
6118         0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
6119         0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
6120         0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
6121         0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
6122         0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
6123         0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
6124         0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
6125         0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
6126         0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
6127         0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
6128         0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
6129         0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
6130         0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
6131         0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
6132         0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
6133         0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
6134         0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
6135         0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
6136         0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
6137         0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
6138         0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
6139         0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
6140         0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
6141         0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
6142         0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
6143         0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
6144         0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
6145         0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
6146         0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
6147         0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
6148         0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
6149         0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
6150         0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
6151         0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
6152         0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
6153         0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
6154         0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
6155         0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
6156         0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
6157         0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
6158         0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
6159         0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
6160         0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
6161         0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
6162         0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
6163         0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
6164         0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
6165         0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
6166         0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
6167         0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
6168         0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
6169         0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
6170         0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
6171         0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
6172         0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
6173         0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
6174         0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
6175         0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
6176         0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
6177         0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
6178         0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
6179         0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
6180         0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
6181         0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
6182         0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
6183         0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
6184         0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
6185         0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
6186         0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
6187         0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
6188         0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
6189         0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
6190         0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
6191         0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
6192         0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
6193         0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
6194         0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
6195         0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
6196         0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
6197         0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
6198         0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
6199         0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
6200         0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
6201         0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
6202         0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
6203         0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
6204         0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
6205         0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
6206         0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
6207         0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
6208         0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
6209         0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
6210         0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
6211         0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
6212         0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
6213         0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
6214         0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
6215         0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
6216         0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
6217         0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
6218         0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
6219         0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
6220         0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
6221         0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
6222         0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
6223         0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
6224         0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
6225         0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
6226         0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
6227         0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
6228         0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
6229         0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
6230         0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
6231         0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
6232         0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
6233         0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
6234         0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
6235         0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
6236         0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
6237         0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
6238         0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
6239         0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
6240         0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
6241         0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
6242         0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
6243         0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
6244         0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
6245         0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
6246         0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
6247         0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
6248         0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
6249         0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
6250         0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
6251         0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
6252         0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
6253         0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
6254         0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
6255         0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
6256         0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
6257         0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
6258         0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
6259         0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
6260         0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
6261         0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
6262         0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
6263         0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
6264         0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
6265         0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
6266         0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
6267         0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
6268         0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
6269         0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
6270         0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
6271         0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
6272         0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
6273         0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
6274         0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
6275         0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
6276         0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
6277         0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6278         0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
6279         0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
6280         0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6281         0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
6282         0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
6283         0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
6284         0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
6285         0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
6286         0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
6287         0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
6288         0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
6289         0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
6290         0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
6291         0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
6292         0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
6293         0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
6294         0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
6295         0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
6296         0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
6297         0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
6298         0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
6299         0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
6300         0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
6301         0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
6302         0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
6303         0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
6304         0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
6305         0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
6306         0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
6307         0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
6308         0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
6309         0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
6310         0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
6311         0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
6312         0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
6313         0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
6314         0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
6315         0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
6316         0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6317         0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
6318         0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
6319         0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6320         0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
6321         0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
6322         0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
6323         0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
6324         0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
6325         0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
6326         0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
6327         0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
6328         0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
6329         0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
6330         0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
6331         0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
6332         0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
6333         0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
6334         0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
6335         0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
6336         0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
6337         0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
6338         0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
6339         0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
6340         0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
6341         0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
6342         0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
6343         0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
6344         0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
6345         0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
6346         0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
6347         0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
6348         0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
6349         0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
6350         0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
6351         0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
6352         0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
6353         0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
6354         0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
6355         0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
6356         0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
6357         0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
6358         0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
6359         0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
6360         0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
6361         0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
6362         0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
6363         0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
6364         0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
6365         0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
6366         0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
6367         0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
6368         0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
6369         0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
6370         0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
6371         0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
6372         0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
6373         0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
6374         0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6375         0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6376         0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
6377         0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
6378         0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
6379         0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
6380         0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
6381         0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
6382         0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
6383         0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
6384         0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
6385         0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
6386         0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
6387         0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
6388         0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
6389         0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
6390         0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
6391         0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
6392         0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
6393         0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
6394         0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
6395         0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
6396         0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
6397         0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
6398         0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
6399         0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
6400         0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
6401         0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
6402         0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
6403         0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
6404         0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
6405         0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
6406         0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
6407         0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
6408         0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
6409         0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
6410         0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
6411         0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
6412         0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
6413         0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
6414         0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
6415         0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
6416         0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
6417         0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
6418         0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
6419         0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
6420         0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
6421         0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
6422         0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
6423         0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
6424         0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
6425         0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
6426         0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
6427         0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
6428         0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
6429         0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
6430         0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
6431         0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
6432         0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
6433         0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
6434         0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
6435         0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
6436         0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
6437         0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
6438         0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
6439         0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
6440         0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
6441         0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
6442         0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
6443         0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
6444         0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
6445         0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
6446         0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
6447         0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
6448         0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
6449         0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
6450         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
6451         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
6452         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
6453         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
6454         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
6455         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
6456         0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
6457         0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
6458         0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
6459         0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6460         0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6461         0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6462         0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6463         0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6464         0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6465         0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
6466         0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
6467         0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
6468 };
6469
6470 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf);       /* 0x1673 */
6471 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL;  /* Expanded little-endian checksum. */
6472
6473 static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6474 {
6475         PortAddr iop_base;
6476         int i;
6477         ushort lram_addr;
6478
6479         iop_base = asc_dvc->iop_base;
6480         AscPutRiscVarFreeQHead(iop_base, 1);
6481         AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6482         AscPutVarFreeQHead(iop_base, 1);
6483         AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6484         AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6485                          (uchar)((int)asc_dvc->max_total_qng + 1));
6486         AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6487                          (uchar)((int)asc_dvc->max_total_qng + 2));
6488         AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
6489                          asc_dvc->max_total_qng);
6490         AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6491         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6492         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6493         AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6494         AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6495         AscPutQDoneInProgress(iop_base, 0);
6496         lram_addr = ASC_QADR_BEG;
6497         for (i = 0; i < 32; i++, lram_addr += 2) {
6498                 AscWriteLramWord(iop_base, lram_addr, 0);
6499         }
6500 }
6501
6502 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6503 {
6504         int i;
6505         ushort warn_code;
6506         PortAddr iop_base;
6507         ASC_PADDR phy_addr;
6508         ASC_DCNT phy_size;
6509
6510         iop_base = asc_dvc->iop_base;
6511         warn_code = 0;
6512         for (i = 0; i <= ASC_MAX_TID; i++) {
6513                 AscPutMCodeInitSDTRAtID(iop_base, i,
6514                                         asc_dvc->cfg->sdtr_period_offset[i]);
6515         }
6516
6517         AscInitQLinkVar(asc_dvc);
6518         AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
6519                          asc_dvc->cfg->disc_enable);
6520         AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
6521                          ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
6522
6523         /* Align overrun buffer on an 8 byte boundary. */
6524         phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
6525         phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
6526         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
6527                                  (uchar *)&phy_addr, 1);
6528         phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
6529         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
6530                                  (uchar *)&phy_size, 1);
6531
6532         asc_dvc->cfg->mcode_date =
6533             AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
6534         asc_dvc->cfg->mcode_version =
6535             AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
6536
6537         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6538         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6539                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
6540                 return warn_code;
6541         }
6542         if (AscStartChip(iop_base) != 1) {
6543                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6544                 return warn_code;
6545         }
6546
6547         return warn_code;
6548 }
6549
6550 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6551 {
6552         ushort warn_code;
6553         PortAddr iop_base;
6554
6555         iop_base = asc_dvc->iop_base;
6556         warn_code = 0;
6557         if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
6558             !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
6559                 AscResetChipAndScsiBus(asc_dvc);
6560                 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6561         }
6562         asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
6563         if (asc_dvc->err_code != 0)
6564                 return UW_ERR;
6565         if (!AscFindSignature(asc_dvc->iop_base)) {
6566                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
6567                 return warn_code;
6568         }
6569         AscDisableInterrupt(iop_base);
6570         warn_code |= AscInitLram(asc_dvc);
6571         if (asc_dvc->err_code != 0)
6572                 return UW_ERR;
6573         ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
6574                  (ulong)_asc_mcode_chksum);
6575         if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
6576                              _asc_mcode_size) != _asc_mcode_chksum) {
6577                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
6578                 return warn_code;
6579         }
6580         warn_code |= AscInitMicroCodeVar(asc_dvc);
6581         asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
6582         AscEnableInterrupt(iop_base);
6583         return warn_code;
6584 }
6585
6586 /*
6587  * Load the Microcode
6588  *
6589  * Write the microcode image to RISC memory starting at address 0.
6590  *
6591  * The microcode is stored compressed in the following format:
6592  *
6593  *  254 word (508 byte) table indexed by byte code followed
6594  *  by the following byte codes:
6595  *
6596  *    1-Byte Code:
6597  *      00: Emit word 0 in table.
6598  *      01: Emit word 1 in table.
6599  *      .
6600  *      FD: Emit word 253 in table.
6601  *
6602  *    Multi-Byte Code:
6603  *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
6604  *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
6605  *
6606  * Returns 0 or an error if the checksum doesn't match
6607  */
6608 static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6609                             int memsize, int chksum)
6610 {
6611         int i, j, end, len = 0;
6612         ADV_DCNT sum;
6613
6614         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6615
6616         for (i = 253 * 2; i < size; i++) {
6617                 if (buf[i] == 0xff) {
6618                         unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
6619                         for (j = 0; j < buf[i + 1]; j++) {
6620                                 AdvWriteWordAutoIncLram(iop_base, word);
6621                                 len += 2;
6622                         }
6623                         i += 3;
6624                 } else if (buf[i] == 0xfe) {
6625                         unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
6626                         AdvWriteWordAutoIncLram(iop_base, word);
6627                         i += 2;
6628                         len += 2;
6629                 } else {
6630                         unsigned char off = buf[i] * 2;
6631                         unsigned short word = (buf[off + 1] << 8) | buf[off];
6632                         AdvWriteWordAutoIncLram(iop_base, word);
6633                         len += 2;
6634                 }
6635         }
6636
6637         end = len;
6638
6639         while (len < memsize) {
6640                 AdvWriteWordAutoIncLram(iop_base, 0);
6641                 len += 2;
6642         }
6643
6644         /* Verify the microcode checksum. */
6645         sum = 0;
6646         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6647
6648         for (len = 0; len < end; len += 2) {
6649                 sum += AdvReadWordAutoIncLram(iop_base);
6650         }
6651
6652         if (sum != chksum)
6653                 return ASC_IERR_MCODE_CHKSUM;
6654
6655         return 0;
6656 }
6657
6658 /*
6659  * DvcGetPhyAddr()
6660  *
6661  * Return the physical address of 'vaddr' and set '*lenp' to the
6662  * number of physically contiguous bytes that follow 'vaddr'.
6663  * 'flag' indicates the type of structure whose physical address
6664  * is being translated.
6665  *
6666  * Note: Because Linux currently doesn't page the kernel and all
6667  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6668  */
6669 ADV_PADDR
6670 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
6671               uchar *vaddr, ADV_SDCNT *lenp, int flag)
6672 {
6673         ADV_PADDR paddr = virt_to_bus(vaddr);
6674
6675         ASC_DBG4(4, "DvcGetPhyAddr: vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n",
6676                  vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr);
6677
6678         return paddr;
6679 }
6680
6681 static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6682 {
6683         ADV_CARR_T *carrp;
6684         ADV_SDCNT buf_size;
6685         ADV_PADDR carr_paddr;
6686
6687         BUG_ON(!asc_dvc->carrier_buf);
6688
6689         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
6690         asc_dvc->carr_freelist = NULL;
6691         if (carrp == asc_dvc->carrier_buf) {
6692                 buf_size = ADV_CARRIER_BUFSIZE;
6693         } else {
6694                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
6695         }
6696
6697         do {
6698                 /* Get physical address of the carrier 'carrp'. */
6699                 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
6700                 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
6701                                                        (uchar *)carrp,
6702                                                        (ADV_SDCNT *)&contig_len,
6703                                                        ADV_IS_CARRIER_FLAG));
6704
6705                 buf_size -= sizeof(ADV_CARR_T);
6706
6707                 /*
6708                  * If the current carrier is not physically contiguous, then
6709                  * maybe there was a page crossing. Try the next carrier
6710                  * aligned start address.
6711                  */
6712                 if (contig_len < sizeof(ADV_CARR_T)) {
6713                         carrp++;
6714                         continue;
6715                 }
6716
6717                 carrp->carr_pa = carr_paddr;
6718                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6719
6720                 /*
6721                  * Insert the carrier at the beginning of the freelist.
6722                  */
6723                 carrp->next_vpa =
6724                         cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6725                 asc_dvc->carr_freelist = carrp;
6726
6727                 carrp++;
6728         } while (buf_size > 0);
6729 }
6730
6731 /*
6732  * Send an idle command to the chip and wait for completion.
6733  *
6734  * Command completion is polled for once per microsecond.
6735  *
6736  * The function can be called from anywhere including an interrupt handler.
6737  * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
6738  * functions to prevent reentrancy.
6739  *
6740  * Return Values:
6741  *   ADV_TRUE - command completed successfully
6742  *   ADV_FALSE - command failed
6743  *   ADV_ERROR - command timed out
6744  */
6745 static int
6746 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6747                ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6748 {
6749         int result;
6750         ADV_DCNT i, j;
6751         AdvPortAddr iop_base;
6752
6753         iop_base = asc_dvc->iop_base;
6754
6755         /*
6756          * Clear the idle command status which is set by the microcode
6757          * to a non-zero value to indicate when the command is completed.
6758          * The non-zero result is one of the IDLE_CMD_STATUS_* values
6759          */
6760         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6761
6762         /*
6763          * Write the idle command value after the idle command parameter
6764          * has been written to avoid a race condition. If the order is not
6765          * followed, the microcode may process the idle command before the
6766          * parameters have been written to LRAM.
6767          */
6768         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
6769                                 cpu_to_le32(idle_cmd_parameter));
6770         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
6771
6772         /*
6773          * Tickle the RISC to tell it to process the idle command.
6774          */
6775         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6776         if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6777                 /*
6778                  * Clear the tickle value. In the ASC-3550 the RISC flag
6779                  * command 'clr_tickle_b' does not work unless the host
6780                  * value is cleared.
6781                  */
6782                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6783         }
6784
6785         /* Wait for up to 100 millisecond for the idle command to timeout. */
6786         for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
6787                 /* Poll once each microsecond for command completion. */
6788                 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
6789                         AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
6790                                         result);
6791                         if (result != 0)
6792                                 return result;
6793                         udelay(1);
6794                 }
6795         }
6796
6797         BUG();          /* The idle command should never timeout. */
6798         return ADV_ERROR;
6799 }
6800
6801 /*
6802  * Reset SCSI Bus and purge all outstanding requests.
6803  *
6804  * Return Value:
6805  *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
6806  *      ADV_FALSE(0) -  Microcode command failed.
6807  *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
6808  *                      may be hung which requires driver recovery.
6809  */
6810 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6811 {
6812         int status;
6813
6814         /*
6815          * Send the SCSI Bus Reset idle start idle command which asserts
6816          * the SCSI Bus Reset signal.
6817          */
6818         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6819         if (status != ADV_TRUE) {
6820                 return status;
6821         }
6822
6823         /*
6824          * Delay for the specified SCSI Bus Reset hold time.
6825          *
6826          * The hold time delay is done on the host because the RISC has no
6827          * microsecond accurate timer.
6828          */
6829         udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6830
6831         /*
6832          * Send the SCSI Bus Reset end idle command which de-asserts
6833          * the SCSI Bus Reset signal and purges any pending requests.
6834          */
6835         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6836         if (status != ADV_TRUE) {
6837                 return status;
6838         }
6839
6840         mdelay(asc_dvc->scsi_reset_wait * 1000);        /* XXX: msleep? */
6841
6842         return status;
6843 }
6844
6845 /*
6846  * Initialize the ASC-3550.
6847  *
6848  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6849  *
6850  * For a non-fatal error return a warning code. If there are no warnings
6851  * then 0 is returned.
6852  *
6853  * Needed after initialization for error recovery.
6854  */
6855 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6856 {
6857         AdvPortAddr iop_base;
6858         ushort warn_code;
6859         int begin_addr;
6860         int end_addr;
6861         ushort code_sum;
6862         int word;
6863         int i;
6864         ushort scsi_cfg1;
6865         uchar tid;
6866         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
6867         ushort wdtr_able = 0, sdtr_able, tagqng_able;
6868         uchar max_cmd[ADV_MAX_TID + 1];
6869
6870         /* If there is already an error, don't continue. */
6871         if (asc_dvc->err_code != 0)
6872                 return ADV_ERROR;
6873
6874         /*
6875          * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6876          */
6877         if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6878                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6879                 return ADV_ERROR;
6880         }
6881
6882         warn_code = 0;
6883         iop_base = asc_dvc->iop_base;
6884
6885         /*
6886          * Save the RISC memory BIOS region before writing the microcode.
6887          * The BIOS may already be loaded and using its RISC LRAM region
6888          * so its region must be saved and restored.
6889          *
6890          * Note: This code makes the assumption, which is currently true,
6891          * that a chip reset does not clear RISC LRAM.
6892          */
6893         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6894                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6895                                 bios_mem[i]);
6896         }
6897
6898         /*
6899          * Save current per TID negotiated values.
6900          */
6901         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6902                 ushort bios_version, major, minor;
6903
6904                 bios_version =
6905                     bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
6906                 major = (bios_version >> 12) & 0xF;
6907                 minor = (bios_version >> 8) & 0xF;
6908                 if (major < 3 || (major == 3 && minor == 1)) {
6909                         /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
6910                         AdvReadWordLram(iop_base, 0x120, wdtr_able);
6911                 } else {
6912                         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6913                 }
6914         }
6915         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6916         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6917         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6918                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
6919                                 max_cmd[tid]);
6920         }
6921
6922         asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
6923                                         _adv_asc3550_size, ADV_3550_MEMSIZE,
6924                                         _adv_asc3550_chksum);
6925         if (asc_dvc->err_code)
6926                 return ADV_ERROR;
6927
6928         /*
6929          * Restore the RISC memory BIOS region.
6930          */
6931         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6932                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6933                                  bios_mem[i]);
6934         }
6935
6936         /*
6937          * Calculate and write the microcode code checksum to the microcode
6938          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6939          */
6940         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
6941         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
6942         code_sum = 0;
6943         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
6944         for (word = begin_addr; word < end_addr; word += 2) {
6945                 code_sum += AdvReadWordAutoIncLram(iop_base);
6946         }
6947         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6948
6949         /*
6950          * Read and save microcode version and date.
6951          */
6952         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
6953                         asc_dvc->cfg->mcode_date);
6954         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
6955                         asc_dvc->cfg->mcode_version);
6956
6957         /*
6958          * Set the chip type to indicate the ASC3550.
6959          */
6960         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6961
6962         /*
6963          * If the PCI Configuration Command Register "Parity Error Response
6964          * Control" Bit was clear (0), then set the microcode variable
6965          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
6966          * to ignore DMA parity errors.
6967          */
6968         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
6969                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6970                 word |= CONTROL_FLAG_IGNORE_PERR;
6971                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6972         }
6973
6974         /*
6975          * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
6976          * threshold of 128 bytes. This register is only accessible to the host.
6977          */
6978         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6979                              START_CTL_EMFU | READ_CMD_MRM);
6980
6981         /*
6982          * Microcode operating variables for WDTR, SDTR, and command tag
6983          * queuing will be set in slave_configure() based on what a
6984          * device reports it is capable of in Inquiry byte 7.
6985          *
6986          * If SCSI Bus Resets have been disabled, then directly set
6987          * SDTR and WDTR from the EEPROM configuration. This will allow
6988          * the BIOS and warm boot to work without a SCSI bus hang on
6989          * the Inquiry caused by host and target mismatched DTR values.
6990          * Without the SCSI Bus Reset, before an Inquiry a device can't
6991          * be assumed to be in Asynchronous, Narrow mode.
6992          */
6993         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
6994                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
6995                                  asc_dvc->wdtr_able);
6996                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
6997                                  asc_dvc->sdtr_able);
6998         }
6999
7000         /*
7001          * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
7002          * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
7003          * bitmask. These values determine the maximum SDTR speed negotiated
7004          * with a device.
7005          *
7006          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7007          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7008          * without determining here whether the device supports SDTR.
7009          *
7010          * 4-bit speed  SDTR speed name
7011          * ===========  ===============
7012          * 0000b (0x0)  SDTR disabled
7013          * 0001b (0x1)  5 Mhz
7014          * 0010b (0x2)  10 Mhz
7015          * 0011b (0x3)  20 Mhz (Ultra)
7016          * 0100b (0x4)  40 Mhz (LVD/Ultra2)
7017          * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
7018          * 0110b (0x6)  Undefined
7019          * .
7020          * 1111b (0xF)  Undefined
7021          */
7022         word = 0;
7023         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7024                 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
7025                         /* Set Ultra speed for TID 'tid'. */
7026                         word |= (0x3 << (4 * (tid % 4)));
7027                 } else {
7028                         /* Set Fast speed for TID 'tid'. */
7029                         word |= (0x2 << (4 * (tid % 4)));
7030                 }
7031                 if (tid == 3) { /* Check if done with sdtr_speed1. */
7032                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
7033                         word = 0;
7034                 } else if (tid == 7) {  /* Check if done with sdtr_speed2. */
7035                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
7036                         word = 0;
7037                 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
7038                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
7039                         word = 0;
7040                 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
7041                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
7042                         /* End of loop. */
7043                 }
7044         }
7045
7046         /*
7047          * Set microcode operating variable for the disconnect per TID bitmask.
7048          */
7049         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7050                          asc_dvc->cfg->disc_enable);
7051
7052         /*
7053          * Set SCSI_CFG0 Microcode Default Value.
7054          *
7055          * The microcode will set the SCSI_CFG0 register using this value
7056          * after it is started below.
7057          */
7058         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7059                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7060                          asc_dvc->chip_scsi_id);
7061
7062         /*
7063          * Determine SCSI_CFG1 Microcode Default Value.
7064          *
7065          * The microcode will set the SCSI_CFG1 register using this value
7066          * after it is started below.
7067          */
7068
7069         /* Read current SCSI_CFG1 Register value. */
7070         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7071
7072         /*
7073          * If all three connectors are in use, return an error.
7074          */
7075         if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
7076             (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
7077                 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
7078                 return ADV_ERROR;
7079         }
7080
7081         /*
7082          * If the internal narrow cable is reversed all of the SCSI_CTRL
7083          * register signals will be set. Check for and return an error if
7084          * this condition is found.
7085          */
7086         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7087                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7088                 return ADV_ERROR;
7089         }
7090
7091         /*
7092          * If this is a differential board and a single-ended device
7093          * is attached to one of the connectors, return an error.
7094          */
7095         if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
7096                 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
7097                 return ADV_ERROR;
7098         }
7099
7100         /*
7101          * If automatic termination control is enabled, then set the
7102          * termination value based on a table listed in a_condor.h.
7103          *
7104          * If manual termination was specified with an EEPROM setting
7105          * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
7106          * is ready to be 'ored' into SCSI_CFG1.
7107          */
7108         if (asc_dvc->cfg->termination == 0) {
7109                 /*
7110                  * The software always controls termination by setting TERM_CTL_SEL.
7111                  * If TERM_CTL_SEL were set to 0, the hardware would set termination.
7112                  */
7113                 asc_dvc->cfg->termination |= TERM_CTL_SEL;
7114
7115                 switch (scsi_cfg1 & CABLE_DETECT) {
7116                         /* TERM_CTL_H: on, TERM_CTL_L: on */
7117                 case 0x3:
7118                 case 0x7:
7119                 case 0xB:
7120                 case 0xD:
7121                 case 0xE:
7122                 case 0xF:
7123                         asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
7124                         break;
7125
7126                         /* TERM_CTL_H: on, TERM_CTL_L: off */
7127                 case 0x1:
7128                 case 0x5:
7129                 case 0x9:
7130                 case 0xA:
7131                 case 0xC:
7132                         asc_dvc->cfg->termination |= TERM_CTL_H;
7133                         break;
7134
7135                         /* TERM_CTL_H: off, TERM_CTL_L: off */
7136                 case 0x2:
7137                 case 0x6:
7138                         break;
7139                 }
7140         }
7141
7142         /*
7143          * Clear any set TERM_CTL_H and TERM_CTL_L bits.
7144          */
7145         scsi_cfg1 &= ~TERM_CTL;
7146
7147         /*
7148          * Invert the TERM_CTL_H and TERM_CTL_L bits and then
7149          * set 'scsi_cfg1'. The TERM_POL bit does not need to be
7150          * referenced, because the hardware internally inverts
7151          * the Termination High and Low bits if TERM_POL is set.
7152          */
7153         scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
7154
7155         /*
7156          * Set SCSI_CFG1 Microcode Default Value
7157          *
7158          * Set filter value and possibly modified termination control
7159          * bits in the Microcode SCSI_CFG1 Register Value.
7160          *
7161          * The microcode will set the SCSI_CFG1 register using this value
7162          * after it is started below.
7163          */
7164         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
7165                          FLTR_DISABLE | scsi_cfg1);
7166
7167         /*
7168          * Set MEM_CFG Microcode Default Value
7169          *
7170          * The microcode will set the MEM_CFG register using this value
7171          * after it is started below.
7172          *
7173          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7174          * are defined.
7175          *
7176          * ASC-3550 has 8KB internal memory.
7177          */
7178         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7179                          BIOS_EN | RAM_SZ_8KB);
7180
7181         /*
7182          * Set SEL_MASK Microcode Default Value
7183          *
7184          * The microcode will set the SEL_MASK register using this value
7185          * after it is started below.
7186          */
7187         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7188                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7189
7190         AdvBuildCarrierFreelist(asc_dvc);
7191
7192         /*
7193          * Set-up the Host->RISC Initiator Command Queue (ICQ).
7194          */
7195
7196         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7197                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7198                 return ADV_ERROR;
7199         }
7200         asc_dvc->carr_freelist = (ADV_CARR_T *)
7201             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7202
7203         /*
7204          * The first command issued will be placed in the stopper carrier.
7205          */
7206         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7207
7208         /*
7209          * Set RISC ICQ physical address start value.
7210          */
7211         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7212
7213         /*
7214          * Set-up the RISC->Host Initiator Response Queue (IRQ).
7215          */
7216         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7217                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7218                 return ADV_ERROR;
7219         }
7220         asc_dvc->carr_freelist = (ADV_CARR_T *)
7221             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7222
7223         /*
7224          * The first command completed by the RISC will be placed in
7225          * the stopper.
7226          *
7227          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7228          * completed the RISC will set the ASC_RQ_STOPPER bit.
7229          */
7230         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7231
7232         /*
7233          * Set RISC IRQ physical address start value.
7234          */
7235         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7236         asc_dvc->carr_pending_cnt = 0;
7237
7238         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7239                              (ADV_INTR_ENABLE_HOST_INTR |
7240                               ADV_INTR_ENABLE_GLOBAL_INTR));
7241
7242         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7243         AdvWriteWordRegister(iop_base, IOPW_PC, word);
7244
7245         /* finally, finally, gentlemen, start your engine */
7246         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7247
7248         /*
7249          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7250          * Resets should be performed. The RISC has to be running
7251          * to issue a SCSI Bus Reset.
7252          */
7253         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7254                 /*
7255                  * If the BIOS Signature is present in memory, restore the
7256                  * BIOS Handshake Configuration Table and do not perform
7257                  * a SCSI Bus Reset.
7258                  */
7259                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7260                     0x55AA) {
7261                         /*
7262                          * Restore per TID negotiated values.
7263                          */
7264                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7265                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7266                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7267                                          tagqng_able);
7268                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7269                                 AdvWriteByteLram(iop_base,
7270                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
7271                                                  max_cmd[tid]);
7272                         }
7273                 } else {
7274                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7275                                 warn_code = ASC_WARN_BUSRESET_ERROR;
7276                         }
7277                 }
7278         }
7279
7280         return warn_code;
7281 }
7282
7283 /*
7284  * Initialize the ASC-38C0800.
7285  *
7286  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7287  *
7288  * For a non-fatal error return a warning code. If there are no warnings
7289  * then 0 is returned.
7290  *
7291  * Needed after initialization for error recovery.
7292  */
7293 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7294 {
7295         AdvPortAddr iop_base;
7296         ushort warn_code;
7297         int begin_addr;
7298         int end_addr;
7299         ushort code_sum;
7300         int word;
7301         int i;
7302         ushort scsi_cfg1;
7303         uchar byte;
7304         uchar tid;
7305         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
7306         ushort wdtr_able, sdtr_able, tagqng_able;
7307         uchar max_cmd[ADV_MAX_TID + 1];
7308
7309         /* If there is already an error, don't continue. */
7310         if (asc_dvc->err_code != 0)
7311                 return ADV_ERROR;
7312
7313         /*
7314          * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7315          */
7316         if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7317                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7318                 return ADV_ERROR;
7319         }
7320
7321         warn_code = 0;
7322         iop_base = asc_dvc->iop_base;
7323
7324         /*
7325          * Save the RISC memory BIOS region before writing the microcode.
7326          * The BIOS may already be loaded and using its RISC LRAM region
7327          * so its region must be saved and restored.
7328          *
7329          * Note: This code makes the assumption, which is currently true,
7330          * that a chip reset does not clear RISC LRAM.
7331          */
7332         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7333                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7334                                 bios_mem[i]);
7335         }
7336
7337         /*
7338          * Save current per TID negotiated values.
7339          */
7340         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7341         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7342         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7343         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7344                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7345                                 max_cmd[tid]);
7346         }
7347
7348         /*
7349          * RAM BIST (RAM Built-In Self Test)
7350          *
7351          * Address : I/O base + offset 0x38h register (byte).
7352          * Function: Bit 7-6(RW) : RAM mode
7353          *                          Normal Mode   : 0x00
7354          *                          Pre-test Mode : 0x40
7355          *                          RAM Test Mode : 0x80
7356          *           Bit 5       : unused
7357          *           Bit 4(RO)   : Done bit
7358          *           Bit 3-0(RO) : Status
7359          *                          Host Error    : 0x08
7360          *                          Int_RAM Error : 0x04
7361          *                          RISC Error    : 0x02
7362          *                          SCSI Error    : 0x01
7363          *                          No Error      : 0x00
7364          *
7365          * Note: RAM BIST code should be put right here, before loading the
7366          * microcode and after saving the RISC memory BIOS region.
7367          */
7368
7369         /*
7370          * LRAM Pre-test
7371          *
7372          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7373          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7374          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7375          * to NORMAL_MODE, return an error too.
7376          */
7377         for (i = 0; i < 2; i++) {
7378                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7379                 mdelay(10);     /* Wait for 10ms before reading back. */
7380                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7381                 if ((byte & RAM_TEST_DONE) == 0
7382                     || (byte & 0x0F) != PRE_TEST_VALUE) {
7383                         asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7384                         return ADV_ERROR;
7385                 }
7386
7387                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7388                 mdelay(10);     /* Wait for 10ms before reading back. */
7389                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7390                     != NORMAL_VALUE) {
7391                         asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7392                         return ADV_ERROR;
7393                 }
7394         }
7395
7396         /*
7397          * LRAM Test - It takes about 1.5 ms to run through the test.
7398          *
7399          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7400          * If Done bit not set or Status not 0, save register byte, set the
7401          * err_code, and return an error.
7402          */
7403         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7404         mdelay(10);     /* Wait for 10ms before checking status. */
7405
7406         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7407         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7408                 /* Get here if Done bit not set or Status not 0. */
7409                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
7410                 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7411                 return ADV_ERROR;
7412         }
7413
7414         /* We need to reset back to normal mode after LRAM test passes. */
7415         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7416
7417         asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
7418                                  _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
7419                                  _adv_asc38C0800_chksum);
7420         if (asc_dvc->err_code)
7421                 return ADV_ERROR;
7422
7423         /*
7424          * Restore the RISC memory BIOS region.
7425          */
7426         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7427                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7428                                  bios_mem[i]);
7429         }
7430
7431         /*
7432          * Calculate and write the microcode code checksum to the microcode
7433          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7434          */
7435         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7436         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7437         code_sum = 0;
7438         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7439         for (word = begin_addr; word < end_addr; word += 2) {
7440                 code_sum += AdvReadWordAutoIncLram(iop_base);
7441         }
7442         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7443
7444         /*
7445          * Read microcode version and date.
7446          */
7447         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7448                         asc_dvc->cfg->mcode_date);
7449         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7450                         asc_dvc->cfg->mcode_version);
7451
7452         /*
7453          * Set the chip type to indicate the ASC38C0800.
7454          */
7455         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7456
7457         /*
7458          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7459          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7460          * cable detection and then we are able to read C_DET[3:0].
7461          *
7462          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7463          * Microcode Default Value' section below.
7464          */
7465         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7466         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7467                              scsi_cfg1 | DIS_TERM_DRV);
7468
7469         /*
7470          * If the PCI Configuration Command Register "Parity Error Response
7471          * Control" Bit was clear (0), then set the microcode variable
7472          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7473          * to ignore DMA parity errors.
7474          */
7475         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7476                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7477                 word |= CONTROL_FLAG_IGNORE_PERR;
7478                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7479         }
7480
7481         /*
7482          * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7483          * bits for the default FIFO threshold.
7484          *
7485          * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7486          *
7487          * For DMA Errata #4 set the BC_THRESH_ENB bit.
7488          */
7489         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7490                              BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7491                              READ_CMD_MRM);
7492
7493         /*
7494          * Microcode operating variables for WDTR, SDTR, and command tag
7495          * queuing will be set in slave_configure() based on what a
7496          * device reports it is capable of in Inquiry byte 7.
7497          *
7498          * If SCSI Bus Resets have been disabled, then directly set
7499          * SDTR and WDTR from the EEPROM configuration. This will allow
7500          * the BIOS and warm boot to work without a SCSI bus hang on
7501          * the Inquiry caused by host and target mismatched DTR values.
7502          * Without the SCSI Bus Reset, before an Inquiry a device can't
7503          * be assumed to be in Asynchronous, Narrow mode.
7504          */
7505         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7506                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7507                                  asc_dvc->wdtr_able);
7508                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7509                                  asc_dvc->sdtr_able);
7510         }
7511
7512         /*
7513          * Set microcode operating variables for DISC and SDTR_SPEED1,
7514          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7515          * configuration values.
7516          *
7517          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7518          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7519          * without determining here whether the device supports SDTR.
7520          */
7521         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7522                          asc_dvc->cfg->disc_enable);
7523         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7524         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7525         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7526         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7527
7528         /*
7529          * Set SCSI_CFG0 Microcode Default Value.
7530          *
7531          * The microcode will set the SCSI_CFG0 register using this value
7532          * after it is started below.
7533          */
7534         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7535                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7536                          asc_dvc->chip_scsi_id);
7537
7538         /*
7539          * Determine SCSI_CFG1 Microcode Default Value.
7540          *
7541          * The microcode will set the SCSI_CFG1 register using this value
7542          * after it is started below.
7543          */
7544
7545         /* Read current SCSI_CFG1 Register value. */
7546         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7547
7548         /*
7549          * If the internal narrow cable is reversed all of the SCSI_CTRL
7550          * register signals will be set. Check for and return an error if
7551          * this condition is found.
7552          */
7553         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7554                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7555                 return ADV_ERROR;
7556         }
7557
7558         /*
7559          * All kind of combinations of devices attached to one of four
7560          * connectors are acceptable except HVD device attached. For example,
7561          * LVD device can be attached to SE connector while SE device attached
7562          * to LVD connector.  If LVD device attached to SE connector, it only
7563          * runs up to Ultra speed.
7564          *
7565          * If an HVD device is attached to one of LVD connectors, return an
7566          * error.  However, there is no way to detect HVD device attached to
7567          * SE connectors.
7568          */
7569         if (scsi_cfg1 & HVD) {
7570                 asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7571                 return ADV_ERROR;
7572         }
7573
7574         /*
7575          * If either SE or LVD automatic termination control is enabled, then
7576          * set the termination value based on a table listed in a_condor.h.
7577          *
7578          * If manual termination was specified with an EEPROM setting then
7579          * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
7580          * to be 'ored' into SCSI_CFG1.
7581          */
7582         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7583                 /* SE automatic termination control is enabled. */
7584                 switch (scsi_cfg1 & C_DET_SE) {
7585                         /* TERM_SE_HI: on, TERM_SE_LO: on */
7586                 case 0x1:
7587                 case 0x2:
7588                 case 0x3:
7589                         asc_dvc->cfg->termination |= TERM_SE;
7590                         break;
7591
7592                         /* TERM_SE_HI: on, TERM_SE_LO: off */
7593                 case 0x0:
7594                         asc_dvc->cfg->termination |= TERM_SE_HI;
7595                         break;
7596                 }
7597         }
7598
7599         if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
7600                 /* LVD automatic termination control is enabled. */
7601                 switch (scsi_cfg1 & C_DET_LVD) {
7602                         /* TERM_LVD_HI: on, TERM_LVD_LO: on */
7603                 case 0x4:
7604                 case 0x8:
7605                 case 0xC:
7606                         asc_dvc->cfg->termination |= TERM_LVD;
7607                         break;
7608
7609                         /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7610                 case 0x0:
7611                         break;
7612                 }
7613         }
7614
7615         /*
7616          * Clear any set TERM_SE and TERM_LVD bits.
7617          */
7618         scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7619
7620         /*
7621          * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7622          */
7623         scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7624
7625         /*
7626          * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
7627          * bits and set possibly modified termination control bits in the
7628          * Microcode SCSI_CFG1 Register Value.
7629          */
7630         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7631
7632         /*
7633          * Set SCSI_CFG1 Microcode Default Value
7634          *
7635          * Set possibly modified termination control and reset DIS_TERM_DRV
7636          * bits in the Microcode SCSI_CFG1 Register Value.
7637          *
7638          * The microcode will set the SCSI_CFG1 register using this value
7639          * after it is started below.
7640          */
7641         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7642
7643         /*
7644          * Set MEM_CFG Microcode Default Value
7645          *
7646          * The microcode will set the MEM_CFG register using this value
7647          * after it is started below.
7648          *
7649          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7650          * are defined.
7651          *
7652          * ASC-38C0800 has 16KB internal memory.
7653          */
7654         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7655                          BIOS_EN | RAM_SZ_16KB);
7656
7657         /*
7658          * Set SEL_MASK Microcode Default Value
7659          *
7660          * The microcode will set the SEL_MASK register using this value
7661          * after it is started below.
7662          */
7663         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7664                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7665
7666         AdvBuildCarrierFreelist(asc_dvc);
7667
7668         /*
7669          * Set-up the Host->RISC Initiator Command Queue (ICQ).
7670          */
7671
7672         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7673                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7674                 return ADV_ERROR;
7675         }
7676         asc_dvc->carr_freelist = (ADV_CARR_T *)
7677             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7678
7679         /*
7680          * The first command issued will be placed in the stopper carrier.
7681          */
7682         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7683
7684         /*
7685          * Set RISC ICQ physical address start value.
7686          * carr_pa is LE, must be native before write
7687          */
7688         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7689
7690         /*
7691          * Set-up the RISC->Host Initiator Response Queue (IRQ).
7692          */
7693         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7694                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7695                 return ADV_ERROR;
7696         }
7697         asc_dvc->carr_freelist = (ADV_CARR_T *)
7698             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7699
7700         /*
7701          * The first command completed by the RISC will be placed in
7702          * the stopper.
7703          *
7704          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7705          * completed the RISC will set the ASC_RQ_STOPPER bit.
7706          */
7707         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7708
7709         /*
7710          * Set RISC IRQ physical address start value.
7711          *
7712          * carr_pa is LE, must be native before write *
7713          */
7714         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7715         asc_dvc->carr_pending_cnt = 0;
7716
7717         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7718                              (ADV_INTR_ENABLE_HOST_INTR |
7719                               ADV_INTR_ENABLE_GLOBAL_INTR));
7720
7721         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7722         AdvWriteWordRegister(iop_base, IOPW_PC, word);
7723
7724         /* finally, finally, gentlemen, start your engine */
7725         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7726
7727         /*
7728          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7729          * Resets should be performed. The RISC has to be running
7730          * to issue a SCSI Bus Reset.
7731          */
7732         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7733                 /*
7734                  * If the BIOS Signature is present in memory, restore the
7735                  * BIOS Handshake Configuration Table and do not perform
7736                  * a SCSI Bus Reset.
7737                  */
7738                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7739                     0x55AA) {
7740                         /*
7741                          * Restore per TID negotiated values.
7742                          */
7743                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7744                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7745                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7746                                          tagqng_able);
7747                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7748                                 AdvWriteByteLram(iop_base,
7749                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
7750                                                  max_cmd[tid]);
7751                         }
7752                 } else {
7753                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7754                                 warn_code = ASC_WARN_BUSRESET_ERROR;
7755                         }
7756                 }
7757         }
7758
7759         return warn_code;
7760 }
7761
7762 /*
7763  * Initialize the ASC-38C1600.
7764  *
7765  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7766  *
7767  * For a non-fatal error return a warning code. If there are no warnings
7768  * then 0 is returned.
7769  *
7770  * Needed after initialization for error recovery.
7771  */
7772 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7773 {
7774         AdvPortAddr iop_base;
7775         ushort warn_code;
7776         int begin_addr;
7777         int end_addr;
7778         ushort code_sum;
7779         long word;
7780         int i;
7781         ushort scsi_cfg1;
7782         uchar byte;
7783         uchar tid;
7784         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
7785         ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
7786         uchar max_cmd[ASC_MAX_TID + 1];
7787
7788         /* If there is already an error, don't continue. */
7789         if (asc_dvc->err_code != 0) {
7790                 return ADV_ERROR;
7791         }
7792
7793         /*
7794          * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7795          */
7796         if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7797                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7798                 return ADV_ERROR;
7799         }
7800
7801         warn_code = 0;
7802         iop_base = asc_dvc->iop_base;
7803
7804         /*
7805          * Save the RISC memory BIOS region before writing the microcode.
7806          * The BIOS may already be loaded and using its RISC LRAM region
7807          * so its region must be saved and restored.
7808          *
7809          * Note: This code makes the assumption, which is currently true,
7810          * that a chip reset does not clear RISC LRAM.
7811          */
7812         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7813                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7814                                 bios_mem[i]);
7815         }
7816
7817         /*
7818          * Save current per TID negotiated values.
7819          */
7820         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7821         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7822         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
7823         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7824         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7825                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7826                                 max_cmd[tid]);
7827         }
7828
7829         /*
7830          * RAM BIST (Built-In Self Test)
7831          *
7832          * Address : I/O base + offset 0x38h register (byte).
7833          * Function: Bit 7-6(RW) : RAM mode
7834          *                          Normal Mode   : 0x00
7835          *                          Pre-test Mode : 0x40
7836          *                          RAM Test Mode : 0x80
7837          *           Bit 5       : unused
7838          *           Bit 4(RO)   : Done bit
7839          *           Bit 3-0(RO) : Status
7840          *                          Host Error    : 0x08
7841          *                          Int_RAM Error : 0x04
7842          *                          RISC Error    : 0x02
7843          *                          SCSI Error    : 0x01
7844          *                          No Error      : 0x00
7845          *
7846          * Note: RAM BIST code should be put right here, before loading the
7847          * microcode and after saving the RISC memory BIOS region.
7848          */
7849
7850         /*
7851          * LRAM Pre-test
7852          *
7853          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7854          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7855          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7856          * to NORMAL_MODE, return an error too.
7857          */
7858         for (i = 0; i < 2; i++) {
7859                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7860                 mdelay(10);     /* Wait for 10ms before reading back. */
7861                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7862                 if ((byte & RAM_TEST_DONE) == 0
7863                     || (byte & 0x0F) != PRE_TEST_VALUE) {
7864                         asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7865                         return ADV_ERROR;
7866                 }
7867
7868                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7869                 mdelay(10);     /* Wait for 10ms before reading back. */
7870                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7871                     != NORMAL_VALUE) {
7872                         asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7873                         return ADV_ERROR;
7874                 }
7875         }
7876
7877         /*
7878          * LRAM Test - It takes about 1.5 ms to run through the test.
7879          *
7880          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7881          * If Done bit not set or Status not 0, save register byte, set the
7882          * err_code, and return an error.
7883          */
7884         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7885         mdelay(10);     /* Wait for 10ms before checking status. */
7886
7887         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7888         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7889                 /* Get here if Done bit not set or Status not 0. */
7890                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
7891                 asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7892                 return ADV_ERROR;
7893         }
7894
7895         /* We need to reset back to normal mode after LRAM test passes. */
7896         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7897
7898         asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
7899                                  _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
7900                                  _adv_asc38C1600_chksum);
7901         if (asc_dvc->err_code)
7902                 return ADV_ERROR;
7903
7904         /*
7905          * Restore the RISC memory BIOS region.
7906          */
7907         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7908                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7909                                  bios_mem[i]);
7910         }
7911
7912         /*
7913          * Calculate and write the microcode code checksum to the microcode
7914          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7915          */
7916         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7917         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7918         code_sum = 0;
7919         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7920         for (word = begin_addr; word < end_addr; word += 2) {
7921                 code_sum += AdvReadWordAutoIncLram(iop_base);
7922         }
7923         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7924
7925         /*
7926          * Read microcode version and date.
7927          */
7928         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7929                         asc_dvc->cfg->mcode_date);
7930         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7931                         asc_dvc->cfg->mcode_version);
7932
7933         /*
7934          * Set the chip type to indicate the ASC38C1600.
7935          */
7936         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7937
7938         /*
7939          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7940          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7941          * cable detection and then we are able to read C_DET[3:0].
7942          *
7943          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7944          * Microcode Default Value' section below.
7945          */
7946         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7947         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7948                              scsi_cfg1 | DIS_TERM_DRV);
7949
7950         /*
7951          * If the PCI Configuration Command Register "Parity Error Response
7952          * Control" Bit was clear (0), then set the microcode variable
7953          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7954          * to ignore DMA parity errors.
7955          */
7956         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7957                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7958                 word |= CONTROL_FLAG_IGNORE_PERR;
7959                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7960         }
7961
7962         /*
7963          * If the BIOS control flag AIPP (Asynchronous Information
7964          * Phase Protection) disable bit is not set, then set the firmware
7965          * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
7966          * AIPP checking and encoding.
7967          */
7968         if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
7969                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7970                 word |= CONTROL_FLAG_ENABLE_AIPP;
7971                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7972         }
7973
7974         /*
7975          * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7976          * and START_CTL_TH [3:2].
7977          */
7978         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7979                              FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7980
7981         /*
7982          * Microcode operating variables for WDTR, SDTR, and command tag
7983          * queuing will be set in slave_configure() based on what a
7984          * device reports it is capable of in Inquiry byte 7.
7985          *
7986          * If SCSI Bus Resets have been disabled, then directly set
7987          * SDTR and WDTR from the EEPROM configuration. This will allow
7988          * the BIOS and warm boot to work without a SCSI bus hang on
7989          * the Inquiry caused by host and target mismatched DTR values.
7990          * Without the SCSI Bus Reset, before an Inquiry a device can't
7991          * be assumed to be in Asynchronous, Narrow mode.
7992          */
7993         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7994                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7995                                  asc_dvc->wdtr_able);
7996                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7997                                  asc_dvc->sdtr_able);
7998         }
7999
8000         /*
8001          * Set microcode operating variables for DISC and SDTR_SPEED1,
8002          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
8003          * configuration values.
8004          *
8005          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
8006          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
8007          * without determining here whether the device supports SDTR.
8008          */
8009         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
8010                          asc_dvc->cfg->disc_enable);
8011         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
8012         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
8013         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
8014         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
8015
8016         /*
8017          * Set SCSI_CFG0 Microcode Default Value.
8018          *
8019          * The microcode will set the SCSI_CFG0 register using this value
8020          * after it is started below.
8021          */
8022         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
8023                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
8024                          asc_dvc->chip_scsi_id);
8025
8026         /*
8027          * Calculate SCSI_CFG1 Microcode Default Value.
8028          *
8029          * The microcode will set the SCSI_CFG1 register using this value
8030          * after it is started below.
8031          *
8032          * Each ASC-38C1600 function has only two cable detect bits.
8033          * The bus mode override bits are in IOPB_SOFT_OVER_WR.
8034          */
8035         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
8036
8037         /*
8038          * If the cable is reversed all of the SCSI_CTRL register signals
8039          * will be set. Check for and return an error if this condition is
8040          * found.
8041          */
8042         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
8043                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
8044                 return ADV_ERROR;
8045         }
8046
8047         /*
8048          * Each ASC-38C1600 function has two connectors. Only an HVD device
8049          * can not be connected to either connector. An LVD device or SE device
8050          * may be connected to either connecor. If an SE device is connected,
8051          * then at most Ultra speed (20 Mhz) can be used on both connectors.
8052          *
8053          * If an HVD device is attached, return an error.
8054          */
8055         if (scsi_cfg1 & HVD) {
8056                 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
8057                 return ADV_ERROR;
8058         }
8059
8060         /*
8061          * Each function in the ASC-38C1600 uses only the SE cable detect and
8062          * termination because there are two connectors for each function. Each
8063          * function may use either LVD or SE mode. Corresponding the SE automatic
8064          * termination control EEPROM bits are used for each function. Each
8065          * function has its own EEPROM. If SE automatic control is enabled for
8066          * the function, then set the termination value based on a table listed
8067          * in a_condor.h.
8068          *
8069          * If manual termination is specified in the EEPROM for the function,
8070          * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
8071          * ready to be 'ored' into SCSI_CFG1.
8072          */
8073         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
8074                 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
8075                 /* SE automatic termination control is enabled. */
8076                 switch (scsi_cfg1 & C_DET_SE) {
8077                         /* TERM_SE_HI: on, TERM_SE_LO: on */
8078                 case 0x1:
8079                 case 0x2:
8080                 case 0x3:
8081                         asc_dvc->cfg->termination |= TERM_SE;
8082                         break;
8083
8084                 case 0x0:
8085                         if (PCI_FUNC(pdev->devfn) == 0) {
8086                                 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
8087                         } else {
8088                                 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
8089                                 asc_dvc->cfg->termination |= TERM_SE_HI;
8090                         }
8091                         break;
8092                 }
8093         }
8094
8095         /*
8096          * Clear any set TERM_SE bits.
8097          */
8098         scsi_cfg1 &= ~TERM_SE;
8099
8100         /*
8101          * Invert the TERM_SE bits and then set 'scsi_cfg1'.
8102          */
8103         scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
8104
8105         /*
8106          * Clear Big Endian and Terminator Polarity bits and set possibly
8107          * modified termination control bits in the Microcode SCSI_CFG1
8108          * Register Value.
8109          *
8110          * Big Endian bit is not used even on big endian machines.
8111          */
8112         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
8113
8114         /*
8115          * Set SCSI_CFG1 Microcode Default Value
8116          *
8117          * Set possibly modified termination control bits in the Microcode
8118          * SCSI_CFG1 Register Value.
8119          *
8120          * The microcode will set the SCSI_CFG1 register using this value
8121          * after it is started below.
8122          */
8123         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
8124
8125         /*
8126          * Set MEM_CFG Microcode Default Value
8127          *
8128          * The microcode will set the MEM_CFG register using this value
8129          * after it is started below.
8130          *
8131          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
8132          * are defined.
8133          *
8134          * ASC-38C1600 has 32KB internal memory.
8135          *
8136          * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
8137          * out a special 16K Adv Library and Microcode version. After the issue
8138          * resolved, we should turn back to the 32K support. Both a_condor.h and
8139          * mcode.sas files also need to be updated.
8140          *
8141          * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8142          *  BIOS_EN | RAM_SZ_32KB);
8143          */
8144         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
8145                          BIOS_EN | RAM_SZ_16KB);
8146
8147         /*
8148          * Set SEL_MASK Microcode Default Value
8149          *
8150          * The microcode will set the SEL_MASK register using this value
8151          * after it is started below.
8152          */
8153         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
8154                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
8155
8156         AdvBuildCarrierFreelist(asc_dvc);
8157
8158         /*
8159          * Set-up the Host->RISC Initiator Command Queue (ICQ).
8160          */
8161         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
8162                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8163                 return ADV_ERROR;
8164         }
8165         asc_dvc->carr_freelist = (ADV_CARR_T *)
8166             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
8167
8168         /*
8169          * The first command issued will be placed in the stopper carrier.
8170          */
8171         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8172
8173         /*
8174          * Set RISC ICQ physical address start value. Initialize the
8175          * COMMA register to the same value otherwise the RISC will
8176          * prematurely detect a command is available.
8177          */
8178         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
8179         AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
8180                               le32_to_cpu(asc_dvc->icq_sp->carr_pa));
8181
8182         /*
8183          * Set-up the RISC->Host Initiator Response Queue (IRQ).
8184          */
8185         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
8186                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
8187                 return ADV_ERROR;
8188         }
8189         asc_dvc->carr_freelist = (ADV_CARR_T *)
8190             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
8191
8192         /*
8193          * The first command completed by the RISC will be placed in
8194          * the stopper.
8195          *
8196          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
8197          * completed the RISC will set the ASC_RQ_STOPPER bit.
8198          */
8199         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
8200
8201         /*
8202          * Set RISC IRQ physical address start value.
8203          */
8204         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
8205         asc_dvc->carr_pending_cnt = 0;
8206
8207         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
8208                              (ADV_INTR_ENABLE_HOST_INTR |
8209                               ADV_INTR_ENABLE_GLOBAL_INTR));
8210         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
8211         AdvWriteWordRegister(iop_base, IOPW_PC, word);
8212
8213         /* finally, finally, gentlemen, start your engine */
8214         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
8215
8216         /*
8217          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
8218          * Resets should be performed. The RISC has to be running
8219          * to issue a SCSI Bus Reset.
8220          */
8221         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
8222                 /*
8223                  * If the BIOS Signature is present in memory, restore the
8224                  * per TID microcode operating variables.
8225                  */
8226                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8227                     0x55AA) {
8228                         /*
8229                          * Restore per TID negotiated values.
8230                          */
8231                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8232                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8233                         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8234                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
8235                                          tagqng_able);
8236                         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
8237                                 AdvWriteByteLram(iop_base,
8238                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
8239                                                  max_cmd[tid]);
8240                         }
8241                 } else {
8242                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8243                                 warn_code = ASC_WARN_BUSRESET_ERROR;
8244                         }
8245                 }
8246         }
8247
8248         return warn_code;
8249 }
8250
8251 /*
8252  * Reset chip and SCSI Bus.
8253  *
8254  * Return Value:
8255  *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
8256  *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
8257  */
8258 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8259 {
8260         int status;
8261         ushort wdtr_able, sdtr_able, tagqng_able;
8262         ushort ppr_able = 0;
8263         uchar tid, max_cmd[ADV_MAX_TID + 1];
8264         AdvPortAddr iop_base;
8265         ushort bios_sig;
8266
8267         iop_base = asc_dvc->iop_base;
8268
8269         /*
8270          * Save current per TID negotiated values.
8271          */
8272         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8273         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8274         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8275                 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8276         }
8277         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8278         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8279                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8280                                 max_cmd[tid]);
8281         }
8282
8283         /*
8284          * Force the AdvInitAsc3550/38C0800Driver() function to
8285          * perform a SCSI Bus Reset by clearing the BIOS signature word.
8286          * The initialization functions assumes a SCSI Bus Reset is not
8287          * needed if the BIOS signature word is present.
8288          */
8289         AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8290         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8291
8292         /*
8293          * Stop chip and reset it.
8294          */
8295         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
8296         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
8297         mdelay(100);
8298         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
8299                              ADV_CTRL_REG_CMD_WR_IO_REG);
8300
8301         /*
8302          * Reset Adv Library error code, if any, and try
8303          * re-initializing the chip.
8304          */
8305         asc_dvc->err_code = 0;
8306         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8307                 status = AdvInitAsc38C1600Driver(asc_dvc);
8308         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8309                 status = AdvInitAsc38C0800Driver(asc_dvc);
8310         } else {
8311                 status = AdvInitAsc3550Driver(asc_dvc);
8312         }
8313
8314         /* Translate initialization return value to status value. */
8315         if (status == 0) {
8316                 status = ADV_TRUE;
8317         } else {
8318                 status = ADV_FALSE;
8319         }
8320
8321         /*
8322          * Restore the BIOS signature word.
8323          */
8324         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8325
8326         /*
8327          * Restore per TID negotiated values.
8328          */
8329         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8330         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8331         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8332                 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8333         }
8334         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8335         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8336                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8337                                  max_cmd[tid]);
8338         }
8339
8340         return status;
8341 }
8342
8343 /*
8344  * adv_async_callback() - Adv Library asynchronous event callback function.
8345  */
8346 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8347 {
8348         switch (code) {
8349         case ADV_ASYNC_SCSI_BUS_RESET_DET:
8350                 /*
8351                  * The firmware detected a SCSI Bus reset.
8352                  */
8353                 ASC_DBG(0,
8354                         "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
8355                 break;
8356
8357         case ADV_ASYNC_RDMA_FAILURE:
8358                 /*
8359                  * Handle RDMA failure by resetting the SCSI Bus and
8360                  * possibly the chip if it is unresponsive. Log the error
8361                  * with a unique code.
8362                  */
8363                 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
8364                 AdvResetChipAndSB(adv_dvc_varp);
8365                 break;
8366
8367         case ADV_HOST_SCSI_BUS_RESET:
8368                 /*
8369                  * Host generated SCSI bus reset occurred.
8370                  */
8371                 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
8372                 break;
8373
8374         default:
8375                 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
8376                 break;
8377         }
8378 }
8379
8380 /*
8381  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8382  *
8383  * Callback function for the Wide SCSI Adv Library.
8384  */
8385 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8386 {
8387         asc_board_t *boardp;
8388         adv_req_t *reqp;
8389         adv_sgblk_t *sgblkp;
8390         struct scsi_cmnd *scp;
8391         struct Scsi_Host *shost;
8392         ADV_DCNT resid_cnt;
8393
8394         ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
8395                  (ulong)adv_dvc_varp, (ulong)scsiqp);
8396         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8397
8398         /*
8399          * Get the adv_req_t structure for the command that has been
8400          * completed. The adv_req_t structure actually contains the
8401          * completed ADV_SCSI_REQ_Q structure.
8402          */
8403         reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
8404         ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
8405         if (reqp == NULL) {
8406                 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8407                 return;
8408         }
8409
8410         /*
8411          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8412          * command that has been completed.
8413          *
8414          * Note: The adv_req_t request structure and adv_sgblk_t structure,
8415          * if any, are dropped, because a board structure pointer can not be
8416          * determined.
8417          */
8418         scp = reqp->cmndp;
8419         ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
8420         if (scp == NULL) {
8421                 ASC_PRINT
8422                     ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8423                 return;
8424         }
8425         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8426
8427         shost = scp->device->host;
8428         ASC_STATS(shost, callback);
8429         ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
8430
8431         boardp = ASC_BOARDP(shost);
8432         BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8433
8434         /*
8435          * 'done_status' contains the command's ending status.
8436          */
8437         switch (scsiqp->done_status) {
8438         case QD_NO_ERROR:
8439                 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
8440                 scp->result = 0;
8441
8442                 /*
8443                  * Check for an underrun condition.
8444                  *
8445                  * If there was no error and an underrun condition, then
8446                  * then return the number of underrun bytes.
8447                  */
8448                 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8449                 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
8450                     resid_cnt <= scp->request_bufflen) {
8451                         ASC_DBG1(1,
8452                                  "adv_isr_callback: underrun condition %lu bytes\n",
8453                                  (ulong)resid_cnt);
8454                         scp->resid = resid_cnt;
8455                 }
8456                 break;
8457
8458         case QD_WITH_ERROR:
8459                 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
8460                 switch (scsiqp->host_status) {
8461                 case QHSTA_NO_ERROR:
8462                         if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
8463                                 ASC_DBG(2,
8464                                         "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
8465                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8466                                                   sizeof(scp->sense_buffer));
8467                                 /*
8468                                  * Note: The 'status_byte()' macro used by
8469                                  * target drivers defined in scsi.h shifts the
8470                                  * status byte returned by host drivers right
8471                                  * by 1 bit.  This is why target drivers also
8472                                  * use right shifted status byte definitions.
8473                                  * For instance target drivers use
8474                                  * CHECK_CONDITION, defined to 0x1, instead of
8475                                  * the SCSI defined check condition value of
8476                                  * 0x2. Host drivers are supposed to return
8477                                  * the status byte as it is defined by SCSI.
8478                                  */
8479                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8480                                     STATUS_BYTE(scsiqp->scsi_status);
8481                         } else {
8482                                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
8483                         }
8484                         break;
8485
8486                 default:
8487                         /* Some other QHSTA error occurred. */
8488                         ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
8489                                  scsiqp->host_status);
8490                         scp->result = HOST_BYTE(DID_BAD_TARGET);
8491                         break;
8492                 }
8493                 break;
8494
8495         case QD_ABORTED_BY_HOST:
8496                 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
8497                 scp->result =
8498                     HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8499                 break;
8500
8501         default:
8502                 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
8503                          scsiqp->done_status);
8504                 scp->result =
8505                     HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8506                 break;
8507         }
8508
8509         /*
8510          * If the 'init_tidmask' bit isn't already set for the target and the
8511          * current request finished normally, then set the bit for the target
8512          * to indicate that a device is present.
8513          */
8514         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
8515             scsiqp->done_status == QD_NO_ERROR &&
8516             scsiqp->host_status == QHSTA_NO_ERROR) {
8517                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
8518         }
8519
8520         asc_scsi_done(scp);
8521
8522         /*
8523          * Free all 'adv_sgblk_t' structures allocated for the request.
8524          */
8525         while ((sgblkp = reqp->sgblkp) != NULL) {
8526                 /* Remove 'sgblkp' from the request list. */
8527                 reqp->sgblkp = sgblkp->next_sgblkp;
8528
8529                 /* Add 'sgblkp' to the board free list. */
8530                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
8531                 boardp->adv_sgblkp = sgblkp;
8532         }
8533
8534         /*
8535          * Free the adv_req_t structure used with the command by adding
8536          * it back to the board free list.
8537          */
8538         reqp->next_reqp = boardp->adv_reqp;
8539         boardp->adv_reqp = reqp;
8540
8541         ASC_DBG(1, "adv_isr_callback: done\n");
8542
8543         return;
8544 }
8545
8546 /*
8547  * Adv Library Interrupt Service Routine
8548  *
8549  *  This function is called by a driver's interrupt service routine.
8550  *  The function disables and re-enables interrupts.
8551  *
8552  *  When a microcode idle command is completed, the ADV_DVC_VAR
8553  *  'idle_cmd_done' field is set to ADV_TRUE.
8554  *
8555  *  Note: AdvISR() can be called when interrupts are disabled or even
8556  *  when there is no hardware interrupt condition present. It will
8557  *  always check for completed idle commands and microcode requests.
8558  *  This is an important feature that shouldn't be changed because it
8559  *  allows commands to be completed from polling mode loops.
8560  *
8561  * Return:
8562  *   ADV_TRUE(1) - interrupt was pending
8563  *   ADV_FALSE(0) - no interrupt was pending
8564  */
8565 static int AdvISR(ADV_DVC_VAR *asc_dvc)
8566 {
8567         AdvPortAddr iop_base;
8568         uchar int_stat;
8569         ushort target_bit;
8570         ADV_CARR_T *free_carrp;
8571         ADV_VADDR irq_next_vpa;
8572         ADV_SCSI_REQ_Q *scsiq;
8573
8574         iop_base = asc_dvc->iop_base;
8575
8576         /* Reading the register clears the interrupt. */
8577         int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8578
8579         if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8580                          ADV_INTR_STATUS_INTRC)) == 0) {
8581                 return ADV_FALSE;
8582         }
8583
8584         /*
8585          * Notify the driver of an asynchronous microcode condition by
8586          * calling the adv_async_callback function. The function
8587          * is passed the microcode ASC_MC_INTRB_CODE byte value.
8588          */
8589         if (int_stat & ADV_INTR_STATUS_INTRB) {
8590                 uchar intrb_code;
8591
8592                 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8593
8594                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8595                     asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8596                         if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
8597                             asc_dvc->carr_pending_cnt != 0) {
8598                                 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8599                                                      ADV_TICKLE_A);
8600                                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8601                                         AdvWriteByteRegister(iop_base,
8602                                                              IOPB_TICKLE,
8603                                                              ADV_TICKLE_NOP);
8604                                 }
8605                         }
8606                 }
8607
8608                 adv_async_callback(asc_dvc, intrb_code);
8609         }
8610
8611         /*
8612          * Check if the IRQ stopper carrier contains a completed request.
8613          */
8614         while (((irq_next_vpa =
8615                  le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8616                 /*
8617                  * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
8618                  * The RISC will have set 'areq_vpa' to a virtual address.
8619                  *
8620                  * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
8621                  * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
8622                  * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
8623                  * in AdvExeScsiQueue().
8624                  */
8625                 scsiq = (ADV_SCSI_REQ_Q *)
8626                     ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8627
8628                 /*
8629                  * Request finished with good status and the queue was not
8630                  * DMAed to host memory by the firmware. Set all status fields
8631                  * to indicate good status.
8632                  */
8633                 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
8634                         scsiq->done_status = QD_NO_ERROR;
8635                         scsiq->host_status = scsiq->scsi_status = 0;
8636                         scsiq->data_cnt = 0L;
8637                 }
8638
8639                 /*
8640                  * Advance the stopper pointer to the next carrier
8641                  * ignoring the lower four bits. Free the previous
8642                  * stopper carrier.
8643                  */
8644                 free_carrp = asc_dvc->irq_sp;
8645                 asc_dvc->irq_sp = (ADV_CARR_T *)
8646                     ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
8647
8648                 free_carrp->next_vpa =
8649                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
8650                 asc_dvc->carr_freelist = free_carrp;
8651                 asc_dvc->carr_pending_cnt--;
8652
8653                 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8654
8655                 /*
8656                  * Clear request microcode control flag.
8657                  */
8658                 scsiq->cntl = 0;
8659
8660                 /*
8661                  * Notify the driver of the completed request by passing
8662                  * the ADV_SCSI_REQ_Q pointer to its callback function.
8663                  */
8664                 scsiq->a_flag |= ADV_SCSIQ_DONE;
8665                 adv_isr_callback(asc_dvc, scsiq);
8666                 /*
8667                  * Note: After the driver callback function is called, 'scsiq'
8668                  * can no longer be referenced.
8669                  *
8670                  * Fall through and continue processing other completed
8671                  * requests...
8672                  */
8673         }
8674         return ADV_TRUE;
8675 }
8676
8677 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8678 {
8679         if (asc_dvc->err_code == 0) {
8680                 asc_dvc->err_code = err_code;
8681                 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8682                                  err_code);
8683         }
8684         return err_code;
8685 }
8686
8687 static void AscAckInterrupt(PortAddr iop_base)
8688 {
8689         uchar host_flag;
8690         uchar risc_flag;
8691         ushort loop;
8692
8693         loop = 0;
8694         do {
8695                 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8696                 if (loop++ > 0x7FFF) {
8697                         break;
8698                 }
8699         } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8700         host_flag =
8701             AscReadLramByte(iop_base,
8702                             ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8703         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8704                          (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8705         AscSetChipStatus(iop_base, CIW_INT_ACK);
8706         loop = 0;
8707         while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8708                 AscSetChipStatus(iop_base, CIW_INT_ACK);
8709                 if (loop++ > 3) {
8710                         break;
8711                 }
8712         }
8713         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8714         return;
8715 }
8716
8717 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8718 {
8719         uchar *period_table;
8720         int max_index;
8721         int min_index;
8722         int i;
8723
8724         period_table = asc_dvc->sdtr_period_tbl;
8725         max_index = (int)asc_dvc->max_sdtr_index;
8726         min_index = (int)asc_dvc->host_init_sdtr_index;
8727         if ((syn_time <= period_table[max_index])) {
8728                 for (i = min_index; i < (max_index - 1); i++) {
8729                         if (syn_time <= period_table[i]) {
8730                                 return (uchar)i;
8731                         }
8732                 }
8733                 return (uchar)max_index;
8734         } else {
8735                 return (uchar)(max_index + 1);
8736         }
8737 }
8738
8739 static uchar
8740 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8741 {
8742         EXT_MSG sdtr_buf;
8743         uchar sdtr_period_index;
8744         PortAddr iop_base;
8745
8746         iop_base = asc_dvc->iop_base;
8747         sdtr_buf.msg_type = EXTENDED_MESSAGE;
8748         sdtr_buf.msg_len = MS_SDTR_LEN;
8749         sdtr_buf.msg_req = EXTENDED_SDTR;
8750         sdtr_buf.xfer_period = sdtr_period;
8751         sdtr_offset &= ASC_SYN_MAX_OFFSET;
8752         sdtr_buf.req_ack_offset = sdtr_offset;
8753         sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8754         if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
8755                 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8756                                         (uchar *)&sdtr_buf,
8757                                         sizeof(EXT_MSG) >> 1);
8758                 return ((sdtr_period_index << 4) | sdtr_offset);
8759         } else {
8760                 sdtr_buf.req_ack_offset = 0;
8761                 AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8762                                         (uchar *)&sdtr_buf,
8763                                         sizeof(EXT_MSG) >> 1);
8764                 return 0;
8765         }
8766 }
8767
8768 static uchar
8769 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8770 {
8771         uchar byte;
8772         uchar sdtr_period_ix;
8773
8774         sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8775         if (sdtr_period_ix > asc_dvc->max_sdtr_index) {
8776                 return 0xFF;
8777         }
8778         byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8779         return byte;
8780 }
8781
8782 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8783 {
8784         ASC_SCSI_BIT_ID_TYPE org_id;
8785         int i;
8786         int sta = TRUE;
8787
8788         AscSetBank(iop_base, 1);
8789         org_id = AscReadChipDvcID(iop_base);
8790         for (i = 0; i <= ASC_MAX_TID; i++) {
8791                 if (org_id == (0x01 << i))
8792                         break;
8793         }
8794         org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8795         AscWriteChipDvcID(iop_base, id);
8796         if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8797                 AscSetBank(iop_base, 0);
8798                 AscSetChipSyn(iop_base, sdtr_data);
8799                 if (AscGetChipSyn(iop_base) != sdtr_data) {
8800                         sta = FALSE;
8801                 }
8802         } else {
8803                 sta = FALSE;
8804         }
8805         AscSetBank(iop_base, 1);
8806         AscWriteChipDvcID(iop_base, org_id);
8807         AscSetBank(iop_base, 0);
8808         return (sta);
8809 }
8810
8811 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8812 {
8813         AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8814         AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8815 }
8816
8817 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8818 {
8819         EXT_MSG ext_msg;
8820         EXT_MSG out_msg;
8821         ushort halt_q_addr;
8822         int sdtr_accept;
8823         ushort int_halt_code;
8824         ASC_SCSI_BIT_ID_TYPE scsi_busy;
8825         ASC_SCSI_BIT_ID_TYPE target_id;
8826         PortAddr iop_base;
8827         uchar tag_code;
8828         uchar q_status;
8829         uchar halt_qp;
8830         uchar sdtr_data;
8831         uchar target_ix;
8832         uchar q_cntl, tid_no;
8833         uchar cur_dvc_qng;
8834         uchar asyn_sdtr;
8835         uchar scsi_status;
8836         asc_board_t *boardp;
8837
8838         BUG_ON(!asc_dvc->drv_ptr);
8839         boardp = asc_dvc->drv_ptr;
8840
8841         iop_base = asc_dvc->iop_base;
8842         int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8843
8844         halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8845         halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8846         target_ix = AscReadLramByte(iop_base,
8847                                     (ushort)(halt_q_addr +
8848                                              (ushort)ASC_SCSIQ_B_TARGET_IX));
8849         q_cntl = AscReadLramByte(iop_base,
8850                             (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8851         tid_no = ASC_TIX_TO_TID(target_ix);
8852         target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8853         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8854                 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8855         } else {
8856                 asyn_sdtr = 0;
8857         }
8858         if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8859                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8860                         AscSetChipSDTR(iop_base, 0, tid_no);
8861                         boardp->sdtr_data[tid_no] = 0;
8862                 }
8863                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8864                 return (0);
8865         } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8866                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8867                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8868                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8869                 }
8870                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8871                 return (0);
8872         } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8873                 AscMemWordCopyPtrFromLram(iop_base,
8874                                           ASCV_MSGIN_BEG,
8875                                           (uchar *)&ext_msg,
8876                                           sizeof(EXT_MSG) >> 1);
8877
8878                 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8879                     ext_msg.msg_req == EXTENDED_SDTR &&
8880                     ext_msg.msg_len == MS_SDTR_LEN) {
8881                         sdtr_accept = TRUE;
8882                         if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8883
8884                                 sdtr_accept = FALSE;
8885                                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8886                         }
8887                         if ((ext_msg.xfer_period <
8888                              asc_dvc->sdtr_period_tbl[asc_dvc->
8889                                                       host_init_sdtr_index])
8890                             || (ext_msg.xfer_period >
8891                                 asc_dvc->sdtr_period_tbl[asc_dvc->
8892                                                          max_sdtr_index])) {
8893                                 sdtr_accept = FALSE;
8894                                 ext_msg.xfer_period =
8895                                     asc_dvc->sdtr_period_tbl[asc_dvc->
8896                                                              host_init_sdtr_index];
8897                         }
8898                         if (sdtr_accept) {
8899                                 sdtr_data =
8900                                     AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8901                                                    ext_msg.req_ack_offset);
8902                                 if ((sdtr_data == 0xFF)) {
8903
8904                                         q_cntl |= QC_MSG_OUT;
8905                                         asc_dvc->init_sdtr &= ~target_id;
8906                                         asc_dvc->sdtr_done &= ~target_id;
8907                                         AscSetChipSDTR(iop_base, asyn_sdtr,
8908                                                        tid_no);
8909                                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8910                                 }
8911                         }
8912                         if (ext_msg.req_ack_offset == 0) {
8913
8914                                 q_cntl &= ~QC_MSG_OUT;
8915                                 asc_dvc->init_sdtr &= ~target_id;
8916                                 asc_dvc->sdtr_done &= ~target_id;
8917                                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8918                         } else {
8919                                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8920
8921                                         q_cntl &= ~QC_MSG_OUT;
8922                                         asc_dvc->sdtr_done |= target_id;
8923                                         asc_dvc->init_sdtr |= target_id;
8924                                         asc_dvc->pci_fix_asyn_xfer &=
8925                                             ~target_id;
8926                                         sdtr_data =
8927                                             AscCalSDTRData(asc_dvc,
8928                                                            ext_msg.xfer_period,
8929                                                            ext_msg.
8930                                                            req_ack_offset);
8931                                         AscSetChipSDTR(iop_base, sdtr_data,
8932                                                        tid_no);
8933                                         boardp->sdtr_data[tid_no] = sdtr_data;
8934                                 } else {
8935
8936                                         q_cntl |= QC_MSG_OUT;
8937                                         AscMsgOutSDTR(asc_dvc,
8938                                                       ext_msg.xfer_period,
8939                                                       ext_msg.req_ack_offset);
8940                                         asc_dvc->pci_fix_asyn_xfer &=
8941                                             ~target_id;
8942                                         sdtr_data =
8943                                             AscCalSDTRData(asc_dvc,
8944                                                            ext_msg.xfer_period,
8945                                                            ext_msg.
8946                                                            req_ack_offset);
8947                                         AscSetChipSDTR(iop_base, sdtr_data,
8948                                                        tid_no);
8949                                         boardp->sdtr_data[tid_no] = sdtr_data;
8950                                         asc_dvc->sdtr_done |= target_id;
8951                                         asc_dvc->init_sdtr |= target_id;
8952                                 }
8953                         }
8954
8955                         AscWriteLramByte(iop_base,
8956                                          (ushort)(halt_q_addr +
8957                                                   (ushort)ASC_SCSIQ_B_CNTL),
8958                                          q_cntl);
8959                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8960                         return (0);
8961                 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8962                            ext_msg.msg_req == EXTENDED_WDTR &&
8963                            ext_msg.msg_len == MS_WDTR_LEN) {
8964
8965                         ext_msg.wdtr_width = 0;
8966                         AscMemWordCopyPtrToLram(iop_base,
8967                                                 ASCV_MSGOUT_BEG,
8968                                                 (uchar *)&ext_msg,
8969                                                 sizeof(EXT_MSG) >> 1);
8970                         q_cntl |= QC_MSG_OUT;
8971                         AscWriteLramByte(iop_base,
8972                                          (ushort)(halt_q_addr +
8973                                                   (ushort)ASC_SCSIQ_B_CNTL),
8974                                          q_cntl);
8975                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8976                         return (0);
8977                 } else {
8978
8979                         ext_msg.msg_type = MESSAGE_REJECT;
8980                         AscMemWordCopyPtrToLram(iop_base,
8981                                                 ASCV_MSGOUT_BEG,
8982                                                 (uchar *)&ext_msg,
8983                                                 sizeof(EXT_MSG) >> 1);
8984                         q_cntl |= QC_MSG_OUT;
8985                         AscWriteLramByte(iop_base,
8986                                          (ushort)(halt_q_addr +
8987                                                   (ushort)ASC_SCSIQ_B_CNTL),
8988                                          q_cntl);
8989                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8990                         return (0);
8991                 }
8992         } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8993
8994                 q_cntl |= QC_REQ_SENSE;
8995
8996                 if ((asc_dvc->init_sdtr & target_id) != 0) {
8997
8998                         asc_dvc->sdtr_done &= ~target_id;
8999
9000                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9001                         q_cntl |= QC_MSG_OUT;
9002                         AscMsgOutSDTR(asc_dvc,
9003                                       asc_dvc->
9004                                       sdtr_period_tbl[(sdtr_data >> 4) &
9005                                                       (uchar)(asc_dvc->
9006                                                               max_sdtr_index -
9007                                                               1)],
9008                                       (uchar)(sdtr_data & (uchar)
9009                                               ASC_SYN_MAX_OFFSET));
9010                 }
9011
9012                 AscWriteLramByte(iop_base,
9013                                  (ushort)(halt_q_addr +
9014                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
9015
9016                 tag_code = AscReadLramByte(iop_base,
9017                                            (ushort)(halt_q_addr + (ushort)
9018                                                     ASC_SCSIQ_B_TAG_CODE));
9019                 tag_code &= 0xDC;
9020                 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
9021                     && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
9022                     ) {
9023
9024                         tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
9025                                      | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
9026
9027                 }
9028                 AscWriteLramByte(iop_base,
9029                                  (ushort)(halt_q_addr +
9030                                           (ushort)ASC_SCSIQ_B_TAG_CODE),
9031                                  tag_code);
9032
9033                 q_status = AscReadLramByte(iop_base,
9034                                            (ushort)(halt_q_addr + (ushort)
9035                                                     ASC_SCSIQ_B_STATUS));
9036                 q_status |= (QS_READY | QS_BUSY);
9037                 AscWriteLramByte(iop_base,
9038                                  (ushort)(halt_q_addr +
9039                                           (ushort)ASC_SCSIQ_B_STATUS),
9040                                  q_status);
9041
9042                 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
9043                 scsi_busy &= ~target_id;
9044                 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
9045
9046                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9047                 return (0);
9048         } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
9049
9050                 AscMemWordCopyPtrFromLram(iop_base,
9051                                           ASCV_MSGOUT_BEG,
9052                                           (uchar *)&out_msg,
9053                                           sizeof(EXT_MSG) >> 1);
9054
9055                 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
9056                     (out_msg.msg_len == MS_SDTR_LEN) &&
9057                     (out_msg.msg_req == EXTENDED_SDTR)) {
9058
9059                         asc_dvc->init_sdtr &= ~target_id;
9060                         asc_dvc->sdtr_done &= ~target_id;
9061                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9062                         boardp->sdtr_data[tid_no] = asyn_sdtr;
9063                 }
9064                 q_cntl &= ~QC_MSG_OUT;
9065                 AscWriteLramByte(iop_base,
9066                                  (ushort)(halt_q_addr +
9067                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
9068                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9069                 return (0);
9070         } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
9071
9072                 scsi_status = AscReadLramByte(iop_base,
9073                                               (ushort)((ushort)halt_q_addr +
9074                                                        (ushort)
9075                                                        ASC_SCSIQ_SCSI_STATUS));
9076                 cur_dvc_qng =
9077                     AscReadLramByte(iop_base,
9078                                     (ushort)((ushort)ASC_QADR_BEG +
9079                                              (ushort)target_ix));
9080                 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
9081
9082                         scsi_busy = AscReadLramByte(iop_base,
9083                                                     (ushort)ASCV_SCSIBUSY_B);
9084                         scsi_busy |= target_id;
9085                         AscWriteLramByte(iop_base,
9086                                          (ushort)ASCV_SCSIBUSY_B, scsi_busy);
9087                         asc_dvc->queue_full_or_busy |= target_id;
9088
9089                         if (scsi_status == SAM_STAT_TASK_SET_FULL) {
9090                                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
9091                                         cur_dvc_qng -= 1;
9092                                         asc_dvc->max_dvc_qng[tid_no] =
9093                                             cur_dvc_qng;
9094
9095                                         AscWriteLramByte(iop_base,
9096                                                          (ushort)((ushort)
9097                                                                   ASCV_MAX_DVC_QNG_BEG
9098                                                                   + (ushort)
9099                                                                   tid_no),
9100                                                          cur_dvc_qng);
9101
9102                                         /*
9103                                          * Set the device queue depth to the
9104                                          * number of active requests when the
9105                                          * QUEUE FULL condition was encountered.
9106                                          */
9107                                         boardp->queue_full |= target_id;
9108                                         boardp->queue_full_cnt[tid_no] =
9109                                             cur_dvc_qng;
9110                                 }
9111                         }
9112                 }
9113                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9114                 return (0);
9115         }
9116 #if CC_VERY_LONG_SG_LIST
9117         else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
9118                 uchar q_no;
9119                 ushort q_addr;
9120                 uchar sg_wk_q_no;
9121                 uchar first_sg_wk_q_no;
9122                 ASC_SCSI_Q *scsiq;      /* Ptr to driver request. */
9123                 ASC_SG_HEAD *sg_head;   /* Ptr to driver SG request. */
9124                 ASC_SG_LIST_Q scsi_sg_q;        /* Structure written to queue. */
9125                 ushort sg_list_dwords;
9126                 ushort sg_entry_cnt;
9127                 uchar next_qp;
9128                 int i;
9129
9130                 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
9131                 if (q_no == ASC_QLINK_END)
9132                         return 0;
9133
9134                 q_addr = ASC_QNO_TO_QADDR(q_no);
9135
9136                 /*
9137                  * Convert the request's SRB pointer to a host ASC_SCSI_REQ
9138                  * structure pointer using a macro provided by the driver.
9139                  * The ASC_SCSI_REQ pointer provides a pointer to the
9140                  * host ASC_SG_HEAD structure.
9141                  */
9142                 /* Read request's SRB pointer. */
9143                 scsiq = (ASC_SCSI_Q *)
9144                     ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
9145                                                                     (ushort)
9146                                                                     (q_addr +
9147                                                                      ASC_SCSIQ_D_SRBPTR))));
9148
9149                 /*
9150                  * Get request's first and working SG queue.
9151                  */
9152                 sg_wk_q_no = AscReadLramByte(iop_base,
9153                                              (ushort)(q_addr +
9154                                                       ASC_SCSIQ_B_SG_WK_QP));
9155
9156                 first_sg_wk_q_no = AscReadLramByte(iop_base,
9157                                                    (ushort)(q_addr +
9158                                                             ASC_SCSIQ_B_FIRST_SG_WK_QP));
9159
9160                 /*
9161                  * Reset request's working SG queue back to the
9162                  * first SG queue.
9163                  */
9164                 AscWriteLramByte(iop_base,
9165                                  (ushort)(q_addr +
9166                                           (ushort)ASC_SCSIQ_B_SG_WK_QP),
9167                                  first_sg_wk_q_no);
9168
9169                 sg_head = scsiq->sg_head;
9170
9171                 /*
9172                  * Set sg_entry_cnt to the number of SG elements
9173                  * that will be completed on this interrupt.
9174                  *
9175                  * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
9176                  * SG elements. The data_cnt and data_addr fields which
9177                  * add 1 to the SG element capacity are not used when
9178                  * restarting SG handling after a halt.
9179                  */
9180                 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
9181                         sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9182
9183                         /*
9184                          * Keep track of remaining number of SG elements that
9185                          * will need to be handled on the next interrupt.
9186                          */
9187                         scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
9188                 } else {
9189                         sg_entry_cnt = scsiq->remain_sg_entry_cnt;
9190                         scsiq->remain_sg_entry_cnt = 0;
9191                 }
9192
9193                 /*
9194                  * Copy SG elements into the list of allocated SG queues.
9195                  *
9196                  * Last index completed is saved in scsiq->next_sg_index.
9197                  */
9198                 next_qp = first_sg_wk_q_no;
9199                 q_addr = ASC_QNO_TO_QADDR(next_qp);
9200                 scsi_sg_q.sg_head_qp = q_no;
9201                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9202                 for (i = 0; i < sg_head->queue_cnt; i++) {
9203                         scsi_sg_q.seq_no = i + 1;
9204                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9205                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9206                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9207                                 /*
9208                                  * After very first SG queue RISC FW uses next
9209                                  * SG queue first element then checks sg_list_cnt
9210                                  * against zero and then decrements, so set
9211                                  * sg_list_cnt 1 less than number of SG elements
9212                                  * in each SG queue.
9213                                  */
9214                                 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
9215                                 scsi_sg_q.sg_cur_list_cnt =
9216                                     ASC_SG_LIST_PER_Q - 1;
9217                         } else {
9218                                 /*
9219                                  * This is the last SG queue in the list of
9220                                  * allocated SG queues. If there are more
9221                                  * SG elements than will fit in the allocated
9222                                  * queues, then set the QCSG_SG_XFER_MORE flag.
9223                                  */
9224                                 if (scsiq->remain_sg_entry_cnt != 0) {
9225                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9226                                 } else {
9227                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9228                                 }
9229                                 /* equals sg_entry_cnt * 2 */
9230                                 sg_list_dwords = sg_entry_cnt << 1;
9231                                 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
9232                                 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
9233                                 sg_entry_cnt = 0;
9234                         }
9235
9236                         scsi_sg_q.q_no = next_qp;
9237                         AscMemWordCopyPtrToLram(iop_base,
9238                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9239                                                 (uchar *)&scsi_sg_q,
9240                                                 sizeof(ASC_SG_LIST_Q) >> 1);
9241
9242                         AscMemDWordCopyPtrToLram(iop_base,
9243                                                  q_addr + ASC_SGQ_LIST_BEG,
9244                                                  (uchar *)&sg_head->
9245                                                  sg_list[scsiq->next_sg_index],
9246                                                  sg_list_dwords);
9247
9248                         scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9249
9250                         /*
9251                          * If the just completed SG queue contained the
9252                          * last SG element, then no more SG queues need
9253                          * to be written.
9254                          */
9255                         if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9256                                 break;
9257                         }
9258
9259                         next_qp = AscReadLramByte(iop_base,
9260                                                   (ushort)(q_addr +
9261                                                            ASC_SCSIQ_B_FWD));
9262                         q_addr = ASC_QNO_TO_QADDR(next_qp);
9263                 }
9264
9265                 /*
9266                  * Clear the halt condition so the RISC will be restarted
9267                  * after the return.
9268                  */
9269                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9270                 return (0);
9271         }
9272 #endif /* CC_VERY_LONG_SG_LIST */
9273         return (0);
9274 }
9275
9276 /*
9277  * void
9278  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9279  *
9280  * Calling/Exit State:
9281  *    none
9282  *
9283  * Description:
9284  *     Input an ASC_QDONE_INFO structure from the chip
9285  */
9286 static void
9287 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9288 {
9289         int i;
9290         ushort word;
9291
9292         AscSetChipLramAddr(iop_base, s_addr);
9293         for (i = 0; i < 2 * words; i += 2) {
9294                 if (i == 10) {
9295                         continue;
9296                 }
9297                 word = inpw(iop_base + IOP_RAM_DATA);
9298                 inbuf[i] = word & 0xff;
9299                 inbuf[i + 1] = (word >> 8) & 0xff;
9300         }
9301         ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9302 }
9303
9304 static uchar
9305 _AscCopyLramScsiDoneQ(PortAddr iop_base,
9306                       ushort q_addr,
9307                       ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9308 {
9309         ushort _val;
9310         uchar sg_queue_cnt;
9311
9312         DvcGetQinfo(iop_base,
9313                     q_addr + ASC_SCSIQ_DONE_INFO_BEG,
9314                     (uchar *)scsiq,
9315                     (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
9316
9317         _val = AscReadLramWord(iop_base,
9318                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
9319         scsiq->q_status = (uchar)_val;
9320         scsiq->q_no = (uchar)(_val >> 8);
9321         _val = AscReadLramWord(iop_base,
9322                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
9323         scsiq->cntl = (uchar)_val;
9324         sg_queue_cnt = (uchar)(_val >> 8);
9325         _val = AscReadLramWord(iop_base,
9326                                (ushort)(q_addr +
9327                                         (ushort)ASC_SCSIQ_B_SENSE_LEN));
9328         scsiq->sense_len = (uchar)_val;
9329         scsiq->extra_bytes = (uchar)(_val >> 8);
9330
9331         /*
9332          * Read high word of remain bytes from alternate location.
9333          */
9334         scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9335                                                           (ushort)(q_addr +
9336                                                                    (ushort)
9337                                                                    ASC_SCSIQ_W_ALT_DC1)))
9338                                << 16);
9339         /*
9340          * Read low word of remain bytes from original location.
9341          */
9342         scsiq->remain_bytes += AscReadLramWord(iop_base,
9343                                                (ushort)(q_addr + (ushort)
9344                                                         ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9345
9346         scsiq->remain_bytes &= max_dma_count;
9347         return sg_queue_cnt;
9348 }
9349
9350 /*
9351  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9352  *
9353  * Interrupt callback function for the Narrow SCSI Asc Library.
9354  */
9355 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9356 {
9357         asc_board_t *boardp;
9358         struct scsi_cmnd *scp;
9359         struct Scsi_Host *shost;
9360
9361         ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
9362                  (ulong)asc_dvc_varp, (ulong)qdonep);
9363         ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9364
9365         /*
9366          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
9367          * command that has been completed.
9368          */
9369         scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
9370         ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
9371
9372         if (scp == NULL) {
9373                 ASC_PRINT("asc_isr_callback: scp is NULL\n");
9374                 return;
9375         }
9376         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9377
9378         shost = scp->device->host;
9379         ASC_STATS(shost, callback);
9380         ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
9381
9382         boardp = ASC_BOARDP(shost);
9383         BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9384
9385         /*
9386          * 'qdonep' contains the command's ending status.
9387          */
9388         switch (qdonep->d3.done_stat) {
9389         case QD_NO_ERROR:
9390                 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
9391                 scp->result = 0;
9392
9393                 /*
9394                  * Check for an underrun condition.
9395                  *
9396                  * If there was no error and an underrun condition, then
9397                  * return the number of underrun bytes.
9398                  */
9399                 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
9400                     qdonep->remain_bytes <= scp->request_bufflen) {
9401                         ASC_DBG1(1,
9402                                  "asc_isr_callback: underrun condition %u bytes\n",
9403                                  (unsigned)qdonep->remain_bytes);
9404                         scp->resid = qdonep->remain_bytes;
9405                 }
9406                 break;
9407
9408         case QD_WITH_ERROR:
9409                 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
9410                 switch (qdonep->d3.host_stat) {
9411                 case QHSTA_NO_ERROR:
9412                         if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
9413                                 ASC_DBG(2,
9414                                         "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
9415                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9416                                                   sizeof(scp->sense_buffer));
9417                                 /*
9418                                  * Note: The 'status_byte()' macro used by
9419                                  * target drivers defined in scsi.h shifts the
9420                                  * status byte returned by host drivers right
9421                                  * by 1 bit.  This is why target drivers also
9422                                  * use right shifted status byte definitions.
9423                                  * For instance target drivers use
9424                                  * CHECK_CONDITION, defined to 0x1, instead of
9425                                  * the SCSI defined check condition value of
9426                                  * 0x2. Host drivers are supposed to return
9427                                  * the status byte as it is defined by SCSI.
9428                                  */
9429                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
9430                                     STATUS_BYTE(qdonep->d3.scsi_stat);
9431                         } else {
9432                                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
9433                         }
9434                         break;
9435
9436                 default:
9437                         /* QHSTA error occurred */
9438                         ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
9439                                  qdonep->d3.host_stat);
9440                         scp->result = HOST_BYTE(DID_BAD_TARGET);
9441                         break;
9442                 }
9443                 break;
9444
9445         case QD_ABORTED_BY_HOST:
9446                 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
9447                 scp->result =
9448                     HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9449                                                     scsi_msg) |
9450                     STATUS_BYTE(qdonep->d3.scsi_stat);
9451                 break;
9452
9453         default:
9454                 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
9455                          qdonep->d3.done_stat);
9456                 scp->result =
9457                     HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9458                                                     scsi_msg) |
9459                     STATUS_BYTE(qdonep->d3.scsi_stat);
9460                 break;
9461         }
9462
9463         /*
9464          * If the 'init_tidmask' bit isn't already set for the target and the
9465          * current request finished normally, then set the bit for the target
9466          * to indicate that a device is present.
9467          */
9468         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
9469             qdonep->d3.done_stat == QD_NO_ERROR &&
9470             qdonep->d3.host_stat == QHSTA_NO_ERROR) {
9471                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
9472         }
9473
9474         asc_scsi_done(scp);
9475
9476         return;
9477 }
9478
9479 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9480 {
9481         uchar next_qp;
9482         uchar n_q_used;
9483         uchar sg_list_qp;
9484         uchar sg_queue_cnt;
9485         uchar q_cnt;
9486         uchar done_q_tail;
9487         uchar tid_no;
9488         ASC_SCSI_BIT_ID_TYPE scsi_busy;
9489         ASC_SCSI_BIT_ID_TYPE target_id;
9490         PortAddr iop_base;
9491         ushort q_addr;
9492         ushort sg_q_addr;
9493         uchar cur_target_qng;
9494         ASC_QDONE_INFO scsiq_buf;
9495         ASC_QDONE_INFO *scsiq;
9496         int false_overrun;
9497
9498         iop_base = asc_dvc->iop_base;
9499         n_q_used = 1;
9500         scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9501         done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9502         q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9503         next_qp = AscReadLramByte(iop_base,
9504                                   (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9505         if (next_qp != ASC_QLINK_END) {
9506                 AscPutVarDoneQTail(iop_base, next_qp);
9507                 q_addr = ASC_QNO_TO_QADDR(next_qp);
9508                 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9509                                                      asc_dvc->max_dma_count);
9510                 AscWriteLramByte(iop_base,
9511                                  (ushort)(q_addr +
9512                                           (ushort)ASC_SCSIQ_B_STATUS),
9513                                  (uchar)(scsiq->
9514                                          q_status & (uchar)~(QS_READY |
9515                                                              QS_ABORTED)));
9516                 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9517                 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9518                 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9519                         sg_q_addr = q_addr;
9520                         sg_list_qp = next_qp;
9521                         for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9522                                 sg_list_qp = AscReadLramByte(iop_base,
9523                                                              (ushort)(sg_q_addr
9524                                                                       + (ushort)
9525                                                                       ASC_SCSIQ_B_FWD));
9526                                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9527                                 if (sg_list_qp == ASC_QLINK_END) {
9528                                         AscSetLibErrorCode(asc_dvc,
9529                                                            ASCQ_ERR_SG_Q_LINKS);
9530                                         scsiq->d3.done_stat = QD_WITH_ERROR;
9531                                         scsiq->d3.host_stat =
9532                                             QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9533                                         goto FATAL_ERR_QDONE;
9534                                 }
9535                                 AscWriteLramByte(iop_base,
9536                                                  (ushort)(sg_q_addr + (ushort)
9537                                                           ASC_SCSIQ_B_STATUS),
9538                                                  QS_FREE);
9539                         }
9540                         n_q_used = sg_queue_cnt + 1;
9541                         AscPutVarDoneQTail(iop_base, sg_list_qp);
9542                 }
9543                 if (asc_dvc->queue_full_or_busy & target_id) {
9544                         cur_target_qng = AscReadLramByte(iop_base,
9545                                                          (ushort)((ushort)
9546                                                                   ASC_QADR_BEG
9547                                                                   + (ushort)
9548                                                                   scsiq->d2.
9549                                                                   target_ix));
9550                         if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9551                                 scsi_busy = AscReadLramByte(iop_base, (ushort)
9552                                                             ASCV_SCSIBUSY_B);
9553                                 scsi_busy &= ~target_id;
9554                                 AscWriteLramByte(iop_base,
9555                                                  (ushort)ASCV_SCSIBUSY_B,
9556                                                  scsi_busy);
9557                                 asc_dvc->queue_full_or_busy &= ~target_id;
9558                         }
9559                 }
9560                 if (asc_dvc->cur_total_qng >= n_q_used) {
9561                         asc_dvc->cur_total_qng -= n_q_used;
9562                         if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9563                                 asc_dvc->cur_dvc_qng[tid_no]--;
9564                         }
9565                 } else {
9566                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9567                         scsiq->d3.done_stat = QD_WITH_ERROR;
9568                         goto FATAL_ERR_QDONE;
9569                 }
9570                 if ((scsiq->d2.srb_ptr == 0UL) ||
9571                     ((scsiq->q_status & QS_ABORTED) != 0)) {
9572                         return (0x11);
9573                 } else if (scsiq->q_status == QS_DONE) {
9574                         false_overrun = FALSE;
9575                         if (scsiq->extra_bytes != 0) {
9576                                 scsiq->remain_bytes +=
9577                                     (ADV_DCNT)scsiq->extra_bytes;
9578                         }
9579                         if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9580                                 if (scsiq->d3.host_stat ==
9581                                     QHSTA_M_DATA_OVER_RUN) {
9582                                         if ((scsiq->
9583                                              cntl & (QC_DATA_IN | QC_DATA_OUT))
9584                                             == 0) {
9585                                                 scsiq->d3.done_stat =
9586                                                     QD_NO_ERROR;
9587                                                 scsiq->d3.host_stat =
9588                                                     QHSTA_NO_ERROR;
9589                                         } else if (false_overrun) {
9590                                                 scsiq->d3.done_stat =
9591                                                     QD_NO_ERROR;
9592                                                 scsiq->d3.host_stat =
9593                                                     QHSTA_NO_ERROR;
9594                                         }
9595                                 } else if (scsiq->d3.host_stat ==
9596                                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9597                                         AscStopChip(iop_base);
9598                                         AscSetChipControl(iop_base,
9599                                                           (uchar)(CC_SCSI_RESET
9600                                                                   | CC_HALT));
9601                                         udelay(60);
9602                                         AscSetChipControl(iop_base, CC_HALT);
9603                                         AscSetChipStatus(iop_base,
9604                                                          CIW_CLR_SCSI_RESET_INT);
9605                                         AscSetChipStatus(iop_base, 0);
9606                                         AscSetChipControl(iop_base, 0);
9607                                 }
9608                         }
9609                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9610                                 asc_isr_callback(asc_dvc, scsiq);
9611                         } else {
9612                                 if ((AscReadLramByte(iop_base,
9613                                                      (ushort)(q_addr + (ushort)
9614                                                               ASC_SCSIQ_CDB_BEG))
9615                                      == START_STOP)) {
9616                                         asc_dvc->unit_not_ready &= ~target_id;
9617                                         if (scsiq->d3.done_stat != QD_NO_ERROR) {
9618                                                 asc_dvc->start_motor &=
9619                                                     ~target_id;
9620                                         }
9621                                 }
9622                         }
9623                         return (1);
9624                 } else {
9625                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9626  FATAL_ERR_QDONE:
9627                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9628                                 asc_isr_callback(asc_dvc, scsiq);
9629                         }
9630                         return (0x80);
9631                 }
9632         }
9633         return (0);
9634 }
9635
9636 static int AscISR(ASC_DVC_VAR *asc_dvc)
9637 {
9638         ASC_CS_TYPE chipstat;
9639         PortAddr iop_base;
9640         ushort saved_ram_addr;
9641         uchar ctrl_reg;
9642         uchar saved_ctrl_reg;
9643         int int_pending;
9644         int status;
9645         uchar host_flag;
9646
9647         iop_base = asc_dvc->iop_base;
9648         int_pending = FALSE;
9649
9650         if (AscIsIntPending(iop_base) == 0)
9651                 return int_pending;
9652
9653         if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9654                 return ERR;
9655         }
9656         if (asc_dvc->in_critical_cnt != 0) {
9657                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9658                 return ERR;
9659         }
9660         if (asc_dvc->is_in_int) {
9661                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9662                 return ERR;
9663         }
9664         asc_dvc->is_in_int = TRUE;
9665         ctrl_reg = AscGetChipControl(iop_base);
9666         saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9667                                        CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9668         chipstat = AscGetChipStatus(iop_base);
9669         if (chipstat & CSW_SCSI_RESET_LATCH) {
9670                 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9671                         int i = 10;
9672                         int_pending = TRUE;
9673                         asc_dvc->sdtr_done = 0;
9674                         saved_ctrl_reg &= (uchar)(~CC_HALT);
9675                         while ((AscGetChipStatus(iop_base) &
9676                                 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9677                                 mdelay(100);
9678                         }
9679                         AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9680                         AscSetChipControl(iop_base, CC_HALT);
9681                         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9682                         AscSetChipStatus(iop_base, 0);
9683                         chipstat = AscGetChipStatus(iop_base);
9684                 }
9685         }
9686         saved_ram_addr = AscGetChipLramAddr(iop_base);
9687         host_flag = AscReadLramByte(iop_base,
9688                                     ASCV_HOST_FLAG_B) &
9689             (uchar)(~ASC_HOST_FLAG_IN_ISR);
9690         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9691                          (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9692         if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
9693                 AscAckInterrupt(iop_base);
9694                 int_pending = TRUE;
9695                 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9696                         if (AscIsrChipHalted(asc_dvc) == ERR) {
9697                                 goto ISR_REPORT_QDONE_FATAL_ERROR;
9698                         } else {
9699                                 saved_ctrl_reg &= (uchar)(~CC_HALT);
9700                         }
9701                 } else {
9702  ISR_REPORT_QDONE_FATAL_ERROR:
9703                         if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9704                                 while (((status =
9705                                          AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9706                                 }
9707                         } else {
9708                                 do {
9709                                         if ((status =
9710                                              AscIsrQDone(asc_dvc)) == 1) {
9711                                                 break;
9712                                         }
9713                                 } while (status == 0x11);
9714                         }
9715                         if ((status & 0x80) != 0)
9716                                 int_pending = ERR;
9717                 }
9718         }
9719         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9720         AscSetChipLramAddr(iop_base, saved_ram_addr);
9721         AscSetChipControl(iop_base, saved_ctrl_reg);
9722         asc_dvc->is_in_int = FALSE;
9723         return int_pending;
9724 }
9725
9726 /*
9727  * advansys_reset()
9728  *
9729  * Reset the bus associated with the command 'scp'.
9730  *
9731  * This function runs its own thread. Interrupts must be blocked but
9732  * sleeping is allowed and no locking other than for host structures is
9733  * required. Returns SUCCESS or FAILED.
9734  */
9735 static int advansys_reset(struct scsi_cmnd *scp)
9736 {
9737         struct Scsi_Host *shost = scp->device->host;
9738         struct asc_board *boardp = ASC_BOARDP(shost);
9739         unsigned long flags;
9740         int status;
9741         int ret = SUCCESS;
9742
9743         ASC_DBG1(1, "advansys_reset: 0x%p\n", scp);
9744
9745         ASC_STATS(shost, reset);
9746
9747         scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
9748
9749         if (ASC_NARROW_BOARD(boardp)) {
9750                 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9751
9752                 /* Reset the chip and SCSI bus. */
9753                 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
9754                 status = AscInitAsc1000Driver(asc_dvc);
9755
9756                 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
9757                 if (asc_dvc->err_code) {
9758                         scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9759                                     "0x%x\n", asc_dvc->err_code);
9760                         ret = FAILED;
9761                 } else if (status) {
9762                         scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9763                                     "0x%x\n", status);
9764                 } else {
9765                         scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9766                                     "successful\n");
9767                 }
9768
9769                 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
9770                 spin_lock_irqsave(&boardp->lock, flags);
9771         } else {
9772                 /*
9773                  * If the suggest reset bus flags are set, then reset the bus.
9774                  * Otherwise only reset the device.
9775                  */
9776                 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
9777
9778                 /*
9779                  * Reset the target's SCSI bus.
9780                  */
9781                 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
9782                 switch (AdvResetChipAndSB(adv_dvc)) {
9783                 case ASC_TRUE:
9784                         scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9785                                     "successful\n");
9786                         break;
9787                 case ASC_FALSE:
9788                 default:
9789                         scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
9790                         ret = FAILED;
9791                         break;
9792                 }
9793                 spin_lock_irqsave(&boardp->lock, flags);
9794                 AdvISR(adv_dvc);
9795         }
9796
9797         /* Save the time of the most recently completed reset. */
9798         boardp->last_reset = jiffies;
9799         spin_unlock_irqrestore(&boardp->lock, flags);
9800
9801         ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
9802
9803         return ret;
9804 }
9805
9806 /*
9807  * advansys_biosparam()
9808  *
9809  * Translate disk drive geometry if the "BIOS greater than 1 GB"
9810  * support is enabled for a drive.
9811  *
9812  * ip (information pointer) is an int array with the following definition:
9813  * ip[0]: heads
9814  * ip[1]: sectors
9815  * ip[2]: cylinders
9816  */
9817 static int
9818 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9819                    sector_t capacity, int ip[])
9820 {
9821         asc_board_t *boardp;
9822
9823         ASC_DBG(1, "advansys_biosparam: begin\n");
9824         ASC_STATS(sdev->host, biosparam);
9825         boardp = ASC_BOARDP(sdev->host);
9826         if (ASC_NARROW_BOARD(boardp)) {
9827                 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
9828                      ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
9829                         ip[0] = 255;
9830                         ip[1] = 63;
9831                 } else {
9832                         ip[0] = 64;
9833                         ip[1] = 32;
9834                 }
9835         } else {
9836                 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
9837                      BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
9838                         ip[0] = 255;
9839                         ip[1] = 63;
9840                 } else {
9841                         ip[0] = 64;
9842                         ip[1] = 32;
9843                 }
9844         }
9845         ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
9846         ASC_DBG(1, "advansys_biosparam: end\n");
9847         return 0;
9848 }
9849
9850 /*
9851  * First-level interrupt handler.
9852  *
9853  * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9854  */
9855 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9856 {
9857         unsigned long flags;
9858         struct Scsi_Host *shost = dev_id;
9859         asc_board_t *boardp = ASC_BOARDP(shost);
9860         irqreturn_t result = IRQ_NONE;
9861
9862         ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
9863         spin_lock_irqsave(&boardp->lock, flags);
9864         if (ASC_NARROW_BOARD(boardp)) {
9865                 if (AscIsIntPending(shost->io_port)) {
9866                         result = IRQ_HANDLED;
9867                         ASC_STATS(shost, interrupt);
9868                         ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
9869                         AscISR(&boardp->dvc_var.asc_dvc_var);
9870                 }
9871         } else {
9872                 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
9873                 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9874                         result = IRQ_HANDLED;
9875                         ASC_STATS(shost, interrupt);
9876                 }
9877         }
9878         spin_unlock_irqrestore(&boardp->lock, flags);
9879
9880         ASC_DBG(1, "advansys_interrupt: end\n");
9881         return result;
9882 }
9883
9884 static int AscHostReqRiscHalt(PortAddr iop_base)
9885 {
9886         int count = 0;
9887         int sta = 0;
9888         uchar saved_stop_code;
9889
9890         if (AscIsChipHalted(iop_base))
9891                 return (1);
9892         saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9893         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9894                          ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9895         do {
9896                 if (AscIsChipHalted(iop_base)) {
9897                         sta = 1;
9898                         break;
9899                 }
9900                 mdelay(100);
9901         } while (count++ < 20);
9902         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9903         return (sta);
9904 }
9905
9906 static int
9907 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9908 {
9909         int sta = FALSE;
9910
9911         if (AscHostReqRiscHalt(iop_base)) {
9912                 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9913                 AscStartChip(iop_base);
9914         }
9915         return sta;
9916 }
9917
9918 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9919 {
9920         char type = sdev->type;
9921         ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
9922
9923         if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9924                 return;
9925         if (asc_dvc->init_sdtr & tid_bits)
9926                 return;
9927
9928         if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9929                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9930
9931         asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9932         if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9933             (type == TYPE_ROM) || (type == TYPE_TAPE))
9934                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9935
9936         if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9937                 AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
9938                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
9939 }
9940
9941 static void
9942 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9943 {
9944         ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
9945         ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
9946
9947         if (sdev->lun == 0) {
9948                 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
9949                 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
9950                         asc_dvc->init_sdtr |= tid_bit;
9951                 } else {
9952                         asc_dvc->init_sdtr &= ~tid_bit;
9953                 }
9954
9955                 if (orig_init_sdtr != asc_dvc->init_sdtr)
9956                         AscAsyncFix(asc_dvc, sdev);
9957         }
9958
9959         if (sdev->tagged_supported) {
9960                 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
9961                         if (sdev->lun == 0) {
9962                                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
9963                                 asc_dvc->use_tagged_qng |= tid_bit;
9964                         }
9965                         scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9966                                                 asc_dvc->max_dvc_qng[sdev->id]);
9967                 }
9968         } else {
9969                 if (sdev->lun == 0) {
9970                         asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9971                         asc_dvc->use_tagged_qng &= ~tid_bit;
9972                 }
9973                 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9974         }
9975
9976         if ((sdev->lun == 0) &&
9977             (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
9978                 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
9979                                  asc_dvc->cfg->disc_enable);
9980                 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
9981                                  asc_dvc->use_tagged_qng);
9982                 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
9983                                  asc_dvc->cfg->can_tagged_qng);
9984
9985                 asc_dvc->max_dvc_qng[sdev->id] =
9986                                         asc_dvc->cfg->max_tag_qng[sdev->id];
9987                 AscWriteLramByte(asc_dvc->iop_base,
9988                                  (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
9989                                  asc_dvc->max_dvc_qng[sdev->id]);
9990         }
9991 }
9992
9993 /*
9994  * Wide Transfers
9995  *
9996  * If the EEPROM enabled WDTR for the device and the device supports wide
9997  * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
9998  * write the new value to the microcode.
9999  */
10000 static void
10001 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
10002 {
10003         unsigned short cfg_word;
10004         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
10005         if ((cfg_word & tidmask) != 0)
10006                 return;
10007
10008         cfg_word |= tidmask;
10009         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
10010
10011         /*
10012          * Clear the microcode SDTR and WDTR negotiation done indicators for
10013          * the target to cause it to negotiate with the new setting set above.
10014          * WDTR when accepted causes the target to enter asynchronous mode, so
10015          * SDTR must be negotiated.
10016          */
10017         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10018         cfg_word &= ~tidmask;
10019         AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10020         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
10021         cfg_word &= ~tidmask;
10022         AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
10023 }
10024
10025 /*
10026  * Synchronous Transfers
10027  *
10028  * If the EEPROM enabled SDTR for the device and the device
10029  * supports synchronous transfers, then turn on the device's
10030  * 'sdtr_able' bit. Write the new value to the microcode.
10031  */
10032 static void
10033 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
10034 {
10035         unsigned short cfg_word;
10036         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
10037         if ((cfg_word & tidmask) != 0)
10038                 return;
10039
10040         cfg_word |= tidmask;
10041         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
10042
10043         /*
10044          * Clear the microcode "SDTR negotiation" done indicator for the
10045          * target to cause it to negotiate with the new setting set above.
10046          */
10047         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10048         cfg_word &= ~tidmask;
10049         AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
10050 }
10051
10052 /*
10053  * PPR (Parallel Protocol Request) Capable
10054  *
10055  * If the device supports DT mode, then it must be PPR capable.
10056  * The PPR message will be used in place of the SDTR and WDTR
10057  * messages to negotiate synchronous speed and offset, transfer
10058  * width, and protocol options.
10059  */
10060 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
10061                                 AdvPortAddr iop_base, unsigned short tidmask)
10062 {
10063         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
10064         adv_dvc->ppr_able |= tidmask;
10065         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
10066 }
10067
10068 static void
10069 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
10070 {
10071         AdvPortAddr iop_base = adv_dvc->iop_base;
10072         unsigned short tidmask = 1 << sdev->id;
10073
10074         if (sdev->lun == 0) {
10075                 /*
10076                  * Handle WDTR, SDTR, and Tag Queuing. If the feature
10077                  * is enabled in the EEPROM and the device supports the
10078                  * feature, then enable it in the microcode.
10079                  */
10080
10081                 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
10082                         advansys_wide_enable_wdtr(iop_base, tidmask);
10083                 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
10084                         advansys_wide_enable_sdtr(iop_base, tidmask);
10085                 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
10086                         advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
10087
10088                 /*
10089                  * Tag Queuing is disabled for the BIOS which runs in polled
10090                  * mode and would see no benefit from Tag Queuing. Also by
10091                  * disabling Tag Queuing in the BIOS devices with Tag Queuing
10092                  * bugs will at least work with the BIOS.
10093                  */
10094                 if ((adv_dvc->tagqng_able & tidmask) &&
10095                     sdev->tagged_supported) {
10096                         unsigned short cfg_word;
10097                         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
10098                         cfg_word |= tidmask;
10099                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
10100                                          cfg_word);
10101                         AdvWriteByteLram(iop_base,
10102                                          ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
10103                                          adv_dvc->max_dvc_qng);
10104                 }
10105         }
10106
10107         if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
10108                 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
10109                                         adv_dvc->max_dvc_qng);
10110         } else {
10111                 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
10112         }
10113 }
10114
10115 /*
10116  * Set the number of commands to queue per device for the
10117  * specified host adapter.
10118  */
10119 static int advansys_slave_configure(struct scsi_device *sdev)
10120 {
10121         asc_board_t *boardp = ASC_BOARDP(sdev->host);
10122
10123         if (ASC_NARROW_BOARD(boardp))
10124                 advansys_narrow_slave_configure(sdev,
10125                                                 &boardp->dvc_var.asc_dvc_var);
10126         else
10127                 advansys_wide_slave_configure(sdev,
10128                                                 &boardp->dvc_var.adv_dvc_var);
10129
10130         return 0;
10131 }
10132
10133 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
10134                         struct asc_scsi_q *asc_scsi_q)
10135 {
10136         memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
10137
10138         /*
10139          * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
10140          */
10141         asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
10142
10143         /*
10144          * Build the ASC_SCSI_Q request.
10145          */
10146         asc_scsi_q->cdbptr = &scp->cmnd[0];
10147         asc_scsi_q->q2.cdb_len = scp->cmd_len;
10148         asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
10149         asc_scsi_q->q1.target_lun = scp->device->lun;
10150         asc_scsi_q->q2.target_ix =
10151             ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
10152         asc_scsi_q->q1.sense_addr =
10153             cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10154         asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
10155
10156         /*
10157          * If there are any outstanding requests for the current target,
10158          * then every 255th request send an ORDERED request. This heuristic
10159          * tries to retain the benefit of request sorting while preventing
10160          * request starvation. 255 is the max number of tags or pending commands
10161          * a device may have outstanding.
10162          *
10163          * The request count is incremented below for every successfully
10164          * started request.
10165          *
10166          */
10167         if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
10168             (boardp->reqcnt[scp->device->id] % 255) == 0) {
10169                 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
10170         } else {
10171                 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
10172         }
10173
10174         /*
10175          * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
10176          * buffer command.
10177          */
10178         if (scp->use_sg == 0) {
10179                 /*
10180                  * CDB request of single contiguous buffer.
10181                  */
10182                 ASC_STATS(scp->device->host, cont_cnt);
10183                 scp->SCp.dma_handle = scp->request_bufflen ?
10184                     dma_map_single(boardp->dev, scp->request_buffer,
10185                                    scp->request_bufflen,
10186                                    scp->sc_data_direction) : 0;
10187                 asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
10188                 asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen);
10189                 ASC_STATS_ADD(scp->device->host, cont_xfer,
10190                               ASC_CEILING(scp->request_bufflen, 512));
10191                 asc_scsi_q->q1.sg_queue_cnt = 0;
10192                 asc_scsi_q->sg_head = NULL;
10193         } else {
10194                 /*
10195                  * CDB scatter-gather request list.
10196                  */
10197                 int sgcnt;
10198                 int use_sg;
10199                 struct scatterlist *slp;
10200                 struct asc_sg_head *asc_sg_head;
10201
10202                 slp = (struct scatterlist *)scp->request_buffer;
10203                 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10204                                     scp->sc_data_direction);
10205
10206                 if (use_sg > scp->device->host->sg_tablesize) {
10207                         ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
10208                                    "sg_tablesize %d\n", boardp->id, use_sg,
10209                                    scp->device->host->sg_tablesize);
10210                         dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10211                                      scp->sc_data_direction);
10212                         scp->result = HOST_BYTE(DID_ERROR);
10213                         return ASC_ERROR;
10214                 }
10215
10216                 ASC_STATS(scp->device->host, sg_cnt);
10217
10218                 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
10219                         use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
10220                 if (!asc_sg_head) {
10221                         dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10222                                      scp->sc_data_direction);
10223                         scp->result = HOST_BYTE(DID_SOFT_ERROR);
10224                         return ASC_ERROR;
10225                 }
10226
10227                 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
10228                 asc_scsi_q->sg_head = asc_sg_head;
10229                 asc_scsi_q->q1.data_cnt = 0;
10230                 asc_scsi_q->q1.data_addr = 0;
10231                 /* This is a byte value, otherwise it would need to be swapped. */
10232                 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
10233                 ASC_STATS_ADD(scp->device->host, sg_elem,
10234                               asc_sg_head->entry_cnt);
10235
10236                 /*
10237                  * Convert scatter-gather list into ASC_SG_HEAD list.
10238                  */
10239                 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
10240                         asc_sg_head->sg_list[sgcnt].addr =
10241                             cpu_to_le32(sg_dma_address(slp));
10242                         asc_sg_head->sg_list[sgcnt].bytes =
10243                             cpu_to_le32(sg_dma_len(slp));
10244                         ASC_STATS_ADD(scp->device->host, sg_xfer,
10245                                       ASC_CEILING(sg_dma_len(slp), 512));
10246                 }
10247         }
10248
10249         ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
10250         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10251
10252         return ASC_NOERROR;
10253 }
10254
10255 /*
10256  * Build scatter-gather list for Adv Library (Wide Board).
10257  *
10258  * Additional ADV_SG_BLOCK structures will need to be allocated
10259  * if the total number of scatter-gather elements exceeds
10260  * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
10261  * assumed to be physically contiguous.
10262  *
10263  * Return:
10264  *      ADV_SUCCESS(1) - SG List successfully created
10265  *      ADV_ERROR(-1) - SG List creation failed
10266  */
10267 static int
10268 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
10269                int use_sg)
10270 {
10271         adv_sgblk_t *sgblkp;
10272         ADV_SCSI_REQ_Q *scsiqp;
10273         struct scatterlist *slp;
10274         int sg_elem_cnt;
10275         ADV_SG_BLOCK *sg_block, *prev_sg_block;
10276         ADV_PADDR sg_block_paddr;
10277         int i;
10278
10279         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10280         slp = (struct scatterlist *)scp->request_buffer;
10281         sg_elem_cnt = use_sg;
10282         prev_sg_block = NULL;
10283         reqp->sgblkp = NULL;
10284
10285         for (;;) {
10286                 /*
10287                  * Allocate a 'adv_sgblk_t' structure from the board free
10288                  * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
10289                  * (15) scatter-gather elements.
10290                  */
10291                 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
10292                         ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
10293                         ASC_STATS(scp->device->host, adv_build_nosg);
10294
10295                         /*
10296                          * Allocation failed. Free 'adv_sgblk_t' structures
10297                          * already allocated for the request.
10298                          */
10299                         while ((sgblkp = reqp->sgblkp) != NULL) {
10300                                 /* Remove 'sgblkp' from the request list. */
10301                                 reqp->sgblkp = sgblkp->next_sgblkp;
10302
10303                                 /* Add 'sgblkp' to the board free list. */
10304                                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
10305                                 boardp->adv_sgblkp = sgblkp;
10306                         }
10307                         return ASC_BUSY;
10308                 }
10309
10310                 /* Complete 'adv_sgblk_t' board allocation. */
10311                 boardp->adv_sgblkp = sgblkp->next_sgblkp;
10312                 sgblkp->next_sgblkp = NULL;
10313
10314                 /*
10315                  * Get 8 byte aligned virtual and physical addresses
10316                  * for the allocated ADV_SG_BLOCK structure.
10317                  */
10318                 sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10319                 sg_block_paddr = virt_to_bus(sg_block);
10320
10321                 /*
10322                  * Check if this is the first 'adv_sgblk_t' for the
10323                  * request.
10324                  */
10325                 if (reqp->sgblkp == NULL) {
10326                         /* Request's first scatter-gather block. */
10327                         reqp->sgblkp = sgblkp;
10328
10329                         /*
10330                          * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10331                          * address pointers.
10332                          */
10333                         scsiqp->sg_list_ptr = sg_block;
10334                         scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
10335                 } else {
10336                         /* Request's second or later scatter-gather block. */
10337                         sgblkp->next_sgblkp = reqp->sgblkp;
10338                         reqp->sgblkp = sgblkp;
10339
10340                         /*
10341                          * Point the previous ADV_SG_BLOCK structure to
10342                          * the newly allocated ADV_SG_BLOCK structure.
10343                          */
10344                         prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
10345                 }
10346
10347                 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
10348                         sg_block->sg_list[i].sg_addr =
10349                                         cpu_to_le32(sg_dma_address(slp));
10350                         sg_block->sg_list[i].sg_count =
10351                                         cpu_to_le32(sg_dma_len(slp));
10352                         ASC_STATS_ADD(scp->device->host, sg_xfer,
10353                                       ASC_CEILING(sg_dma_len(slp), 512));
10354
10355                         if (--sg_elem_cnt == 0) {       /* Last ADV_SG_BLOCK and scatter-gather entry. */
10356                                 sg_block->sg_cnt = i + 1;
10357                                 sg_block->sg_ptr = 0L;  /* Last ADV_SG_BLOCK in list. */
10358                                 return ADV_SUCCESS;
10359                         }
10360                         slp++;
10361                 }
10362                 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10363                 prev_sg_block = sg_block;
10364         }
10365 }
10366
10367 /*
10368  * Build a request structure for the Adv Library (Wide Board).
10369  *
10370  * If an adv_req_t can not be allocated to issue the request,
10371  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
10372  *
10373  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
10374  * microcode for DMA addresses or math operations are byte swapped
10375  * to little-endian order.
10376  */
10377 static int
10378 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
10379               ADV_SCSI_REQ_Q **adv_scsiqpp)
10380 {
10381         adv_req_t *reqp;
10382         ADV_SCSI_REQ_Q *scsiqp;
10383         int i;
10384         int ret;
10385
10386         /*
10387          * Allocate an adv_req_t structure from the board to execute
10388          * the command.
10389          */
10390         if (boardp->adv_reqp == NULL) {
10391                 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
10392                 ASC_STATS(scp->device->host, adv_build_noreq);
10393                 return ASC_BUSY;
10394         } else {
10395                 reqp = boardp->adv_reqp;
10396                 boardp->adv_reqp = reqp->next_reqp;
10397                 reqp->next_reqp = NULL;
10398         }
10399
10400         /*
10401          * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
10402          */
10403         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10404
10405         /*
10406          * Initialize the structure.
10407          */
10408         scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
10409
10410         /*
10411          * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
10412          */
10413         scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
10414
10415         /*
10416          * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
10417          */
10418         reqp->cmndp = scp;
10419
10420         /*
10421          * Build the ADV_SCSI_REQ_Q request.
10422          */
10423
10424         /* Set CDB length and copy it to the request structure.  */
10425         scsiqp->cdb_len = scp->cmd_len;
10426         /* Copy first 12 CDB bytes to cdb[]. */
10427         for (i = 0; i < scp->cmd_len && i < 12; i++) {
10428                 scsiqp->cdb[i] = scp->cmnd[i];
10429         }
10430         /* Copy last 4 CDB bytes, if present, to cdb16[]. */
10431         for (; i < scp->cmd_len; i++) {
10432                 scsiqp->cdb16[i - 12] = scp->cmnd[i];
10433         }
10434
10435         scsiqp->target_id = scp->device->id;
10436         scsiqp->target_lun = scp->device->lun;
10437
10438         scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10439         scsiqp->sense_len = sizeof(scp->sense_buffer);
10440
10441         /*
10442          * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
10443          * buffer command.
10444          */
10445
10446         scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10447         scsiqp->vdata_addr = scp->request_buffer;
10448         scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
10449
10450         if (scp->use_sg == 0) {
10451                 /*
10452                  * CDB request of single contiguous buffer.
10453                  */
10454                 reqp->sgblkp = NULL;
10455                 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
10456                 if (scp->request_bufflen) {
10457                         scsiqp->vdata_addr = scp->request_buffer;
10458                         scp->SCp.dma_handle =
10459                             dma_map_single(boardp->dev, scp->request_buffer,
10460                                            scp->request_bufflen,
10461                                            scp->sc_data_direction);
10462                 } else {
10463                         scsiqp->vdata_addr = NULL;
10464                         scp->SCp.dma_handle = 0;
10465                 }
10466                 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
10467                 scsiqp->sg_list_ptr = NULL;
10468                 scsiqp->sg_real_addr = 0;
10469                 ASC_STATS(scp->device->host, cont_cnt);
10470                 ASC_STATS_ADD(scp->device->host, cont_xfer,
10471                               ASC_CEILING(scp->request_bufflen, 512));
10472         } else {
10473                 /*
10474                  * CDB scatter-gather request list.
10475                  */
10476                 struct scatterlist *slp;
10477                 int use_sg;
10478
10479                 slp = (struct scatterlist *)scp->request_buffer;
10480                 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
10481                                     scp->sc_data_direction);
10482
10483                 if (use_sg > ADV_MAX_SG_LIST) {
10484                         ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
10485                                    "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
10486                                    scp->device->host->sg_tablesize);
10487                         dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10488                                      scp->sc_data_direction);
10489                         scp->result = HOST_BYTE(DID_ERROR);
10490
10491                         /*
10492                          * Free the 'adv_req_t' structure by adding it back
10493                          * to the board free list.
10494                          */
10495                         reqp->next_reqp = boardp->adv_reqp;
10496                         boardp->adv_reqp = reqp;
10497
10498                         return ASC_ERROR;
10499                 }
10500
10501                 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10502                 if (ret != ADV_SUCCESS) {
10503                         /*
10504                          * Free the adv_req_t structure by adding it back to
10505                          * the board free list.
10506                          */
10507                         reqp->next_reqp = boardp->adv_reqp;
10508                         boardp->adv_reqp = reqp;
10509
10510                         return ret;
10511                 }
10512
10513                 ASC_STATS(scp->device->host, sg_cnt);
10514                 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
10515         }
10516
10517         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10518         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10519
10520         *adv_scsiqpp = scsiqp;
10521
10522         return ASC_NOERROR;
10523 }
10524
10525 static int AscSgListToQueue(int sg_list)
10526 {
10527         int n_sg_list_qs;
10528
10529         n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10530         if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10531                 n_sg_list_qs++;
10532         return n_sg_list_qs + 1;
10533 }
10534
10535 static uint
10536 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10537 {
10538         uint cur_used_qs;
10539         uint cur_free_qs;
10540         ASC_SCSI_BIT_ID_TYPE target_id;
10541         uchar tid_no;
10542
10543         target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10544         tid_no = ASC_TIX_TO_TID(target_ix);
10545         if ((asc_dvc->unit_not_ready & target_id) ||
10546             (asc_dvc->queue_full_or_busy & target_id)) {
10547                 return 0;
10548         }
10549         if (n_qs == 1) {
10550                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10551                     (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
10552         } else {
10553                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
10554                     (uint) ASC_MIN_FREE_Q;
10555         }
10556         if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10557                 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10558                 if (asc_dvc->cur_dvc_qng[tid_no] >=
10559                     asc_dvc->max_dvc_qng[tid_no]) {
10560                         return 0;
10561                 }
10562                 return cur_free_qs;
10563         }
10564         if (n_qs > 1) {
10565                 if ((n_qs > asc_dvc->last_q_shortage)
10566                     && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10567                         asc_dvc->last_q_shortage = n_qs;
10568                 }
10569         }
10570         return 0;
10571 }
10572
10573 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10574 {
10575         ushort q_addr;
10576         uchar next_qp;
10577         uchar q_status;
10578
10579         q_addr = ASC_QNO_TO_QADDR(free_q_head);
10580         q_status = (uchar)AscReadLramByte(iop_base,
10581                                           (ushort)(q_addr +
10582                                                    ASC_SCSIQ_B_STATUS));
10583         next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10584         if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
10585                 return next_qp;
10586         return ASC_QLINK_END;
10587 }
10588
10589 static uchar
10590 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10591 {
10592         uchar i;
10593
10594         for (i = 0; i < n_free_q; i++) {
10595                 free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
10596                 if (free_q_head == ASC_QLINK_END)
10597                         break;
10598         }
10599         return free_q_head;
10600 }
10601
10602 /*
10603  * void
10604  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10605  *
10606  * Calling/Exit State:
10607  *    none
10608  *
10609  * Description:
10610  *     Output an ASC_SCSI_Q structure to the chip
10611  */
10612 static void
10613 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10614 {
10615         int i;
10616
10617         ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
10618         AscSetChipLramAddr(iop_base, s_addr);
10619         for (i = 0; i < 2 * words; i += 2) {
10620                 if (i == 4 || i == 20) {
10621                         continue;
10622                 }
10623                 outpw(iop_base + IOP_RAM_DATA,
10624                       ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
10625         }
10626 }
10627
10628 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10629 {
10630         ushort q_addr;
10631         uchar tid_no;
10632         uchar sdtr_data;
10633         uchar syn_period_ix;
10634         uchar syn_offset;
10635         PortAddr iop_base;
10636
10637         iop_base = asc_dvc->iop_base;
10638         if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10639             ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10640                 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10641                 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10642                 syn_period_ix =
10643                     (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
10644                 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
10645                 AscMsgOutSDTR(asc_dvc,
10646                               asc_dvc->sdtr_period_tbl[syn_period_ix],
10647                               syn_offset);
10648                 scsiq->q1.cntl |= QC_MSG_OUT;
10649         }
10650         q_addr = ASC_QNO_TO_QADDR(q_no);
10651         if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
10652                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10653         }
10654         scsiq->q1.status = QS_FREE;
10655         AscMemWordCopyPtrToLram(iop_base,
10656                                 q_addr + ASC_SCSIQ_CDB_BEG,
10657                                 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
10658
10659         DvcPutScsiQ(iop_base,
10660                     q_addr + ASC_SCSIQ_CPY_BEG,
10661                     (uchar *)&scsiq->q1.cntl,
10662                     ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
10663         AscWriteLramWord(iop_base,
10664                          (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
10665                          (ushort)(((ushort)scsiq->q1.
10666                                    q_no << 8) | (ushort)QS_READY));
10667         return 1;
10668 }
10669
10670 static int
10671 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10672 {
10673         int sta;
10674         int i;
10675         ASC_SG_HEAD *sg_head;
10676         ASC_SG_LIST_Q scsi_sg_q;
10677         ASC_DCNT saved_data_addr;
10678         ASC_DCNT saved_data_cnt;
10679         PortAddr iop_base;
10680         ushort sg_list_dwords;
10681         ushort sg_index;
10682         ushort sg_entry_cnt;
10683         ushort q_addr;
10684         uchar next_qp;
10685
10686         iop_base = asc_dvc->iop_base;
10687         sg_head = scsiq->sg_head;
10688         saved_data_addr = scsiq->q1.data_addr;
10689         saved_data_cnt = scsiq->q1.data_cnt;
10690         scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
10691         scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
10692 #if CC_VERY_LONG_SG_LIST
10693         /*
10694          * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
10695          * then not all SG elements will fit in the allocated queues.
10696          * The rest of the SG elements will be copied when the RISC
10697          * completes the SG elements that fit and halts.
10698          */
10699         if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10700                 /*
10701                  * Set sg_entry_cnt to be the number of SG elements that
10702                  * will fit in the allocated SG queues. It is minus 1, because
10703                  * the first SG element is handled above. ASC_MAX_SG_LIST is
10704                  * already inflated by 1 to account for this. For example it
10705                  * may be 50 which is 1 + 7 queues * 7 SG elements.
10706                  */
10707                 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10708
10709                 /*
10710                  * Keep track of remaining number of SG elements that will
10711                  * need to be handled from a_isr.c.
10712                  */
10713                 scsiq->remain_sg_entry_cnt =
10714                     sg_head->entry_cnt - ASC_MAX_SG_LIST;
10715         } else {
10716 #endif /* CC_VERY_LONG_SG_LIST */
10717                 /*
10718                  * Set sg_entry_cnt to be the number of SG elements that
10719                  * will fit in the allocated SG queues. It is minus 1, because
10720                  * the first SG element is handled above.
10721                  */
10722                 sg_entry_cnt = sg_head->entry_cnt - 1;
10723 #if CC_VERY_LONG_SG_LIST
10724         }
10725 #endif /* CC_VERY_LONG_SG_LIST */
10726         if (sg_entry_cnt != 0) {
10727                 scsiq->q1.cntl |= QC_SG_HEAD;
10728                 q_addr = ASC_QNO_TO_QADDR(q_no);
10729                 sg_index = 1;
10730                 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10731                 scsi_sg_q.sg_head_qp = q_no;
10732                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10733                 for (i = 0; i < sg_head->queue_cnt; i++) {
10734                         scsi_sg_q.seq_no = i + 1;
10735                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10736                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10737                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10738                                 if (i == 0) {
10739                                         scsi_sg_q.sg_list_cnt =
10740                                             ASC_SG_LIST_PER_Q;
10741                                         scsi_sg_q.sg_cur_list_cnt =
10742                                             ASC_SG_LIST_PER_Q;
10743                                 } else {
10744                                         scsi_sg_q.sg_list_cnt =
10745                                             ASC_SG_LIST_PER_Q - 1;
10746                                         scsi_sg_q.sg_cur_list_cnt =
10747                                             ASC_SG_LIST_PER_Q - 1;
10748                                 }
10749                         } else {
10750 #if CC_VERY_LONG_SG_LIST
10751                                 /*
10752                                  * This is the last SG queue in the list of
10753                                  * allocated SG queues. If there are more
10754                                  * SG elements than will fit in the allocated
10755                                  * queues, then set the QCSG_SG_XFER_MORE flag.
10756                                  */
10757                                 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10758                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10759                                 } else {
10760 #endif /* CC_VERY_LONG_SG_LIST */
10761                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10762 #if CC_VERY_LONG_SG_LIST
10763                                 }
10764 #endif /* CC_VERY_LONG_SG_LIST */
10765                                 sg_list_dwords = sg_entry_cnt << 1;
10766                                 if (i == 0) {
10767                                         scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10768                                         scsi_sg_q.sg_cur_list_cnt =
10769                                             sg_entry_cnt;
10770                                 } else {
10771                                         scsi_sg_q.sg_list_cnt =
10772                                             sg_entry_cnt - 1;
10773                                         scsi_sg_q.sg_cur_list_cnt =
10774                                             sg_entry_cnt - 1;
10775                                 }
10776                                 sg_entry_cnt = 0;
10777                         }
10778                         next_qp = AscReadLramByte(iop_base,
10779                                                   (ushort)(q_addr +
10780                                                            ASC_SCSIQ_B_FWD));
10781                         scsi_sg_q.q_no = next_qp;
10782                         q_addr = ASC_QNO_TO_QADDR(next_qp);
10783                         AscMemWordCopyPtrToLram(iop_base,
10784                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10785                                                 (uchar *)&scsi_sg_q,
10786                                                 sizeof(ASC_SG_LIST_Q) >> 1);
10787                         AscMemDWordCopyPtrToLram(iop_base,
10788                                                  q_addr + ASC_SGQ_LIST_BEG,
10789                                                  (uchar *)&sg_head->
10790                                                  sg_list[sg_index],
10791                                                  sg_list_dwords);
10792                         sg_index += ASC_SG_LIST_PER_Q;
10793                         scsiq->next_sg_index = sg_index;
10794                 }
10795         } else {
10796                 scsiq->q1.cntl &= ~QC_SG_HEAD;
10797         }
10798         sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10799         scsiq->q1.data_addr = saved_data_addr;
10800         scsiq->q1.data_cnt = saved_data_cnt;
10801         return (sta);
10802 }
10803
10804 static int
10805 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10806 {
10807         PortAddr iop_base;
10808         uchar free_q_head;
10809         uchar next_qp;
10810         uchar tid_no;
10811         uchar target_ix;
10812         int sta;
10813
10814         iop_base = asc_dvc->iop_base;
10815         target_ix = scsiq->q2.target_ix;
10816         tid_no = ASC_TIX_TO_TID(target_ix);
10817         sta = 0;
10818         free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
10819         if (n_q_required > 1) {
10820                 next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
10821                                                     (uchar)n_q_required);
10822                 if (next_qp != ASC_QLINK_END) {
10823                         asc_dvc->last_q_shortage = 0;
10824                         scsiq->sg_head->queue_cnt = n_q_required - 1;
10825                         scsiq->q1.q_no = free_q_head;
10826                         sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10827                                                      free_q_head);
10828                 }
10829         } else if (n_q_required == 1) {
10830                 next_qp = AscAllocFreeQueue(iop_base, free_q_head);
10831                 if (next_qp != ASC_QLINK_END) {
10832                         scsiq->q1.q_no = free_q_head;
10833                         sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
10834                 }
10835         }
10836         if (sta == 1) {
10837                 AscPutVarFreeQHead(iop_base, next_qp);
10838                 asc_dvc->cur_total_qng += n_q_required;
10839                 asc_dvc->cur_dvc_qng[tid_no]++;
10840         }
10841         return sta;
10842 }
10843
10844 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
10845 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
10846         INQUIRY,
10847         REQUEST_SENSE,
10848         READ_CAPACITY,
10849         READ_TOC,
10850         MODE_SELECT,
10851         MODE_SENSE,
10852         MODE_SELECT_10,
10853         MODE_SENSE_10,
10854         0xFF,
10855         0xFF,
10856         0xFF,
10857         0xFF,
10858         0xFF,
10859         0xFF,
10860         0xFF,
10861         0xFF
10862 };
10863
10864 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10865 {
10866         PortAddr iop_base;
10867         int sta;
10868         int n_q_required;
10869         int disable_syn_offset_one_fix;
10870         int i;
10871         ASC_PADDR addr;
10872         ushort sg_entry_cnt = 0;
10873         ushort sg_entry_cnt_minus_one = 0;
10874         uchar target_ix;
10875         uchar tid_no;
10876         uchar sdtr_data;
10877         uchar extra_bytes;
10878         uchar scsi_cmd;
10879         uchar disable_cmd;
10880         ASC_SG_HEAD *sg_head;
10881         ASC_DCNT data_cnt;
10882
10883         iop_base = asc_dvc->iop_base;
10884         sg_head = scsiq->sg_head;
10885         if (asc_dvc->err_code != 0)
10886                 return (ERR);
10887         scsiq->q1.q_no = 0;
10888         if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10889                 scsiq->q1.extra_bytes = 0;
10890         }
10891         sta = 0;
10892         target_ix = scsiq->q2.target_ix;
10893         tid_no = ASC_TIX_TO_TID(target_ix);
10894         n_q_required = 1;
10895         if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10896                 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10897                         asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10898                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10899                         AscMsgOutSDTR(asc_dvc,
10900                                       asc_dvc->
10901                                       sdtr_period_tbl[(sdtr_data >> 4) &
10902                                                       (uchar)(asc_dvc->
10903                                                               max_sdtr_index -
10904                                                               1)],
10905                                       (uchar)(sdtr_data & (uchar)
10906                                               ASC_SYN_MAX_OFFSET));
10907                         scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10908                 }
10909         }
10910         if (asc_dvc->in_critical_cnt != 0) {
10911                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10912                 return (ERR);
10913         }
10914         asc_dvc->in_critical_cnt++;
10915         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10916                 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10917                         asc_dvc->in_critical_cnt--;
10918                         return (ERR);
10919                 }
10920 #if !CC_VERY_LONG_SG_LIST
10921                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10922                         asc_dvc->in_critical_cnt--;
10923                         return (ERR);
10924                 }
10925 #endif /* !CC_VERY_LONG_SG_LIST */
10926                 if (sg_entry_cnt == 1) {
10927                         scsiq->q1.data_addr =
10928                             (ADV_PADDR)sg_head->sg_list[0].addr;
10929                         scsiq->q1.data_cnt =
10930                             (ADV_DCNT)sg_head->sg_list[0].bytes;
10931                         scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10932                 }
10933                 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10934         }
10935         scsi_cmd = scsiq->cdbptr[0];
10936         disable_syn_offset_one_fix = FALSE;
10937         if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10938             !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10939                 if (scsiq->q1.cntl & QC_SG_HEAD) {
10940                         data_cnt = 0;
10941                         for (i = 0; i < sg_entry_cnt; i++) {
10942                                 data_cnt +=
10943                                     (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
10944                                                           bytes);
10945                         }
10946                 } else {
10947                         data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10948                 }
10949                 if (data_cnt != 0UL) {
10950                         if (data_cnt < 512UL) {
10951                                 disable_syn_offset_one_fix = TRUE;
10952                         } else {
10953                                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
10954                                      i++) {
10955                                         disable_cmd =
10956                                             _syn_offset_one_disable_cmd[i];
10957                                         if (disable_cmd == 0xFF) {
10958                                                 break;
10959                                         }
10960                                         if (scsi_cmd == disable_cmd) {
10961                                                 disable_syn_offset_one_fix =
10962                                                     TRUE;
10963                                                 break;
10964                                         }
10965                                 }
10966                         }
10967                 }
10968         }
10969         if (disable_syn_offset_one_fix) {
10970                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10971                 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10972                                        ASC_TAG_FLAG_DISABLE_DISCONNECT);
10973         } else {
10974                 scsiq->q2.tag_code &= 0x27;
10975         }
10976         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10977                 if (asc_dvc->bug_fix_cntl) {
10978                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10979                                 if ((scsi_cmd == READ_6) ||
10980                                     (scsi_cmd == READ_10)) {
10981                                         addr =
10982                                             (ADV_PADDR)le32_to_cpu(sg_head->
10983                                                                    sg_list
10984                                                                    [sg_entry_cnt_minus_one].
10985                                                                    addr) +
10986                                             (ADV_DCNT)le32_to_cpu(sg_head->
10987                                                                   sg_list
10988                                                                   [sg_entry_cnt_minus_one].
10989                                                                   bytes);
10990                                         extra_bytes =
10991                                             (uchar)((ushort)addr & 0x0003);
10992                                         if ((extra_bytes != 0)
10993                                             &&
10994                                             ((scsiq->q2.
10995                                               tag_code &
10996                                               ASC_TAG_FLAG_EXTRA_BYTES)
10997                                              == 0)) {
10998                                                 scsiq->q2.tag_code |=
10999                                                     ASC_TAG_FLAG_EXTRA_BYTES;
11000                                                 scsiq->q1.extra_bytes =
11001                                                     extra_bytes;
11002                                                 data_cnt =
11003                                                     le32_to_cpu(sg_head->
11004                                                                 sg_list
11005                                                                 [sg_entry_cnt_minus_one].
11006                                                                 bytes);
11007                                                 data_cnt -=
11008                                                     (ASC_DCNT) extra_bytes;
11009                                                 sg_head->
11010                                                     sg_list
11011                                                     [sg_entry_cnt_minus_one].
11012                                                     bytes =
11013                                                     cpu_to_le32(data_cnt);
11014                                         }
11015                                 }
11016                         }
11017                 }
11018                 sg_head->entry_to_copy = sg_head->entry_cnt;
11019 #if CC_VERY_LONG_SG_LIST
11020                 /*
11021                  * Set the sg_entry_cnt to the maximum possible. The rest of
11022                  * the SG elements will be copied when the RISC completes the
11023                  * SG elements that fit and halts.
11024                  */
11025                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
11026                         sg_entry_cnt = ASC_MAX_SG_LIST;
11027                 }
11028 #endif /* CC_VERY_LONG_SG_LIST */
11029                 n_q_required = AscSgListToQueue(sg_entry_cnt);
11030                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11031                      (uint) n_q_required)
11032                     || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11033                         if ((sta =
11034                              AscSendScsiQueue(asc_dvc, scsiq,
11035                                               n_q_required)) == 1) {
11036                                 asc_dvc->in_critical_cnt--;
11037                                 return (sta);
11038                         }
11039                 }
11040         } else {
11041                 if (asc_dvc->bug_fix_cntl) {
11042                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11043                                 if ((scsi_cmd == READ_6) ||
11044                                     (scsi_cmd == READ_10)) {
11045                                         addr =
11046                                             le32_to_cpu(scsiq->q1.data_addr) +
11047                                             le32_to_cpu(scsiq->q1.data_cnt);
11048                                         extra_bytes =
11049                                             (uchar)((ushort)addr & 0x0003);
11050                                         if ((extra_bytes != 0)
11051                                             &&
11052                                             ((scsiq->q2.
11053                                               tag_code &
11054                                               ASC_TAG_FLAG_EXTRA_BYTES)
11055                                              == 0)) {
11056                                                 data_cnt =
11057                                                     le32_to_cpu(scsiq->q1.
11058                                                                 data_cnt);
11059                                                 if (((ushort)data_cnt & 0x01FF)
11060                                                     == 0) {
11061                                                         scsiq->q2.tag_code |=
11062                                                             ASC_TAG_FLAG_EXTRA_BYTES;
11063                                                         data_cnt -= (ASC_DCNT)
11064                                                             extra_bytes;
11065                                                         scsiq->q1.data_cnt =
11066                                                             cpu_to_le32
11067                                                             (data_cnt);
11068                                                         scsiq->q1.extra_bytes =
11069                                                             extra_bytes;
11070                                                 }
11071                                         }
11072                                 }
11073                         }
11074                 }
11075                 n_q_required = 1;
11076                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11077                     ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11078                         if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11079                                                     n_q_required)) == 1) {
11080                                 asc_dvc->in_critical_cnt--;
11081                                 return (sta);
11082                         }
11083                 }
11084         }
11085         asc_dvc->in_critical_cnt--;
11086         return (sta);
11087 }
11088
11089 /*
11090  * AdvExeScsiQueue() - Send a request to the RISC microcode program.
11091  *
11092  *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
11093  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
11094  *   RISC to notify it a new command is ready to be executed.
11095  *
11096  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
11097  * set to SCSI_MAX_RETRY.
11098  *
11099  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
11100  * for DMA addresses or math operations are byte swapped to little-endian
11101  * order.
11102  *
11103  * Return:
11104  *      ADV_SUCCESS(1) - The request was successfully queued.
11105  *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
11106  *                       request completes.
11107  *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
11108  *                       host IC error.
11109  */
11110 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
11111 {
11112         AdvPortAddr iop_base;
11113         ADV_DCNT req_size;
11114         ADV_PADDR req_paddr;
11115         ADV_CARR_T *new_carrp;
11116
11117         /*
11118          * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
11119          */
11120         if (scsiq->target_id > ADV_MAX_TID) {
11121                 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
11122                 scsiq->done_status = QD_WITH_ERROR;
11123                 return ADV_ERROR;
11124         }
11125
11126         iop_base = asc_dvc->iop_base;
11127
11128         /*
11129          * Allocate a carrier ensuring at least one carrier always
11130          * remains on the freelist and initialize fields.
11131          */
11132         if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
11133                 return ADV_BUSY;
11134         }
11135         asc_dvc->carr_freelist = (ADV_CARR_T *)
11136             ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
11137         asc_dvc->carr_pending_cnt++;
11138
11139         /*
11140          * Set the carrier to be a stopper by setting 'next_vpa'
11141          * to the stopper value. The current stopper will be changed
11142          * below to point to the new stopper.
11143          */
11144         new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
11145
11146         /*
11147          * Clear the ADV_SCSI_REQ_Q done flag.
11148          */
11149         scsiq->a_flag &= ~ADV_SCSIQ_DONE;
11150
11151         req_size = sizeof(ADV_SCSI_REQ_Q);
11152         req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
11153                                   (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
11154
11155         BUG_ON(req_paddr & 31);
11156         BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
11157
11158         /* Wait for assertion before making little-endian */
11159         req_paddr = cpu_to_le32(req_paddr);
11160
11161         /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
11162         scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
11163         scsiq->scsiq_rptr = req_paddr;
11164
11165         scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
11166         /*
11167          * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
11168          * order during initialization.
11169          */
11170         scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
11171
11172         /*
11173          * Use the current stopper to send the ADV_SCSI_REQ_Q command to
11174          * the microcode. The newly allocated stopper will become the new
11175          * stopper.
11176          */
11177         asc_dvc->icq_sp->areq_vpa = req_paddr;
11178
11179         /*
11180          * Set the 'next_vpa' pointer for the old stopper to be the
11181          * physical address of the new stopper. The RISC can only
11182          * follow physical addresses.
11183          */
11184         asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
11185
11186         /*
11187          * Set the host adapter stopper pointer to point to the new carrier.
11188          */
11189         asc_dvc->icq_sp = new_carrp;
11190
11191         if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
11192             asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
11193                 /*
11194                  * Tickle the RISC to tell it to read its Command Queue Head pointer.
11195                  */
11196                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
11197                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
11198                         /*
11199                          * Clear the tickle value. In the ASC-3550 the RISC flag
11200                          * command 'clr_tickle_a' does not work unless the host
11201                          * value is cleared.
11202                          */
11203                         AdvWriteByteRegister(iop_base, IOPB_TICKLE,
11204                                              ADV_TICKLE_NOP);
11205                 }
11206         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
11207                 /*
11208                  * Notify the RISC a carrier is ready by writing the physical
11209                  * address of the new carrier stopper to the COMMA register.
11210                  */
11211                 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
11212                                       le32_to_cpu(new_carrp->carr_pa));
11213         }
11214
11215         return ADV_SUCCESS;
11216 }
11217
11218 /*
11219  * Execute a single 'Scsi_Cmnd'.
11220  *
11221  * The function 'done' is called when the request has been completed.
11222  *
11223  * Scsi_Cmnd:
11224  *
11225  *  host - board controlling device
11226  *  device - device to send command
11227  *  target - target of device
11228  *  lun - lun of device
11229  *  cmd_len - length of SCSI CDB
11230  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
11231  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
11232  *
11233  *  if (use_sg == 0) {
11234  *    request_buffer - buffer address for request
11235  *    request_bufflen - length of request buffer
11236  *  } else {
11237  *    request_buffer - pointer to scatterlist structure
11238  *  }
11239  *
11240  *  sense_buffer - sense command buffer
11241  *
11242  *  result (4 bytes of an int):
11243  *    Byte Meaning
11244  *    0 SCSI Status Byte Code
11245  *    1 SCSI One Byte Message Code
11246  *    2 Host Error Code
11247  *    3 Mid-Level Error Code
11248  *
11249  *  host driver fields:
11250  *    SCp - Scsi_Pointer used for command processing status
11251  *    scsi_done - used to save caller's done function
11252  *    host_scribble - used for pointer to another struct scsi_cmnd
11253  *
11254  * If this function returns ASC_NOERROR the request will be completed
11255  * from the interrupt handler.
11256  *
11257  * If this function returns ASC_ERROR the host error code has been set,
11258  * and the called must call asc_scsi_done.
11259  *
11260  * If ASC_BUSY is returned the request will be returned to the midlayer
11261  * and re-tried later.
11262  */
11263 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
11264 {
11265         int ret, err_code;
11266         asc_board_t *boardp = ASC_BOARDP(scp->device->host);
11267
11268         ASC_DBG1(1, "asc_execute_scsi_cmnd: scp 0x%p\n", scp);
11269
11270         if (ASC_NARROW_BOARD(boardp)) {
11271                 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
11272                 struct asc_scsi_q asc_scsi_q;
11273
11274                 /* asc_build_req() can not return ASC_BUSY. */
11275                 ret = asc_build_req(boardp, scp, &asc_scsi_q);
11276                 if (ret == ASC_ERROR) {
11277                         ASC_STATS(scp->device->host, build_error);
11278                         return ASC_ERROR;
11279                 }
11280
11281                 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
11282                 kfree(asc_scsi_q.sg_head);
11283                 err_code = asc_dvc->err_code;
11284         } else {
11285                 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
11286                 ADV_SCSI_REQ_Q *adv_scsiqp;
11287
11288                 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
11289                 case ASC_NOERROR:
11290                         ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
11291                                 "ASC_NOERROR\n");
11292                         break;
11293                 case ASC_BUSY:
11294                         ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
11295                                 "ASC_BUSY\n");
11296                         /*
11297                          * The asc_stats fields 'adv_build_noreq' and
11298                          * 'adv_build_nosg' count wide board busy conditions.
11299                          * They are updated in adv_build_req and
11300                          * adv_get_sglist, respectively.
11301                          */
11302                         return ASC_BUSY;
11303                 case ASC_ERROR:
11304                 default:
11305                         ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
11306                                 "ASC_ERROR\n");
11307                         ASC_STATS(scp->device->host, build_error);
11308                         return ASC_ERROR;
11309                 }
11310
11311                 ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
11312                 err_code = adv_dvc->err_code;
11313         }
11314
11315         switch (ret) {
11316         case ASC_NOERROR:
11317                 ASC_STATS(scp->device->host, exe_noerror);
11318                 /*
11319                  * Increment monotonically increasing per device
11320                  * successful request counter. Wrapping doesn't matter.
11321                  */
11322                 boardp->reqcnt[scp->device->id]++;
11323                 ASC_DBG(1, "asc_execute_scsi_cmnd: ExeScsiQueue(), "
11324                         "ASC_NOERROR\n");
11325                 break;
11326         case ASC_BUSY:
11327                 ASC_STATS(scp->device->host, exe_busy);
11328                 break;
11329         case ASC_ERROR:
11330                 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11331                            "ASC_ERROR, err_code 0x%x\n", boardp->id, err_code);
11332                 ASC_STATS(scp->device->host, exe_error);
11333                 scp->result = HOST_BYTE(DID_ERROR);
11334                 break;
11335         default:
11336                 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() "
11337                            "unknown, err_code 0x%x\n", boardp->id, err_code);
11338                 ASC_STATS(scp->device->host, exe_unknown);
11339                 scp->result = HOST_BYTE(DID_ERROR);
11340                 break;
11341         }
11342
11343         ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
11344         return ret;
11345 }
11346
11347 /*
11348  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11349  *
11350  * This function always returns 0. Command return status is saved
11351  * in the 'scp' result field.
11352  */
11353 static int
11354 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11355 {
11356         struct Scsi_Host *shost = scp->device->host;
11357         asc_board_t *boardp = ASC_BOARDP(shost);
11358         unsigned long flags;
11359         int asc_res, result = 0;
11360
11361         ASC_STATS(shost, queuecommand);
11362         scp->scsi_done = done;
11363
11364         /*
11365          * host_lock taken by mid-level prior to call, but need
11366          * to protect against own ISR
11367          */
11368         spin_lock_irqsave(&boardp->lock, flags);
11369         asc_res = asc_execute_scsi_cmnd(scp);
11370         spin_unlock_irqrestore(&boardp->lock, flags);
11371
11372         switch (asc_res) {
11373         case ASC_NOERROR:
11374                 break;
11375         case ASC_BUSY:
11376                 result = SCSI_MLQUEUE_HOST_BUSY;
11377                 break;
11378         case ASC_ERROR:
11379         default:
11380                 asc_scsi_done(scp);
11381                 break;
11382         }
11383
11384         return result;
11385 }
11386
11387 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11388 {
11389         PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11390             (PortAddr) (ASC_EISA_CFG_IOP_MASK);
11391         return inpw(eisa_cfg_iop);
11392 }
11393
11394 /*
11395  * Return the BIOS address of the adapter at the specified
11396  * I/O port and with the specified bus type.
11397  */
11398 static unsigned short __devinit
11399 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11400 {
11401         unsigned short cfg_lsw;
11402         unsigned short bios_addr;
11403
11404         /*
11405          * The PCI BIOS is re-located by the motherboard BIOS. Because
11406          * of this the driver can not determine where a PCI BIOS is
11407          * loaded and executes.
11408          */
11409         if (bus_type & ASC_IS_PCI)
11410                 return 0;
11411
11412         if ((bus_type & ASC_IS_EISA) != 0) {
11413                 cfg_lsw = AscGetEisaChipCfg(iop_base);
11414                 cfg_lsw &= 0x000F;
11415                 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
11416                 return bios_addr;
11417         }
11418
11419         cfg_lsw = AscGetChipCfgLsw(iop_base);
11420
11421         /*
11422          *  ISA PnP uses the top bit as the 32K BIOS flag
11423          */
11424         if (bus_type == ASC_IS_ISAPNP)
11425                 cfg_lsw &= 0x7FFF;
11426         bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
11427         return bios_addr;
11428 }
11429
11430 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11431 {
11432         ushort cfg_lsw;
11433
11434         if (AscGetChipScsiID(iop_base) == new_host_id) {
11435                 return (new_host_id);
11436         }
11437         cfg_lsw = AscGetChipCfgLsw(iop_base);
11438         cfg_lsw &= 0xF8FF;
11439         cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
11440         AscSetChipCfgLsw(iop_base, cfg_lsw);
11441         return (AscGetChipScsiID(iop_base));
11442 }
11443
11444 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11445 {
11446         unsigned char sc;
11447
11448         AscSetBank(iop_base, 1);
11449         sc = inp(iop_base + IOP_REG_SC);
11450         AscSetBank(iop_base, 0);
11451         return sc;
11452 }
11453
11454 static unsigned char __devinit
11455 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11456 {
11457         if (bus_type & ASC_IS_EISA) {
11458                 PortAddr eisa_iop;
11459                 unsigned char revision;
11460                 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11461                     (PortAddr) ASC_EISA_REV_IOP_MASK;
11462                 revision = inp(eisa_iop);
11463                 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
11464         }
11465         return AscGetChipVerNo(iop_base);
11466 }
11467
11468 #ifdef CONFIG_ISA
11469 static void __devinit AscEnableIsaDma(uchar dma_channel)
11470 {
11471         if (dma_channel < 4) {
11472                 outp(0x000B, (ushort)(0xC0 | dma_channel));
11473                 outp(0x000A, dma_channel);
11474         } else if (dma_channel < 8) {
11475                 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
11476                 outp(0x00D4, (ushort)(dma_channel - 4));
11477         }
11478         return;
11479 }
11480 #endif /* CONFIG_ISA */
11481
11482 static int AscStopQueueExe(PortAddr iop_base)
11483 {
11484         int count = 0;
11485
11486         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11487                 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11488                                  ASC_STOP_REQ_RISC_STOP);
11489                 do {
11490                         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11491                             ASC_STOP_ACK_RISC_STOP) {
11492                                 return (1);
11493                         }
11494                         mdelay(100);
11495                 } while (count++ < 20);
11496         }
11497         return (0);
11498 }
11499
11500 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11501 {
11502         if (bus_type & ASC_IS_ISA)
11503                 return ASC_MAX_ISA_DMA_COUNT;
11504         else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11505                 return ASC_MAX_VL_DMA_COUNT;
11506         return ASC_MAX_PCI_DMA_COUNT;
11507 }
11508
11509 #ifdef CONFIG_ISA
11510 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
11511 {
11512         ushort channel;
11513
11514         channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11515         if (channel == 0x03)
11516                 return (0);
11517         else if (channel == 0x00)
11518                 return (7);
11519         return (channel + 4);
11520 }
11521
11522 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11523 {
11524         ushort cfg_lsw;
11525         uchar value;
11526
11527         if ((dma_channel >= 5) && (dma_channel <= 7)) {
11528                 if (dma_channel == 7)
11529                         value = 0x00;
11530                 else
11531                         value = dma_channel - 4;
11532                 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11533                 cfg_lsw |= value;
11534                 AscSetChipCfgLsw(iop_base, cfg_lsw);
11535                 return (AscGetIsaDmaChannel(iop_base));
11536         }
11537         return 0;
11538 }
11539
11540 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11541 {
11542         uchar speed_value;
11543
11544         AscSetBank(iop_base, 1);
11545         speed_value = AscReadChipDmaSpeed(iop_base);
11546         speed_value &= 0x07;
11547         AscSetBank(iop_base, 0);
11548         return speed_value;
11549 }
11550
11551 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11552 {
11553         speed_value &= 0x07;
11554         AscSetBank(iop_base, 1);
11555         AscWriteChipDmaSpeed(iop_base, speed_value);
11556         AscSetBank(iop_base, 0);
11557         return AscGetIsaDmaSpeed(iop_base);
11558 }
11559 #endif /* CONFIG_ISA */
11560
11561 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11562 {
11563         int i;
11564         PortAddr iop_base;
11565         ushort warn_code;
11566         uchar chip_version;
11567
11568         iop_base = asc_dvc->iop_base;
11569         warn_code = 0;
11570         asc_dvc->err_code = 0;
11571         if ((asc_dvc->bus_type &
11572              (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
11573                 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
11574         }
11575         AscSetChipControl(iop_base, CC_HALT);
11576         AscSetChipStatus(iop_base, 0);
11577         asc_dvc->bug_fix_cntl = 0;
11578         asc_dvc->pci_fix_asyn_xfer = 0;
11579         asc_dvc->pci_fix_asyn_xfer_always = 0;
11580         /* asc_dvc->init_state initalized in AscInitGetConfig(). */
11581         asc_dvc->sdtr_done = 0;
11582         asc_dvc->cur_total_qng = 0;
11583         asc_dvc->is_in_int = 0;
11584         asc_dvc->in_critical_cnt = 0;
11585         asc_dvc->last_q_shortage = 0;
11586         asc_dvc->use_tagged_qng = 0;
11587         asc_dvc->no_scam = 0;
11588         asc_dvc->unit_not_ready = 0;
11589         asc_dvc->queue_full_or_busy = 0;
11590         asc_dvc->redo_scam = 0;
11591         asc_dvc->res2 = 0;
11592         asc_dvc->host_init_sdtr_index = 0;
11593         asc_dvc->cfg->can_tagged_qng = 0;
11594         asc_dvc->cfg->cmd_qng_enabled = 0;
11595         asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
11596         asc_dvc->init_sdtr = 0;
11597         asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
11598         asc_dvc->scsi_reset_wait = 3;
11599         asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
11600         asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
11601         asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
11602         asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
11603         asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
11604         asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
11605         asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
11606             ASC_LIB_VERSION_MINOR;
11607         chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11608         asc_dvc->cfg->chip_version = chip_version;
11609         asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
11610         asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
11611         asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
11612         asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
11613         asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
11614         asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
11615         asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
11616         asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
11617         asc_dvc->max_sdtr_index = 7;
11618         if ((asc_dvc->bus_type & ASC_IS_PCI) &&
11619             (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
11620                 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
11621                 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
11622                 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
11623                 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
11624                 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
11625                 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
11626                 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
11627                 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
11628                 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
11629                 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
11630                 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
11631                 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
11632                 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
11633                 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
11634                 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
11635                 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
11636                 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
11637                 asc_dvc->max_sdtr_index = 15;
11638                 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
11639                         AscSetExtraControl(iop_base,
11640                                            (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11641                 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
11642                         AscSetExtraControl(iop_base,
11643                                            (SEC_ACTIVE_NEGATE |
11644                                             SEC_ENABLE_FILTER));
11645                 }
11646         }
11647         if (asc_dvc->bus_type == ASC_IS_PCI) {
11648                 AscSetExtraControl(iop_base,
11649                                    (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11650         }
11651
11652         asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
11653 #ifdef CONFIG_ISA
11654         if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
11655                 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
11656                         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
11657                         asc_dvc->bus_type = ASC_IS_ISAPNP;
11658                 }
11659                 asc_dvc->cfg->isa_dma_channel =
11660                     (uchar)AscGetIsaDmaChannel(iop_base);
11661         }
11662 #endif /* CONFIG_ISA */
11663         for (i = 0; i <= ASC_MAX_TID; i++) {
11664                 asc_dvc->cur_dvc_qng[i] = 0;
11665                 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
11666                 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
11667                 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
11668                 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
11669         }
11670         return warn_code;
11671 }
11672
11673 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11674 {
11675         int retry;
11676
11677         for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
11678                 unsigned char read_back;
11679                 AscSetChipEEPCmd(iop_base, cmd_reg);
11680                 mdelay(1);
11681                 read_back = AscGetChipEEPCmd(iop_base);
11682                 if (read_back == cmd_reg)
11683                         return 1;
11684         }
11685         return 0;
11686 }
11687
11688 static void __devinit AscWaitEEPRead(void)
11689 {
11690         mdelay(1);
11691 }
11692
11693 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
11694 {
11695         ushort read_wval;
11696         uchar cmd_reg;
11697
11698         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11699         AscWaitEEPRead();
11700         cmd_reg = addr | ASC_EEP_CMD_READ;
11701         AscWriteEEPCmdReg(iop_base, cmd_reg);
11702         AscWaitEEPRead();
11703         read_wval = AscGetChipEEPData(iop_base);
11704         AscWaitEEPRead();
11705         return read_wval;
11706 }
11707
11708 static ushort __devinit
11709 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11710 {
11711         ushort wval;
11712         ushort sum;
11713         ushort *wbuf;
11714         int cfg_beg;
11715         int cfg_end;
11716         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11717         int s_addr;
11718
11719         wbuf = (ushort *)cfg_buf;
11720         sum = 0;
11721         /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11722         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11723                 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11724                 sum += *wbuf;
11725         }
11726         if (bus_type & ASC_IS_VL) {
11727                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11728                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11729         } else {
11730                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11731                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11732         }
11733         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11734                 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11735                 if (s_addr <= uchar_end_in_config) {
11736                         /*
11737                          * Swap all char fields - must unswap bytes already swapped
11738                          * by AscReadEEPWord().
11739                          */
11740                         *wbuf = le16_to_cpu(wval);
11741                 } else {
11742                         /* Don't swap word field at the end - cntl field. */
11743                         *wbuf = wval;
11744                 }
11745                 sum += wval;    /* Checksum treats all EEPROM data as words. */
11746         }
11747         /*
11748          * Read the checksum word which will be compared against 'sum'
11749          * by the caller. Word field already swapped.
11750          */
11751         *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11752         return sum;
11753 }
11754
11755 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11756 {
11757         PortAddr iop_base;
11758         ushort q_addr;
11759         ushort saved_word;
11760         int sta;
11761
11762         iop_base = asc_dvc->iop_base;
11763         sta = 0;
11764         q_addr = ASC_QNO_TO_QADDR(241);
11765         saved_word = AscReadLramWord(iop_base, q_addr);
11766         AscSetChipLramAddr(iop_base, q_addr);
11767         AscSetChipLramData(iop_base, 0x55AA);
11768         mdelay(10);
11769         AscSetChipLramAddr(iop_base, q_addr);
11770         if (AscGetChipLramData(iop_base) == 0x55AA) {
11771                 sta = 1;
11772                 AscWriteLramWord(iop_base, q_addr, saved_word);
11773         }
11774         return (sta);
11775 }
11776
11777 static void __devinit AscWaitEEPWrite(void)
11778 {
11779         mdelay(20);
11780         return;
11781 }
11782
11783 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11784 {
11785         ushort read_back;
11786         int retry;
11787
11788         retry = 0;
11789         while (TRUE) {
11790                 AscSetChipEEPData(iop_base, data_reg);
11791                 mdelay(1);
11792                 read_back = AscGetChipEEPData(iop_base);
11793                 if (read_back == data_reg) {
11794                         return (1);
11795                 }
11796                 if (retry++ > ASC_EEP_MAX_RETRY) {
11797                         return (0);
11798                 }
11799         }
11800 }
11801
11802 static ushort __devinit
11803 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11804 {
11805         ushort read_wval;
11806
11807         read_wval = AscReadEEPWord(iop_base, addr);
11808         if (read_wval != word_val) {
11809                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11810                 AscWaitEEPRead();
11811                 AscWriteEEPDataReg(iop_base, word_val);
11812                 AscWaitEEPRead();
11813                 AscWriteEEPCmdReg(iop_base,
11814                                   (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11815                 AscWaitEEPWrite();
11816                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11817                 AscWaitEEPRead();
11818                 return (AscReadEEPWord(iop_base, addr));
11819         }
11820         return (read_wval);
11821 }
11822
11823 static int __devinit
11824 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11825 {
11826         int n_error;
11827         ushort *wbuf;
11828         ushort word;
11829         ushort sum;
11830         int s_addr;
11831         int cfg_beg;
11832         int cfg_end;
11833         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11834
11835         wbuf = (ushort *)cfg_buf;
11836         n_error = 0;
11837         sum = 0;
11838         /* Write two config words; AscWriteEEPWord() will swap bytes. */
11839         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11840                 sum += *wbuf;
11841                 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11842                         n_error++;
11843                 }
11844         }
11845         if (bus_type & ASC_IS_VL) {
11846                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11847                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11848         } else {
11849                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11850                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11851         }
11852         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11853                 if (s_addr <= uchar_end_in_config) {
11854                         /*
11855                          * This is a char field. Swap char fields before they are
11856                          * swapped again by AscWriteEEPWord().
11857                          */
11858                         word = cpu_to_le16(*wbuf);
11859                         if (word !=
11860                             AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11861                                 n_error++;
11862                         }
11863                 } else {
11864                         /* Don't swap word field at the end - cntl field. */
11865                         if (*wbuf !=
11866                             AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11867                                 n_error++;
11868                         }
11869                 }
11870                 sum += *wbuf;   /* Checksum calculated from word values. */
11871         }
11872         /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11873         *wbuf = sum;
11874         if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11875                 n_error++;
11876         }
11877
11878         /* Read EEPROM back again. */
11879         wbuf = (ushort *)cfg_buf;
11880         /*
11881          * Read two config words; Byte-swapping done by AscReadEEPWord().
11882          */
11883         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11884                 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11885                         n_error++;
11886                 }
11887         }
11888         if (bus_type & ASC_IS_VL) {
11889                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11890                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11891         } else {
11892                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11893                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11894         }
11895         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11896                 if (s_addr <= uchar_end_in_config) {
11897                         /*
11898                          * Swap all char fields. Must unswap bytes already swapped
11899                          * by AscReadEEPWord().
11900                          */
11901                         word =
11902                             le16_to_cpu(AscReadEEPWord
11903                                         (iop_base, (uchar)s_addr));
11904                 } else {
11905                         /* Don't swap word field at the end - cntl field. */
11906                         word = AscReadEEPWord(iop_base, (uchar)s_addr);
11907                 }
11908                 if (*wbuf != word) {
11909                         n_error++;
11910                 }
11911         }
11912         /* Read checksum; Byte swapping not needed. */
11913         if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11914                 n_error++;
11915         }
11916         return n_error;
11917 }
11918
11919 static int __devinit
11920 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11921 {
11922         int retry;
11923         int n_error;
11924
11925         retry = 0;
11926         while (TRUE) {
11927                 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11928                                                    bus_type)) == 0) {
11929                         break;
11930                 }
11931                 if (++retry > ASC_EEP_MAX_RETRY) {
11932                         break;
11933                 }
11934         }
11935         return n_error;
11936 }
11937
11938 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
11939 {
11940         ASCEEP_CONFIG eep_config_buf;
11941         ASCEEP_CONFIG *eep_config;
11942         PortAddr iop_base;
11943         ushort chksum;
11944         ushort warn_code;
11945         ushort cfg_msw, cfg_lsw;
11946         int i;
11947         int write_eep = 0;
11948
11949         iop_base = asc_dvc->iop_base;
11950         warn_code = 0;
11951         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
11952         AscStopQueueExe(iop_base);
11953         if ((AscStopChip(iop_base) == FALSE) ||
11954             (AscGetChipScsiCtrl(iop_base) != 0)) {
11955                 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
11956                 AscResetChipAndScsiBus(asc_dvc);
11957                 mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
11958         }
11959         if (AscIsChipHalted(iop_base) == FALSE) {
11960                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11961                 return (warn_code);
11962         }
11963         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11964         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11965                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11966                 return (warn_code);
11967         }
11968         eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
11969         cfg_msw = AscGetChipCfgMsw(iop_base);
11970         cfg_lsw = AscGetChipCfgLsw(iop_base);
11971         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11972                 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11973                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11974                 AscSetChipCfgMsw(iop_base, cfg_msw);
11975         }
11976         chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
11977         ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
11978         if (chksum == 0) {
11979                 chksum = 0xaa55;
11980         }
11981         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11982                 warn_code |= ASC_WARN_AUTO_CONFIG;
11983                 if (asc_dvc->cfg->chip_version == 3) {
11984                         if (eep_config->cfg_lsw != cfg_lsw) {
11985                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
11986                                 eep_config->cfg_lsw =
11987                                     AscGetChipCfgLsw(iop_base);
11988                         }
11989                         if (eep_config->cfg_msw != cfg_msw) {
11990                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
11991                                 eep_config->cfg_msw =
11992                                     AscGetChipCfgMsw(iop_base);
11993                         }
11994                 }
11995         }
11996         eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11997         eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
11998         ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
11999                  eep_config->chksum);
12000         if (chksum != eep_config->chksum) {
12001                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12002                     ASC_CHIP_VER_PCI_ULTRA_3050) {
12003                         ASC_DBG(1,
12004                                 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12005                         eep_config->init_sdtr = 0xFF;
12006                         eep_config->disc_enable = 0xFF;
12007                         eep_config->start_motor = 0xFF;
12008                         eep_config->use_cmd_qng = 0;
12009                         eep_config->max_total_qng = 0xF0;
12010                         eep_config->max_tag_qng = 0x20;
12011                         eep_config->cntl = 0xBFFF;
12012                         ASC_EEP_SET_CHIP_ID(eep_config, 7);
12013                         eep_config->no_scam = 0;
12014                         eep_config->adapter_info[0] = 0;
12015                         eep_config->adapter_info[1] = 0;
12016                         eep_config->adapter_info[2] = 0;
12017                         eep_config->adapter_info[3] = 0;
12018                         eep_config->adapter_info[4] = 0;
12019                         /* Indicate EEPROM-less board. */
12020                         eep_config->adapter_info[5] = 0xBB;
12021                 } else {
12022                         ASC_PRINT
12023                             ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12024                         write_eep = 1;
12025                         warn_code |= ASC_WARN_EEPROM_CHKSUM;
12026                 }
12027         }
12028         asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12029         asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12030         asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12031         asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12032         asc_dvc->start_motor = eep_config->start_motor;
12033         asc_dvc->dvc_cntl = eep_config->cntl;
12034         asc_dvc->no_scam = eep_config->no_scam;
12035         asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12036         asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12037         asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12038         asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12039         asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12040         asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12041         if (!AscTestExternalLram(asc_dvc)) {
12042                 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
12043                      ASC_IS_PCI_ULTRA)) {
12044                         eep_config->max_total_qng =
12045                             ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12046                         eep_config->max_tag_qng =
12047                             ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12048                 } else {
12049                         eep_config->cfg_msw |= 0x0800;
12050                         cfg_msw |= 0x0800;
12051                         AscSetChipCfgMsw(iop_base, cfg_msw);
12052                         eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12053                         eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12054                 }
12055         } else {
12056         }
12057         if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12058                 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12059         }
12060         if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12061                 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12062         }
12063         if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12064                 eep_config->max_tag_qng = eep_config->max_total_qng;
12065         }
12066         if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12067                 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12068         }
12069         asc_dvc->max_total_qng = eep_config->max_total_qng;
12070         if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12071             eep_config->use_cmd_qng) {
12072                 eep_config->disc_enable = eep_config->use_cmd_qng;
12073                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12074         }
12075         ASC_EEP_SET_CHIP_ID(eep_config,
12076                             ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12077         asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12078         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12079             !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12080                 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12081         }
12082
12083         for (i = 0; i <= ASC_MAX_TID; i++) {
12084                 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12085                 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12086                 asc_dvc->cfg->sdtr_period_offset[i] =
12087                     (uchar)(ASC_DEF_SDTR_OFFSET |
12088                             (asc_dvc->host_init_sdtr_index << 4));
12089         }
12090         eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12091         if (write_eep) {
12092                 if ((i = AscSetEEPConfig(iop_base, eep_config,
12093                                      asc_dvc->bus_type)) != 0) {
12094                         ASC_PRINT1
12095                             ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
12096                              i);
12097                 } else {
12098                         ASC_PRINT
12099                             ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
12100                 }
12101         }
12102         return (warn_code);
12103 }
12104
12105 static int __devinit AscInitGetConfig(asc_board_t *boardp)
12106 {
12107         ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
12108         unsigned short warn_code = 0;
12109
12110         asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
12111         if (asc_dvc->err_code != 0)
12112                 return asc_dvc->err_code;
12113
12114         if (AscFindSignature(asc_dvc->iop_base)) {
12115                 warn_code |= AscInitAscDvcVar(asc_dvc);
12116                 warn_code |= AscInitFromEEP(asc_dvc);
12117                 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
12118                 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
12119                         asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
12120         } else {
12121                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12122         }
12123
12124         switch (warn_code) {
12125         case 0: /* No error */
12126                 break;
12127         case ASC_WARN_IO_PORT_ROTATE:
12128                 ASC_PRINT1("AscInitGetConfig: board %d: I/O port address "
12129                            "modified\n", boardp->id);
12130                 break;
12131         case ASC_WARN_AUTO_CONFIG:
12132                 ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment "
12133                            "switch enabled\n", boardp->id);
12134                 break;
12135         case ASC_WARN_EEPROM_CHKSUM:
12136                 ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum "
12137                            "error\n", boardp->id);
12138                 break;
12139         case ASC_WARN_IRQ_MODIFIED:
12140                 ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n",
12141                            boardp->id);
12142                 break;
12143         case ASC_WARN_CMD_QNG_CONFLICT:
12144                 ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled "
12145                            "w/o disconnects\n", boardp->id);
12146                 break;
12147         default:
12148                 ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: "
12149                            "0x%x\n", boardp->id, warn_code);
12150                 break;
12151         }
12152
12153         if (asc_dvc->err_code != 0) {
12154                 ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, "
12155                            "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12156                            asc_dvc->err_code);
12157         }
12158
12159         return asc_dvc->err_code;
12160 }
12161
12162 static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp)
12163 {
12164         ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
12165         PortAddr iop_base = asc_dvc->iop_base;
12166         unsigned short cfg_msw;
12167         unsigned short warn_code = 0;
12168
12169         asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12170         if (asc_dvc->err_code != 0)
12171                 return asc_dvc->err_code;
12172         if (!AscFindSignature(asc_dvc->iop_base)) {
12173                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12174                 return asc_dvc->err_code;
12175         }
12176
12177         cfg_msw = AscGetChipCfgMsw(iop_base);
12178         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12179                 cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12180                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12181                 AscSetChipCfgMsw(iop_base, cfg_msw);
12182         }
12183         if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12184             asc_dvc->cfg->cmd_qng_enabled) {
12185                 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12186                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12187         }
12188         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12189                 warn_code |= ASC_WARN_AUTO_CONFIG;
12190         }
12191 #ifdef CONFIG_PCI
12192         if (asc_dvc->bus_type & ASC_IS_PCI) {
12193                 cfg_msw &= 0xFFC0;
12194                 AscSetChipCfgMsw(iop_base, cfg_msw);
12195                 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12196                 } else {
12197                         if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
12198                             (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
12199                                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12200                                 asc_dvc->bug_fix_cntl |=
12201                                     ASC_BUG_FIX_ASYN_USE_SYN;
12202                         }
12203                 }
12204         } else
12205 #endif /* CONFIG_PCI */
12206         if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12207                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12208                     == ASC_CHIP_VER_ASYN_BUG) {
12209                         asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12210                 }
12211         }
12212         if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12213             asc_dvc->cfg->chip_scsi_id) {
12214                 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12215         }
12216 #ifdef CONFIG_ISA
12217         if (asc_dvc->bus_type & ASC_IS_ISA) {
12218                 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12219                 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12220         }
12221 #endif /* CONFIG_ISA */
12222
12223         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12224
12225         switch (warn_code) {
12226         case 0: /* No error. */
12227                 break;
12228         case ASC_WARN_IO_PORT_ROTATE:
12229                 ASC_PRINT1("AscInitSetConfig: board %d: I/O port address "
12230                            "modified\n", boardp->id);
12231                 break;
12232         case ASC_WARN_AUTO_CONFIG:
12233                 ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment "
12234                            "switch enabled\n", boardp->id);
12235                 break;
12236         case ASC_WARN_EEPROM_CHKSUM:
12237                 ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum "
12238                            "error\n", boardp->id);
12239                 break;
12240         case ASC_WARN_IRQ_MODIFIED:
12241                 ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n",
12242                            boardp->id);
12243                 break;
12244         case ASC_WARN_CMD_QNG_CONFLICT:
12245                 ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o "
12246                            "disconnects\n",
12247                      boardp->id);
12248                 break;
12249         default:
12250                 ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: "
12251                            "0x%x\n", boardp->id, warn_code);
12252                 break;
12253         }
12254
12255         if (asc_dvc->err_code != 0) {
12256                 ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, "
12257                            "err_code 0x%x\n", boardp->id, asc_dvc->init_state,
12258                            asc_dvc->err_code);
12259         }
12260
12261         return asc_dvc->err_code;
12262 }
12263
12264 /*
12265  * EEPROM Configuration.
12266  *
12267  * All drivers should use this structure to set the default EEPROM
12268  * configuration. The BIOS now uses this structure when it is built.
12269  * Additional structure information can be found in a_condor.h where
12270  * the structure is defined.
12271  *
12272  * The *_Field_IsChar structs are needed to correct for endianness.
12273  * These values are read from the board 16 bits at a time directly
12274  * into the structs. Because some fields are char, the values will be
12275  * in the wrong order. The *_Field_IsChar tells when to flip the
12276  * bytes. Data read and written to PCI memory is automatically swapped
12277  * on big-endian platforms so char fields read as words are actually being
12278  * unswapped on big-endian platforms.
12279  */
12280 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
12281         ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
12282         0x0000,                 /* cfg_msw */
12283         0xFFFF,                 /* disc_enable */
12284         0xFFFF,                 /* wdtr_able */
12285         0xFFFF,                 /* sdtr_able */
12286         0xFFFF,                 /* start_motor */
12287         0xFFFF,                 /* tagqng_able */
12288         0xFFFF,                 /* bios_scan */
12289         0,                      /* scam_tolerant */
12290         7,                      /* adapter_scsi_id */
12291         0,                      /* bios_boot_delay */
12292         3,                      /* scsi_reset_delay */
12293         0,                      /* bios_id_lun */
12294         0,                      /* termination */
12295         0,                      /* reserved1 */
12296         0xFFE7,                 /* bios_ctrl */
12297         0xFFFF,                 /* ultra_able */
12298         0,                      /* reserved2 */
12299         ASC_DEF_MAX_HOST_QNG,   /* max_host_qng */
12300         ASC_DEF_MAX_DVC_QNG,    /* max_dvc_qng */
12301         0,                      /* dvc_cntl */
12302         0,                      /* bug_fix */
12303         0,                      /* serial_number_word1 */
12304         0,                      /* serial_number_word2 */
12305         0,                      /* serial_number_word3 */
12306         0,                      /* check_sum */
12307         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12308         ,                       /* oem_name[16] */
12309         0,                      /* dvc_err_code */
12310         0,                      /* adv_err_code */
12311         0,                      /* adv_err_addr */
12312         0,                      /* saved_dvc_err_code */
12313         0,                      /* saved_adv_err_code */
12314         0,                      /* saved_adv_err_addr */
12315         0                       /* num_of_err */
12316 };
12317
12318 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
12319         0,                      /* cfg_lsw */
12320         0,                      /* cfg_msw */
12321         0,                      /* -disc_enable */
12322         0,                      /* wdtr_able */
12323         0,                      /* sdtr_able */
12324         0,                      /* start_motor */
12325         0,                      /* tagqng_able */
12326         0,                      /* bios_scan */
12327         0,                      /* scam_tolerant */
12328         1,                      /* adapter_scsi_id */
12329         1,                      /* bios_boot_delay */
12330         1,                      /* scsi_reset_delay */
12331         1,                      /* bios_id_lun */
12332         1,                      /* termination */
12333         1,                      /* reserved1 */
12334         0,                      /* bios_ctrl */
12335         0,                      /* ultra_able */
12336         0,                      /* reserved2 */
12337         1,                      /* max_host_qng */
12338         1,                      /* max_dvc_qng */
12339         0,                      /* dvc_cntl */
12340         0,                      /* bug_fix */
12341         0,                      /* serial_number_word1 */
12342         0,                      /* serial_number_word2 */
12343         0,                      /* serial_number_word3 */
12344         0,                      /* check_sum */
12345         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12346         ,                       /* oem_name[16] */
12347         0,                      /* dvc_err_code */
12348         0,                      /* adv_err_code */
12349         0,                      /* adv_err_addr */
12350         0,                      /* saved_dvc_err_code */
12351         0,                      /* saved_adv_err_code */
12352         0,                      /* saved_adv_err_addr */
12353         0                       /* num_of_err */
12354 };
12355
12356 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
12357         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12358         0x0000,                 /* 01 cfg_msw */
12359         0xFFFF,                 /* 02 disc_enable */
12360         0xFFFF,                 /* 03 wdtr_able */
12361         0x4444,                 /* 04 sdtr_speed1 */
12362         0xFFFF,                 /* 05 start_motor */
12363         0xFFFF,                 /* 06 tagqng_able */
12364         0xFFFF,                 /* 07 bios_scan */
12365         0,                      /* 08 scam_tolerant */
12366         7,                      /* 09 adapter_scsi_id */
12367         0,                      /*    bios_boot_delay */
12368         3,                      /* 10 scsi_reset_delay */
12369         0,                      /*    bios_id_lun */
12370         0,                      /* 11 termination_se */
12371         0,                      /*    termination_lvd */
12372         0xFFE7,                 /* 12 bios_ctrl */
12373         0x4444,                 /* 13 sdtr_speed2 */
12374         0x4444,                 /* 14 sdtr_speed3 */
12375         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
12376         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
12377         0,                      /* 16 dvc_cntl */
12378         0x4444,                 /* 17 sdtr_speed4 */
12379         0,                      /* 18 serial_number_word1 */
12380         0,                      /* 19 serial_number_word2 */
12381         0,                      /* 20 serial_number_word3 */
12382         0,                      /* 21 check_sum */
12383         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12384         ,                       /* 22-29 oem_name[16] */
12385         0,                      /* 30 dvc_err_code */
12386         0,                      /* 31 adv_err_code */
12387         0,                      /* 32 adv_err_addr */
12388         0,                      /* 33 saved_dvc_err_code */
12389         0,                      /* 34 saved_adv_err_code */
12390         0,                      /* 35 saved_adv_err_addr */
12391         0,                      /* 36 reserved */
12392         0,                      /* 37 reserved */
12393         0,                      /* 38 reserved */
12394         0,                      /* 39 reserved */
12395         0,                      /* 40 reserved */
12396         0,                      /* 41 reserved */
12397         0,                      /* 42 reserved */
12398         0,                      /* 43 reserved */
12399         0,                      /* 44 reserved */
12400         0,                      /* 45 reserved */
12401         0,                      /* 46 reserved */
12402         0,                      /* 47 reserved */
12403         0,                      /* 48 reserved */
12404         0,                      /* 49 reserved */
12405         0,                      /* 50 reserved */
12406         0,                      /* 51 reserved */
12407         0,                      /* 52 reserved */
12408         0,                      /* 53 reserved */
12409         0,                      /* 54 reserved */
12410         0,                      /* 55 reserved */
12411         0,                      /* 56 cisptr_lsw */
12412         0,                      /* 57 cisprt_msw */
12413         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
12414         PCI_DEVICE_ID_38C0800_REV1,     /* 59 subsysid */
12415         0,                      /* 60 reserved */
12416         0,                      /* 61 reserved */
12417         0,                      /* 62 reserved */
12418         0                       /* 63 reserved */
12419 };
12420
12421 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12422         0,                      /* 00 cfg_lsw */
12423         0,                      /* 01 cfg_msw */
12424         0,                      /* 02 disc_enable */
12425         0,                      /* 03 wdtr_able */
12426         0,                      /* 04 sdtr_speed1 */
12427         0,                      /* 05 start_motor */
12428         0,                      /* 06 tagqng_able */
12429         0,                      /* 07 bios_scan */
12430         0,                      /* 08 scam_tolerant */
12431         1,                      /* 09 adapter_scsi_id */
12432         1,                      /*    bios_boot_delay */
12433         1,                      /* 10 scsi_reset_delay */
12434         1,                      /*    bios_id_lun */
12435         1,                      /* 11 termination_se */
12436         1,                      /*    termination_lvd */
12437         0,                      /* 12 bios_ctrl */
12438         0,                      /* 13 sdtr_speed2 */
12439         0,                      /* 14 sdtr_speed3 */
12440         1,                      /* 15 max_host_qng */
12441         1,                      /*    max_dvc_qng */
12442         0,                      /* 16 dvc_cntl */
12443         0,                      /* 17 sdtr_speed4 */
12444         0,                      /* 18 serial_number_word1 */
12445         0,                      /* 19 serial_number_word2 */
12446         0,                      /* 20 serial_number_word3 */
12447         0,                      /* 21 check_sum */
12448         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12449         ,                       /* 22-29 oem_name[16] */
12450         0,                      /* 30 dvc_err_code */
12451         0,                      /* 31 adv_err_code */
12452         0,                      /* 32 adv_err_addr */
12453         0,                      /* 33 saved_dvc_err_code */
12454         0,                      /* 34 saved_adv_err_code */
12455         0,                      /* 35 saved_adv_err_addr */
12456         0,                      /* 36 reserved */
12457         0,                      /* 37 reserved */
12458         0,                      /* 38 reserved */
12459         0,                      /* 39 reserved */
12460         0,                      /* 40 reserved */
12461         0,                      /* 41 reserved */
12462         0,                      /* 42 reserved */
12463         0,                      /* 43 reserved */
12464         0,                      /* 44 reserved */
12465         0,                      /* 45 reserved */
12466         0,                      /* 46 reserved */
12467         0,                      /* 47 reserved */
12468         0,                      /* 48 reserved */
12469         0,                      /* 49 reserved */
12470         0,                      /* 50 reserved */
12471         0,                      /* 51 reserved */
12472         0,                      /* 52 reserved */
12473         0,                      /* 53 reserved */
12474         0,                      /* 54 reserved */
12475         0,                      /* 55 reserved */
12476         0,                      /* 56 cisptr_lsw */
12477         0,                      /* 57 cisprt_msw */
12478         0,                      /* 58 subsysvid */
12479         0,                      /* 59 subsysid */
12480         0,                      /* 60 reserved */
12481         0,                      /* 61 reserved */
12482         0,                      /* 62 reserved */
12483         0                       /* 63 reserved */
12484 };
12485
12486 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12487         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12488         0x0000,                 /* 01 cfg_msw */
12489         0xFFFF,                 /* 02 disc_enable */
12490         0xFFFF,                 /* 03 wdtr_able */
12491         0x5555,                 /* 04 sdtr_speed1 */
12492         0xFFFF,                 /* 05 start_motor */
12493         0xFFFF,                 /* 06 tagqng_able */
12494         0xFFFF,                 /* 07 bios_scan */
12495         0,                      /* 08 scam_tolerant */
12496         7,                      /* 09 adapter_scsi_id */
12497         0,                      /*    bios_boot_delay */
12498         3,                      /* 10 scsi_reset_delay */
12499         0,                      /*    bios_id_lun */
12500         0,                      /* 11 termination_se */
12501         0,                      /*    termination_lvd */
12502         0xFFE7,                 /* 12 bios_ctrl */
12503         0x5555,                 /* 13 sdtr_speed2 */
12504         0x5555,                 /* 14 sdtr_speed3 */
12505         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
12506         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
12507         0,                      /* 16 dvc_cntl */
12508         0x5555,                 /* 17 sdtr_speed4 */
12509         0,                      /* 18 serial_number_word1 */
12510         0,                      /* 19 serial_number_word2 */
12511         0,                      /* 20 serial_number_word3 */
12512         0,                      /* 21 check_sum */
12513         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12514         ,                       /* 22-29 oem_name[16] */
12515         0,                      /* 30 dvc_err_code */
12516         0,                      /* 31 adv_err_code */
12517         0,                      /* 32 adv_err_addr */
12518         0,                      /* 33 saved_dvc_err_code */
12519         0,                      /* 34 saved_adv_err_code */
12520         0,                      /* 35 saved_adv_err_addr */
12521         0,                      /* 36 reserved */
12522         0,                      /* 37 reserved */
12523         0,                      /* 38 reserved */
12524         0,                      /* 39 reserved */
12525         0,                      /* 40 reserved */
12526         0,                      /* 41 reserved */
12527         0,                      /* 42 reserved */
12528         0,                      /* 43 reserved */
12529         0,                      /* 44 reserved */
12530         0,                      /* 45 reserved */
12531         0,                      /* 46 reserved */
12532         0,                      /* 47 reserved */
12533         0,                      /* 48 reserved */
12534         0,                      /* 49 reserved */
12535         0,                      /* 50 reserved */
12536         0,                      /* 51 reserved */
12537         0,                      /* 52 reserved */
12538         0,                      /* 53 reserved */
12539         0,                      /* 54 reserved */
12540         0,                      /* 55 reserved */
12541         0,                      /* 56 cisptr_lsw */
12542         0,                      /* 57 cisprt_msw */
12543         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
12544         PCI_DEVICE_ID_38C1600_REV1,     /* 59 subsysid */
12545         0,                      /* 60 reserved */
12546         0,                      /* 61 reserved */
12547         0,                      /* 62 reserved */
12548         0                       /* 63 reserved */
12549 };
12550
12551 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12552         0,                      /* 00 cfg_lsw */
12553         0,                      /* 01 cfg_msw */
12554         0,                      /* 02 disc_enable */
12555         0,                      /* 03 wdtr_able */
12556         0,                      /* 04 sdtr_speed1 */
12557         0,                      /* 05 start_motor */
12558         0,                      /* 06 tagqng_able */
12559         0,                      /* 07 bios_scan */
12560         0,                      /* 08 scam_tolerant */
12561         1,                      /* 09 adapter_scsi_id */
12562         1,                      /*    bios_boot_delay */
12563         1,                      /* 10 scsi_reset_delay */
12564         1,                      /*    bios_id_lun */
12565         1,                      /* 11 termination_se */
12566         1,                      /*    termination_lvd */
12567         0,                      /* 12 bios_ctrl */
12568         0,                      /* 13 sdtr_speed2 */
12569         0,                      /* 14 sdtr_speed3 */
12570         1,                      /* 15 max_host_qng */
12571         1,                      /*    max_dvc_qng */
12572         0,                      /* 16 dvc_cntl */
12573         0,                      /* 17 sdtr_speed4 */
12574         0,                      /* 18 serial_number_word1 */
12575         0,                      /* 19 serial_number_word2 */
12576         0,                      /* 20 serial_number_word3 */
12577         0,                      /* 21 check_sum */
12578         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12579         ,                       /* 22-29 oem_name[16] */
12580         0,                      /* 30 dvc_err_code */
12581         0,                      /* 31 adv_err_code */
12582         0,                      /* 32 adv_err_addr */
12583         0,                      /* 33 saved_dvc_err_code */
12584         0,                      /* 34 saved_adv_err_code */
12585         0,                      /* 35 saved_adv_err_addr */
12586         0,                      /* 36 reserved */
12587         0,                      /* 37 reserved */
12588         0,                      /* 38 reserved */
12589         0,                      /* 39 reserved */
12590         0,                      /* 40 reserved */
12591         0,                      /* 41 reserved */
12592         0,                      /* 42 reserved */
12593         0,                      /* 43 reserved */
12594         0,                      /* 44 reserved */
12595         0,                      /* 45 reserved */
12596         0,                      /* 46 reserved */
12597         0,                      /* 47 reserved */
12598         0,                      /* 48 reserved */
12599         0,                      /* 49 reserved */
12600         0,                      /* 50 reserved */
12601         0,                      /* 51 reserved */
12602         0,                      /* 52 reserved */
12603         0,                      /* 53 reserved */
12604         0,                      /* 54 reserved */
12605         0,                      /* 55 reserved */
12606         0,                      /* 56 cisptr_lsw */
12607         0,                      /* 57 cisprt_msw */
12608         0,                      /* 58 subsysvid */
12609         0,                      /* 59 subsysid */
12610         0,                      /* 60 reserved */
12611         0,                      /* 61 reserved */
12612         0,                      /* 62 reserved */
12613         0                       /* 63 reserved */
12614 };
12615
12616 #ifdef CONFIG_PCI
12617 /*
12618  * Wait for EEPROM command to complete
12619  */
12620 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
12621 {
12622         int eep_delay_ms;
12623
12624         for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
12625                 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
12626                     ASC_EEP_CMD_DONE) {
12627                         break;
12628                 }
12629                 mdelay(1);
12630         }
12631         if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12632             0)
12633                 BUG();
12634 }
12635
12636 /*
12637  * Read the EEPROM from specified location
12638  */
12639 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12640 {
12641         AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12642                              ASC_EEP_CMD_READ | eep_word_addr);
12643         AdvWaitEEPCmd(iop_base);
12644         return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
12645 }
12646
12647 /*
12648  * Write the EEPROM from 'cfg_buf'.
12649  */
12650 void __devinit
12651 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12652 {
12653         ushort *wbuf;
12654         ushort addr, chksum;
12655         ushort *charfields;
12656
12657         wbuf = (ushort *)cfg_buf;
12658         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12659         chksum = 0;
12660
12661         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12662         AdvWaitEEPCmd(iop_base);
12663
12664         /*
12665          * Write EEPROM from word 0 to word 20.
12666          */
12667         for (addr = ADV_EEP_DVC_CFG_BEGIN;
12668              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12669                 ushort word;
12670
12671                 if (*charfields++) {
12672                         word = cpu_to_le16(*wbuf);
12673                 } else {
12674                         word = *wbuf;
12675                 }
12676                 chksum += *wbuf;        /* Checksum is calculated from word values. */
12677                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12678                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12679                                      ASC_EEP_CMD_WRITE | addr);
12680                 AdvWaitEEPCmd(iop_base);
12681                 mdelay(ADV_EEP_DELAY_MS);
12682         }
12683
12684         /*
12685          * Write EEPROM checksum at word 21.
12686          */
12687         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12688         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12689         AdvWaitEEPCmd(iop_base);
12690         wbuf++;
12691         charfields++;
12692
12693         /*
12694          * Write EEPROM OEM name at words 22 to 29.
12695          */
12696         for (addr = ADV_EEP_DVC_CTL_BEGIN;
12697              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12698                 ushort word;
12699
12700                 if (*charfields++) {
12701                         word = cpu_to_le16(*wbuf);
12702                 } else {
12703                         word = *wbuf;
12704                 }
12705                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12706                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12707                                      ASC_EEP_CMD_WRITE | addr);
12708                 AdvWaitEEPCmd(iop_base);
12709         }
12710         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12711         AdvWaitEEPCmd(iop_base);
12712 }
12713
12714 /*
12715  * Write the EEPROM from 'cfg_buf'.
12716  */
12717 void __devinit
12718 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12719 {
12720         ushort *wbuf;
12721         ushort *charfields;
12722         ushort addr, chksum;
12723
12724         wbuf = (ushort *)cfg_buf;
12725         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12726         chksum = 0;
12727
12728         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12729         AdvWaitEEPCmd(iop_base);
12730
12731         /*
12732          * Write EEPROM from word 0 to word 20.
12733          */
12734         for (addr = ADV_EEP_DVC_CFG_BEGIN;
12735              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12736                 ushort word;
12737
12738                 if (*charfields++) {
12739                         word = cpu_to_le16(*wbuf);
12740                 } else {
12741                         word = *wbuf;
12742                 }
12743                 chksum += *wbuf;        /* Checksum is calculated from word values. */
12744                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12745                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12746                                      ASC_EEP_CMD_WRITE | addr);
12747                 AdvWaitEEPCmd(iop_base);
12748                 mdelay(ADV_EEP_DELAY_MS);
12749         }
12750
12751         /*
12752          * Write EEPROM checksum at word 21.
12753          */
12754         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12755         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12756         AdvWaitEEPCmd(iop_base);
12757         wbuf++;
12758         charfields++;
12759
12760         /*
12761          * Write EEPROM OEM name at words 22 to 29.
12762          */
12763         for (addr = ADV_EEP_DVC_CTL_BEGIN;
12764              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12765                 ushort word;
12766
12767                 if (*charfields++) {
12768                         word = cpu_to_le16(*wbuf);
12769                 } else {
12770                         word = *wbuf;
12771                 }
12772                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12773                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12774                                      ASC_EEP_CMD_WRITE | addr);
12775                 AdvWaitEEPCmd(iop_base);
12776         }
12777         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12778         AdvWaitEEPCmd(iop_base);
12779 }
12780
12781 /*
12782  * Write the EEPROM from 'cfg_buf'.
12783  */
12784 void __devinit
12785 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12786 {
12787         ushort *wbuf;
12788         ushort *charfields;
12789         ushort addr, chksum;
12790
12791         wbuf = (ushort *)cfg_buf;
12792         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12793         chksum = 0;
12794
12795         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12796         AdvWaitEEPCmd(iop_base);
12797
12798         /*
12799          * Write EEPROM from word 0 to word 20.
12800          */
12801         for (addr = ADV_EEP_DVC_CFG_BEGIN;
12802              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12803                 ushort word;
12804
12805                 if (*charfields++) {
12806                         word = cpu_to_le16(*wbuf);
12807                 } else {
12808                         word = *wbuf;
12809                 }
12810                 chksum += *wbuf;        /* Checksum is calculated from word values. */
12811                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12812                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12813                                      ASC_EEP_CMD_WRITE | addr);
12814                 AdvWaitEEPCmd(iop_base);
12815                 mdelay(ADV_EEP_DELAY_MS);
12816         }
12817
12818         /*
12819          * Write EEPROM checksum at word 21.
12820          */
12821         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12822         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12823         AdvWaitEEPCmd(iop_base);
12824         wbuf++;
12825         charfields++;
12826
12827         /*
12828          * Write EEPROM OEM name at words 22 to 29.
12829          */
12830         for (addr = ADV_EEP_DVC_CTL_BEGIN;
12831              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12832                 ushort word;
12833
12834                 if (*charfields++) {
12835                         word = cpu_to_le16(*wbuf);
12836                 } else {
12837                         word = *wbuf;
12838                 }
12839                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12840                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12841                                      ASC_EEP_CMD_WRITE | addr);
12842                 AdvWaitEEPCmd(iop_base);
12843         }
12844         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12845         AdvWaitEEPCmd(iop_base);
12846 }
12847
12848 /*
12849  * Read EEPROM configuration into the specified buffer.
12850  *
12851  * Return a checksum based on the EEPROM configuration read.
12852  */
12853 static ushort __devinit
12854 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12855 {
12856         ushort wval, chksum;
12857         ushort *wbuf;
12858         int eep_addr;
12859         ushort *charfields;
12860
12861         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12862         wbuf = (ushort *)cfg_buf;
12863         chksum = 0;
12864
12865         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12866              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12867                 wval = AdvReadEEPWord(iop_base, eep_addr);
12868                 chksum += wval; /* Checksum is calculated from word values. */
12869                 if (*charfields++) {
12870                         *wbuf = le16_to_cpu(wval);
12871                 } else {
12872                         *wbuf = wval;
12873                 }
12874         }
12875         /* Read checksum word. */
12876         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12877         wbuf++;
12878         charfields++;
12879
12880         /* Read rest of EEPROM not covered by the checksum. */
12881         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12882              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12883                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12884                 if (*charfields++) {
12885                         *wbuf = le16_to_cpu(*wbuf);
12886                 }
12887         }
12888         return chksum;
12889 }
12890
12891 /*
12892  * Read EEPROM configuration into the specified buffer.
12893  *
12894  * Return a checksum based on the EEPROM configuration read.
12895  */
12896 static ushort __devinit
12897 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12898 {
12899         ushort wval, chksum;
12900         ushort *wbuf;
12901         int eep_addr;
12902         ushort *charfields;
12903
12904         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12905         wbuf = (ushort *)cfg_buf;
12906         chksum = 0;
12907
12908         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12909              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12910                 wval = AdvReadEEPWord(iop_base, eep_addr);
12911                 chksum += wval; /* Checksum is calculated from word values. */
12912                 if (*charfields++) {
12913                         *wbuf = le16_to_cpu(wval);
12914                 } else {
12915                         *wbuf = wval;
12916                 }
12917         }
12918         /* Read checksum word. */
12919         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12920         wbuf++;
12921         charfields++;
12922
12923         /* Read rest of EEPROM not covered by the checksum. */
12924         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12925              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12926                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12927                 if (*charfields++) {
12928                         *wbuf = le16_to_cpu(*wbuf);
12929                 }
12930         }
12931         return chksum;
12932 }
12933
12934 /*
12935  * Read EEPROM configuration into the specified buffer.
12936  *
12937  * Return a checksum based on the EEPROM configuration read.
12938  */
12939 static ushort __devinit
12940 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12941 {
12942         ushort wval, chksum;
12943         ushort *wbuf;
12944         int eep_addr;
12945         ushort *charfields;
12946
12947         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12948         wbuf = (ushort *)cfg_buf;
12949         chksum = 0;
12950
12951         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12952              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12953                 wval = AdvReadEEPWord(iop_base, eep_addr);
12954                 chksum += wval; /* Checksum is calculated from word values. */
12955                 if (*charfields++) {
12956                         *wbuf = le16_to_cpu(wval);
12957                 } else {
12958                         *wbuf = wval;
12959                 }
12960         }
12961         /* Read checksum word. */
12962         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12963         wbuf++;
12964         charfields++;
12965
12966         /* Read rest of EEPROM not covered by the checksum. */
12967         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12968              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12969                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12970                 if (*charfields++) {
12971                         *wbuf = le16_to_cpu(*wbuf);
12972                 }
12973         }
12974         return chksum;
12975 }
12976
12977 /*
12978  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12979  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12980  * all of this is done.
12981  *
12982  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12983  *
12984  * For a non-fatal error return a warning code. If there are no warnings
12985  * then 0 is returned.
12986  *
12987  * Note: Chip is stopped on entry.
12988  */
12989 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
12990 {
12991         AdvPortAddr iop_base;
12992         ushort warn_code;
12993         ADVEEP_3550_CONFIG eep_config;
12994
12995         iop_base = asc_dvc->iop_base;
12996
12997         warn_code = 0;
12998
12999         /*
13000          * Read the board's EEPROM configuration.
13001          *
13002          * Set default values if a bad checksum is found.
13003          */
13004         if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
13005                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13006
13007                 /*
13008                  * Set EEPROM default values.
13009                  */
13010                 memcpy(&eep_config, &Default_3550_EEPROM_Config,
13011                         sizeof(ADVEEP_3550_CONFIG));
13012
13013                 /*
13014                  * Assume the 6 byte board serial number that was read from
13015                  * EEPROM is correct even if the EEPROM checksum failed.
13016                  */
13017                 eep_config.serial_number_word3 =
13018                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13019
13020                 eep_config.serial_number_word2 =
13021                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13022
13023                 eep_config.serial_number_word1 =
13024                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13025
13026                 AdvSet3550EEPConfig(iop_base, &eep_config);
13027         }
13028         /*
13029          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13030          * EEPROM configuration that was read.
13031          *
13032          * This is the mapping of EEPROM fields to Adv Library fields.
13033          */
13034         asc_dvc->wdtr_able = eep_config.wdtr_able;
13035         asc_dvc->sdtr_able = eep_config.sdtr_able;
13036         asc_dvc->ultra_able = eep_config.ultra_able;
13037         asc_dvc->tagqng_able = eep_config.tagqng_able;
13038         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13039         asc_dvc->max_host_qng = eep_config.max_host_qng;
13040         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13041         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13042         asc_dvc->start_motor = eep_config.start_motor;
13043         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13044         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13045         asc_dvc->no_scam = eep_config.scam_tolerant;
13046         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13047         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13048         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13049
13050         /*
13051          * Set the host maximum queuing (max. 253, min. 16) and the per device
13052          * maximum queuing (max. 63, min. 4).
13053          */
13054         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13055                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13056         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13057                 /* If the value is zero, assume it is uninitialized. */
13058                 if (eep_config.max_host_qng == 0) {
13059                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13060                 } else {
13061                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13062                 }
13063         }
13064
13065         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13066                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13067         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13068                 /* If the value is zero, assume it is uninitialized. */
13069                 if (eep_config.max_dvc_qng == 0) {
13070                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13071                 } else {
13072                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13073                 }
13074         }
13075
13076         /*
13077          * If 'max_dvc_qng' is greater than 'max_host_qng', then
13078          * set 'max_dvc_qng' to 'max_host_qng'.
13079          */
13080         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13081                 eep_config.max_dvc_qng = eep_config.max_host_qng;
13082         }
13083
13084         /*
13085          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13086          * values based on possibly adjusted EEPROM values.
13087          */
13088         asc_dvc->max_host_qng = eep_config.max_host_qng;
13089         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13090
13091         /*
13092          * If the EEPROM 'termination' field is set to automatic (0), then set
13093          * the ADV_DVC_CFG 'termination' field to automatic also.
13094          *
13095          * If the termination is specified with a non-zero 'termination'
13096          * value check that a legal value is set and set the ADV_DVC_CFG
13097          * 'termination' field appropriately.
13098          */
13099         if (eep_config.termination == 0) {
13100                 asc_dvc->cfg->termination = 0;  /* auto termination */
13101         } else {
13102                 /* Enable manual control with low off / high off. */
13103                 if (eep_config.termination == 1) {
13104                         asc_dvc->cfg->termination = TERM_CTL_SEL;
13105
13106                         /* Enable manual control with low off / high on. */
13107                 } else if (eep_config.termination == 2) {
13108                         asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
13109
13110                         /* Enable manual control with low on / high on. */
13111                 } else if (eep_config.termination == 3) {
13112                         asc_dvc->cfg->termination =
13113                             TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
13114                 } else {
13115                         /*
13116                          * The EEPROM 'termination' field contains a bad value. Use
13117                          * automatic termination instead.
13118                          */
13119                         asc_dvc->cfg->termination = 0;
13120                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
13121                 }
13122         }
13123
13124         return warn_code;
13125 }
13126
13127 /*
13128  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
13129  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
13130  * all of this is done.
13131  *
13132  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13133  *
13134  * For a non-fatal error return a warning code. If there are no warnings
13135  * then 0 is returned.
13136  *
13137  * Note: Chip is stopped on entry.
13138  */
13139 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
13140 {
13141         AdvPortAddr iop_base;
13142         ushort warn_code;
13143         ADVEEP_38C0800_CONFIG eep_config;
13144         uchar tid, termination;
13145         ushort sdtr_speed = 0;
13146
13147         iop_base = asc_dvc->iop_base;
13148
13149         warn_code = 0;
13150
13151         /*
13152          * Read the board's EEPROM configuration.
13153          *
13154          * Set default values if a bad checksum is found.
13155          */
13156         if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
13157             eep_config.check_sum) {
13158                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13159
13160                 /*
13161                  * Set EEPROM default values.
13162                  */
13163                 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
13164                         sizeof(ADVEEP_38C0800_CONFIG));
13165
13166                 /*
13167                  * Assume the 6 byte board serial number that was read from
13168                  * EEPROM is correct even if the EEPROM checksum failed.
13169                  */
13170                 eep_config.serial_number_word3 =
13171                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13172
13173                 eep_config.serial_number_word2 =
13174                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13175
13176                 eep_config.serial_number_word1 =
13177                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13178
13179                 AdvSet38C0800EEPConfig(iop_base, &eep_config);
13180         }
13181         /*
13182          * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
13183          * EEPROM configuration that was read.
13184          *
13185          * This is the mapping of EEPROM fields to Adv Library fields.
13186          */
13187         asc_dvc->wdtr_able = eep_config.wdtr_able;
13188         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13189         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13190         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13191         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13192         asc_dvc->tagqng_able = eep_config.tagqng_able;
13193         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13194         asc_dvc->max_host_qng = eep_config.max_host_qng;
13195         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13196         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
13197         asc_dvc->start_motor = eep_config.start_motor;
13198         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13199         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13200         asc_dvc->no_scam = eep_config.scam_tolerant;
13201         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
13202         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
13203         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
13204
13205         /*
13206          * For every Target ID if any of its 'sdtr_speed[1234]' bits
13207          * are set, then set an 'sdtr_able' bit for it.
13208          */
13209         asc_dvc->sdtr_able = 0;
13210         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13211                 if (tid == 0) {
13212                         sdtr_speed = asc_dvc->sdtr_speed1;
13213                 } else if (tid == 4) {
13214                         sdtr_speed = asc_dvc->sdtr_speed2;
13215                 } else if (tid == 8) {
13216                         sdtr_speed = asc_dvc->sdtr_speed3;
13217                 } else if (tid == 12) {
13218                         sdtr_speed = asc_dvc->sdtr_speed4;
13219                 }
13220                 if (sdtr_speed & ADV_MAX_TID) {
13221                         asc_dvc->sdtr_able |= (1 << tid);
13222                 }
13223                 sdtr_speed >>= 4;
13224         }
13225
13226         /*
13227          * Set the host maximum queuing (max. 253, min. 16) and the per device
13228          * maximum queuing (max. 63, min. 4).
13229          */
13230         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13231                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13232         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13233                 /* If the value is zero, assume it is uninitialized. */
13234                 if (eep_config.max_host_qng == 0) {
13235                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13236                 } else {
13237                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13238                 }
13239         }
13240
13241         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13242                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13243         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13244                 /* If the value is zero, assume it is uninitialized. */
13245                 if (eep_config.max_dvc_qng == 0) {
13246                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13247                 } else {
13248                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13249                 }
13250         }
13251
13252         /*
13253          * If 'max_dvc_qng' is greater than 'max_host_qng', then
13254          * set 'max_dvc_qng' to 'max_host_qng'.
13255          */
13256         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13257                 eep_config.max_dvc_qng = eep_config.max_host_qng;
13258         }
13259
13260         /*
13261          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
13262          * values based on possibly adjusted EEPROM values.
13263          */
13264         asc_dvc->max_host_qng = eep_config.max_host_qng;
13265         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13266
13267         /*
13268          * If the EEPROM 'termination' field is set to automatic (0), then set
13269          * the ADV_DVC_CFG 'termination' field to automatic also.
13270          *
13271          * If the termination is specified with a non-zero 'termination'
13272          * value check that a legal value is set and set the ADV_DVC_CFG
13273          * 'termination' field appropriately.
13274          */
13275         if (eep_config.termination_se == 0) {
13276                 termination = 0;        /* auto termination for SE */
13277         } else {
13278                 /* Enable manual control with low off / high off. */
13279                 if (eep_config.termination_se == 1) {
13280                         termination = 0;
13281
13282                         /* Enable manual control with low off / high on. */
13283                 } else if (eep_config.termination_se == 2) {
13284                         termination = TERM_SE_HI;
13285
13286                         /* Enable manual control with low on / high on. */
13287                 } else if (eep_config.termination_se == 3) {
13288                         termination = TERM_SE;
13289                 } else {
13290                         /*
13291                          * The EEPROM 'termination_se' field contains a bad value.
13292                          * Use automatic termination instead.
13293                          */
13294                         termination = 0;
13295                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
13296                 }
13297         }
13298
13299         if (eep_config.termination_lvd == 0) {
13300                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
13301         } else {
13302                 /* Enable manual control with low off / high off. */
13303                 if (eep_config.termination_lvd == 1) {
13304                         asc_dvc->cfg->termination = termination;
13305
13306                         /* Enable manual control with low off / high on. */
13307                 } else if (eep_config.termination_lvd == 2) {
13308                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13309
13310                         /* Enable manual control with low on / high on. */
13311                 } else if (eep_config.termination_lvd == 3) {
13312                         asc_dvc->cfg->termination = termination | TERM_LVD;
13313                 } else {
13314                         /*
13315                          * The EEPROM 'termination_lvd' field contains a bad value.
13316                          * Use automatic termination instead.
13317                          */
13318                         asc_dvc->cfg->termination = termination;
13319                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
13320                 }
13321         }
13322
13323         return warn_code;
13324 }
13325
13326 /*
13327  * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
13328  * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
13329  * all of this is done.
13330  *
13331  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
13332  *
13333  * For a non-fatal error return a warning code. If there are no warnings
13334  * then 0 is returned.
13335  *
13336  * Note: Chip is stopped on entry.
13337  */
13338 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
13339 {
13340         AdvPortAddr iop_base;
13341         ushort warn_code;
13342         ADVEEP_38C1600_CONFIG eep_config;
13343         uchar tid, termination;
13344         ushort sdtr_speed = 0;
13345
13346         iop_base = asc_dvc->iop_base;
13347
13348         warn_code = 0;
13349
13350         /*
13351          * Read the board's EEPROM configuration.
13352          *
13353          * Set default values if a bad checksum is found.
13354          */
13355         if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
13356             eep_config.check_sum) {
13357                 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
13358                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
13359
13360                 /*
13361                  * Set EEPROM default values.
13362                  */
13363                 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
13364                         sizeof(ADVEEP_38C1600_CONFIG));
13365
13366                 if (PCI_FUNC(pdev->devfn) != 0) {
13367                         u8 ints;
13368                         /*
13369                          * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
13370                          * and old Mac system booting problem. The Expansion
13371                          * ROM must be disabled in Function 1 for these systems
13372                          */
13373                         eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
13374                         /*
13375                          * Clear the INTAB (bit 11) if the GPIO 0 input
13376                          * indicates the Function 1 interrupt line is wired
13377                          * to INTB.
13378                          *
13379                          * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
13380                          *   1 - Function 1 interrupt line wired to INT A.
13381                          *   0 - Function 1 interrupt line wired to INT B.
13382                          *
13383                          * Note: Function 0 is always wired to INTA.
13384                          * Put all 5 GPIO bits in input mode and then read
13385                          * their input values.
13386                          */
13387                         AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13388                         ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13389                         if ((ints & 0x01) == 0)
13390                                 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
13391                 }
13392
13393                 /*
13394                  * Assume the 6 byte board serial number that was read from
13395                  * EEPROM is correct even if the EEPROM checksum failed.
13396                  */
13397                 eep_config.serial_number_word3 =
13398                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13399                 eep_config.serial_number_word2 =
13400                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13401                 eep_config.serial_number_word1 =
13402                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13403
13404                 AdvSet38C1600EEPConfig(iop_base, &eep_config);
13405         }
13406
13407         /*
13408          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13409          * EEPROM configuration that was read.
13410          *
13411          * This is the mapping of EEPROM fields to Adv Library fields.
13412          */
13413         asc_dvc->wdtr_able = eep_config.wdtr_able;
13414         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13415         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13416         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13417         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13418         asc_dvc->ppr_able = 0;
13419         asc_dvc->tagqng_able = eep_config.tagqng_able;
13420         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13421         asc_dvc->max_host_qng = eep_config.max_host_qng;
13422         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13423         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13424         asc_dvc->start_motor = eep_config.start_motor;
13425         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13426         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13427         asc_dvc->no_scam = eep_config.scam_tolerant;
13428
13429         /*
13430          * For every Target ID if any of its 'sdtr_speed[1234]' bits
13431          * are set, then set an 'sdtr_able' bit for it.
13432          */
13433         asc_dvc->sdtr_able = 0;
13434         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13435                 if (tid == 0) {
13436                         sdtr_speed = asc_dvc->sdtr_speed1;
13437                 } else if (tid == 4) {
13438                         sdtr_speed = asc_dvc->sdtr_speed2;
13439                 } else if (tid == 8) {
13440                         sdtr_speed = asc_dvc->sdtr_speed3;
13441                 } else if (tid == 12) {
13442                         sdtr_speed = asc_dvc->sdtr_speed4;
13443                 }
13444                 if (sdtr_speed & ASC_MAX_TID) {
13445                         asc_dvc->sdtr_able |= (1 << tid);
13446                 }
13447                 sdtr_speed >>= 4;
13448         }
13449
13450         /*
13451          * Set the host maximum queuing (max. 253, min. 16) and the per device
13452          * maximum queuing (max. 63, min. 4).
13453          */
13454         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13455                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13456         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13457                 /* If the value is zero, assume it is uninitialized. */
13458                 if (eep_config.max_host_qng == 0) {
13459                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13460                 } else {
13461                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13462                 }
13463         }
13464
13465         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13466                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13467         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13468                 /* If the value is zero, assume it is uninitialized. */
13469                 if (eep_config.max_dvc_qng == 0) {
13470                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13471                 } else {
13472                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13473                 }
13474         }
13475
13476         /*
13477          * If 'max_dvc_qng' is greater than 'max_host_qng', then
13478          * set 'max_dvc_qng' to 'max_host_qng'.
13479          */
13480         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13481                 eep_config.max_dvc_qng = eep_config.max_host_qng;
13482         }
13483
13484         /*
13485          * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13486          * values based on possibly adjusted EEPROM values.
13487          */
13488         asc_dvc->max_host_qng = eep_config.max_host_qng;
13489         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13490
13491         /*
13492          * If the EEPROM 'termination' field is set to automatic (0), then set
13493          * the ASC_DVC_CFG 'termination' field to automatic also.
13494          *
13495          * If the termination is specified with a non-zero 'termination'
13496          * value check that a legal value is set and set the ASC_DVC_CFG
13497          * 'termination' field appropriately.
13498          */
13499         if (eep_config.termination_se == 0) {
13500                 termination = 0;        /* auto termination for SE */
13501         } else {
13502                 /* Enable manual control with low off / high off. */
13503                 if (eep_config.termination_se == 1) {
13504                         termination = 0;
13505
13506                         /* Enable manual control with low off / high on. */
13507                 } else if (eep_config.termination_se == 2) {
13508                         termination = TERM_SE_HI;
13509
13510                         /* Enable manual control with low on / high on. */
13511                 } else if (eep_config.termination_se == 3) {
13512                         termination = TERM_SE;
13513                 } else {
13514                         /*
13515                          * The EEPROM 'termination_se' field contains a bad value.
13516                          * Use automatic termination instead.
13517                          */
13518                         termination = 0;
13519                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
13520                 }
13521         }
13522
13523         if (eep_config.termination_lvd == 0) {
13524                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
13525         } else {
13526                 /* Enable manual control with low off / high off. */
13527                 if (eep_config.termination_lvd == 1) {
13528                         asc_dvc->cfg->termination = termination;
13529
13530                         /* Enable manual control with low off / high on. */
13531                 } else if (eep_config.termination_lvd == 2) {
13532                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13533
13534                         /* Enable manual control with low on / high on. */
13535                 } else if (eep_config.termination_lvd == 3) {
13536                         asc_dvc->cfg->termination = termination | TERM_LVD;
13537                 } else {
13538                         /*
13539                          * The EEPROM 'termination_lvd' field contains a bad value.
13540                          * Use automatic termination instead.
13541                          */
13542                         asc_dvc->cfg->termination = termination;
13543                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
13544                 }
13545         }
13546
13547         return warn_code;
13548 }
13549
13550 /*
13551  * Initialize the ADV_DVC_VAR structure.
13552  *
13553  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13554  *
13555  * For a non-fatal error return a warning code. If there are no warnings
13556  * then 0 is returned.
13557  */
13558 static int __devinit
13559 AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp)
13560 {
13561         ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var;
13562         unsigned short warn_code = 0;
13563         AdvPortAddr iop_base = asc_dvc->iop_base;
13564         u16 cmd;
13565         int status;
13566
13567         asc_dvc->err_code = 0;
13568
13569         /*
13570          * Save the state of the PCI Configuration Command Register
13571          * "Parity Error Response Control" Bit. If the bit is clear (0),
13572          * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13573          * DMA parity errors.
13574          */
13575         asc_dvc->cfg->control_flag = 0;
13576         pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13577         if ((cmd & PCI_COMMAND_PARITY) == 0)
13578                 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13579
13580         asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13581             ADV_LIB_VERSION_MINOR;
13582         asc_dvc->cfg->chip_version =
13583             AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13584
13585         ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13586                  (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13587                  (ushort)ADV_CHIP_ID_BYTE);
13588
13589         ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13590                  (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13591                  (ushort)ADV_CHIP_ID_WORD);
13592
13593         /*
13594          * Reset the chip to start and allow register writes.
13595          */
13596         if (AdvFindSignature(iop_base) == 0) {
13597                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13598                 return ADV_ERROR;
13599         } else {
13600                 /*
13601                  * The caller must set 'chip_type' to a valid setting.
13602                  */
13603                 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13604                     asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13605                     asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13606                         asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13607                         return ADV_ERROR;
13608                 }
13609
13610                 /*
13611                  * Reset Chip.
13612                  */
13613                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13614                                      ADV_CTRL_REG_CMD_RESET);
13615                 mdelay(100);
13616                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13617                                      ADV_CTRL_REG_CMD_WR_IO_REG);
13618
13619                 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13620                         status = AdvInitFrom38C1600EEP(asc_dvc);
13621                 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13622                         status = AdvInitFrom38C0800EEP(asc_dvc);
13623                 } else {
13624                         status = AdvInitFrom3550EEP(asc_dvc);
13625                 }
13626                 warn_code |= status;
13627         }
13628
13629         if (warn_code != 0) {
13630                 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
13631                            boardp->id, warn_code);
13632         }
13633
13634         if (asc_dvc->err_code) {
13635                 ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n",
13636                      boardp->id, asc_dvc->err_code);
13637         }
13638
13639         return asc_dvc->err_code;
13640 }
13641 #endif
13642
13643 static struct scsi_host_template advansys_template = {
13644         .proc_name = DRV_NAME,
13645 #ifdef CONFIG_PROC_FS
13646         .proc_info = advansys_proc_info,
13647 #endif
13648         .name = DRV_NAME,
13649         .info = advansys_info,
13650         .queuecommand = advansys_queuecommand,
13651         .eh_bus_reset_handler = advansys_reset,
13652         .bios_param = advansys_biosparam,
13653         .slave_configure = advansys_slave_configure,
13654         /*
13655          * Because the driver may control an ISA adapter 'unchecked_isa_dma'
13656          * must be set. The flag will be cleared in advansys_board_found
13657          * for non-ISA adapters.
13658          */
13659         .unchecked_isa_dma = 1,
13660         /*
13661          * All adapters controlled by this driver are capable of large
13662          * scatter-gather lists. According to the mid-level SCSI documentation
13663          * this obviates any performance gain provided by setting
13664          * 'use_clustering'. But empirically while CPU utilization is increased
13665          * by enabling clustering, I/O throughput increases as well.
13666          */
13667         .use_clustering = ENABLE_CLUSTERING,
13668 };
13669
13670 static int __devinit
13671 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
13672 {
13673         int req_cnt = 0;
13674         adv_req_t *reqp = NULL;
13675         int sg_cnt = 0;
13676         adv_sgblk_t *sgp;
13677         int warn_code, err_code;
13678
13679         /*
13680          * Allocate buffer carrier structures. The total size
13681          * is about 4 KB, so allocate all at once.
13682          */
13683         boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13684         ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
13685
13686         if (!boardp->carrp)
13687                 goto kmalloc_failed;
13688
13689         /*
13690          * Allocate up to 'max_host_qng' request structures for the Wide
13691          * board. The total size is about 16 KB, so allocate all at once.
13692          * If the allocation fails decrement and try again.
13693          */
13694         for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
13695                 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13696
13697                 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
13698                          "bytes %lu\n", reqp, req_cnt,
13699                          (ulong)sizeof(adv_req_t) * req_cnt);
13700
13701                 if (reqp)
13702                         break;
13703         }
13704
13705         if (!reqp)
13706                 goto kmalloc_failed;
13707
13708         boardp->orig_reqp = reqp;
13709
13710         /*
13711          * Allocate up to ADV_TOT_SG_BLOCK request structures for
13712          * the Wide board. Each structure is about 136 bytes.
13713          */
13714         boardp->adv_sgblkp = NULL;
13715         for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13716                 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13717
13718                 if (!sgp)
13719                         break;
13720
13721                 sgp->next_sgblkp = boardp->adv_sgblkp;
13722                 boardp->adv_sgblkp = sgp;
13723
13724         }
13725
13726         ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
13727                  sg_cnt, sizeof(adv_sgblk_t),
13728                  (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
13729
13730         if (!boardp->adv_sgblkp)
13731                 goto kmalloc_failed;
13732
13733         adv_dvc_varp->carrier_buf = boardp->carrp;
13734
13735         /*
13736          * Point 'adv_reqp' to the request structures and
13737          * link them together.
13738          */
13739         req_cnt--;
13740         reqp[req_cnt].next_reqp = NULL;
13741         for (; req_cnt > 0; req_cnt--) {
13742                 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
13743         }
13744         boardp->adv_reqp = &reqp[0];
13745
13746         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13747                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
13748                 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
13749         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13750                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
13751                            "\n");
13752                 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
13753         } else {
13754                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
13755                            "\n");
13756                 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
13757         }
13758         err_code = adv_dvc_varp->err_code;
13759
13760         if (warn_code || err_code) {
13761                 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
13762                            " error 0x%x\n", boardp->id, warn_code, err_code);
13763         }
13764
13765         goto exit;
13766
13767  kmalloc_failed:
13768         ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
13769                    "failed\n", boardp->id);
13770         err_code = ADV_ERROR;
13771  exit:
13772         return err_code;
13773 }
13774
13775 static void advansys_wide_free_mem(asc_board_t *boardp)
13776 {
13777         kfree(boardp->carrp);
13778         boardp->carrp = NULL;
13779         kfree(boardp->orig_reqp);
13780         boardp->orig_reqp = boardp->adv_reqp = NULL;
13781         while (boardp->adv_sgblkp) {
13782                 adv_sgblk_t *sgp = boardp->adv_sgblkp;
13783                 boardp->adv_sgblkp = sgp->next_sgblkp;
13784                 kfree(sgp);
13785         }
13786 }
13787
13788 static int __devinit advansys_board_found(struct Scsi_Host *shost,
13789                                           unsigned int iop, int bus_type)
13790 {
13791         struct pci_dev *pdev;
13792         asc_board_t *boardp;
13793         ASC_DVC_VAR *asc_dvc_varp = NULL;
13794         ADV_DVC_VAR *adv_dvc_varp = NULL;
13795         int share_irq, warn_code, ret;
13796
13797         boardp = ASC_BOARDP(shost);
13798         boardp->id = asc_board_count++;
13799         spin_lock_init(&boardp->lock);
13800         pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
13801
13802         if (ASC_NARROW_BOARD(boardp)) {
13803                 ASC_DBG(1, "advansys_board_found: narrow board\n");
13804                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
13805                 asc_dvc_varp->bus_type = bus_type;
13806                 asc_dvc_varp->drv_ptr = boardp;
13807                 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
13808                 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
13809                 asc_dvc_varp->iop_base = iop;
13810         } else {
13811 #ifdef CONFIG_PCI
13812                 ASC_DBG(1, "advansys_board_found: wide board\n");
13813                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
13814                 adv_dvc_varp->drv_ptr = boardp;
13815                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
13816                 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
13817                         ASC_DBG(1, "advansys_board_found: ASC-3550\n");
13818                         adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13819                 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
13820                         ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
13821                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13822                 } else {
13823                         ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
13824                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13825                 }
13826
13827                 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
13828                 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
13829                                                boardp->asc_n_io_port);
13830                 if (!boardp->ioremap_addr) {
13831                         ASC_PRINT3
13832                             ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
13833                              boardp->id, pci_resource_start(pdev, 1),
13834                              boardp->asc_n_io_port);
13835                         ret = -ENODEV;
13836                         goto err_shost;
13837                 }
13838                 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
13839                 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
13840                          adv_dvc_varp->iop_base);
13841
13842                 /*
13843                  * Even though it isn't used to access wide boards, other
13844                  * than for the debug line below, save I/O Port address so
13845                  * that it can be reported.
13846                  */
13847                 boardp->ioport = iop;
13848
13849                 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
13850                          "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
13851                          (ushort)inpw(iop));
13852 #endif /* CONFIG_PCI */
13853         }
13854
13855 #ifdef CONFIG_PROC_FS
13856         /*
13857          * Allocate buffer for printing information from
13858          * /proc/scsi/advansys/[0...].
13859          */
13860         boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13861         if (!boardp->prtbuf) {
13862                 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
13863                            "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
13864                 ret = -ENOMEM;
13865                 goto err_unmap;
13866         }
13867 #endif /* CONFIG_PROC_FS */
13868
13869         if (ASC_NARROW_BOARD(boardp)) {
13870                 /*
13871                  * Set the board bus type and PCI IRQ before
13872                  * calling AscInitGetConfig().
13873                  */
13874                 switch (asc_dvc_varp->bus_type) {
13875 #ifdef CONFIG_ISA
13876                 case ASC_IS_ISA:
13877                         shost->unchecked_isa_dma = TRUE;
13878                         share_irq = 0;
13879                         break;
13880                 case ASC_IS_VL:
13881                         shost->unchecked_isa_dma = FALSE;
13882                         share_irq = 0;
13883                         break;
13884                 case ASC_IS_EISA:
13885                         shost->unchecked_isa_dma = FALSE;
13886                         share_irq = IRQF_SHARED;
13887                         break;
13888 #endif /* CONFIG_ISA */
13889 #ifdef CONFIG_PCI
13890                 case ASC_IS_PCI:
13891                         shost->unchecked_isa_dma = FALSE;
13892                         share_irq = IRQF_SHARED;
13893                         break;
13894 #endif /* CONFIG_PCI */
13895                 default:
13896                         ASC_PRINT2
13897                             ("advansys_board_found: board %d: unknown adapter type: %d\n",
13898                              boardp->id, asc_dvc_varp->bus_type);
13899                         shost->unchecked_isa_dma = TRUE;
13900                         share_irq = 0;
13901                         break;
13902                 }
13903
13904                 /*
13905                  * NOTE: AscInitGetConfig() may change the board's
13906                  * bus_type value. The bus_type value should no
13907                  * longer be used. If the bus_type field must be
13908                  * referenced only use the bit-wise AND operator "&".
13909                  */
13910                 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
13911                 ret = AscInitGetConfig(boardp) ? -ENODEV : 0;
13912         } else {
13913 #ifdef CONFIG_PCI
13914                 /*
13915                  * For Wide boards set PCI information before calling
13916                  * AdvInitGetConfig().
13917                  */
13918                 shost->unchecked_isa_dma = FALSE;
13919                 share_irq = IRQF_SHARED;
13920                 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
13921
13922                 ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0;
13923 #endif /* CONFIG_PCI */
13924         }
13925
13926         if (ret)
13927                 goto err_free_proc;
13928
13929         /*
13930          * Save the EEPROM configuration so that it can be displayed
13931          * from /proc/scsi/advansys/[0...].
13932          */
13933         if (ASC_NARROW_BOARD(boardp)) {
13934
13935                 ASCEEP_CONFIG *ep;
13936
13937                 /*
13938                  * Set the adapter's target id bit in the 'init_tidmask' field.
13939                  */
13940                 boardp->init_tidmask |=
13941                     ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
13942
13943                 /*
13944                  * Save EEPROM settings for the board.
13945                  */
13946                 ep = &boardp->eep_config.asc_eep;
13947
13948                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
13949                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
13950                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
13951                 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
13952                 ep->start_motor = asc_dvc_varp->start_motor;
13953                 ep->cntl = asc_dvc_varp->dvc_cntl;
13954                 ep->no_scam = asc_dvc_varp->no_scam;
13955                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
13956                 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
13957                 /* 'max_tag_qng' is set to the same value for every device. */
13958                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
13959                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
13960                 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
13961                 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
13962                 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
13963                 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
13964                 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
13965
13966                 /*
13967                  * Modify board configuration.
13968                  */
13969                 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
13970                 ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0;
13971                 if (ret)
13972                         goto err_free_proc;
13973         } else {
13974                 ADVEEP_3550_CONFIG *ep_3550;
13975                 ADVEEP_38C0800_CONFIG *ep_38C0800;
13976                 ADVEEP_38C1600_CONFIG *ep_38C1600;
13977
13978                 /*
13979                  * Save Wide EEP Configuration Information.
13980                  */
13981                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13982                         ep_3550 = &boardp->eep_config.adv_3550_eep;
13983
13984                         ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
13985                         ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
13986                         ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13987                         ep_3550->termination = adv_dvc_varp->cfg->termination;
13988                         ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
13989                         ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
13990                         ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
13991                         ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
13992                         ep_3550->ultra_able = adv_dvc_varp->ultra_able;
13993                         ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
13994                         ep_3550->start_motor = adv_dvc_varp->start_motor;
13995                         ep_3550->scsi_reset_delay =
13996                             adv_dvc_varp->scsi_reset_wait;
13997                         ep_3550->serial_number_word1 =
13998                             adv_dvc_varp->cfg->serial1;
13999                         ep_3550->serial_number_word2 =
14000                             adv_dvc_varp->cfg->serial2;
14001                         ep_3550->serial_number_word3 =
14002                             adv_dvc_varp->cfg->serial3;
14003                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
14004                         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
14005
14006                         ep_38C0800->adapter_scsi_id =
14007                             adv_dvc_varp->chip_scsi_id;
14008                         ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
14009                         ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14010                         ep_38C0800->termination_lvd =
14011                             adv_dvc_varp->cfg->termination;
14012                         ep_38C0800->disc_enable =
14013                             adv_dvc_varp->cfg->disc_enable;
14014                         ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
14015                         ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
14016                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14017                         ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14018                         ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14019                         ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14020                         ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14021                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
14022                         ep_38C0800->start_motor = adv_dvc_varp->start_motor;
14023                         ep_38C0800->scsi_reset_delay =
14024                             adv_dvc_varp->scsi_reset_wait;
14025                         ep_38C0800->serial_number_word1 =
14026                             adv_dvc_varp->cfg->serial1;
14027                         ep_38C0800->serial_number_word2 =
14028                             adv_dvc_varp->cfg->serial2;
14029                         ep_38C0800->serial_number_word3 =
14030                             adv_dvc_varp->cfg->serial3;
14031                 } else {
14032                         ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
14033
14034                         ep_38C1600->adapter_scsi_id =
14035                             adv_dvc_varp->chip_scsi_id;
14036                         ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
14037                         ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
14038                         ep_38C1600->termination_lvd =
14039                             adv_dvc_varp->cfg->termination;
14040                         ep_38C1600->disc_enable =
14041                             adv_dvc_varp->cfg->disc_enable;
14042                         ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
14043                         ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
14044                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14045                         ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
14046                         ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
14047                         ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
14048                         ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
14049                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
14050                         ep_38C1600->start_motor = adv_dvc_varp->start_motor;
14051                         ep_38C1600->scsi_reset_delay =
14052                             adv_dvc_varp->scsi_reset_wait;
14053                         ep_38C1600->serial_number_word1 =
14054                             adv_dvc_varp->cfg->serial1;
14055                         ep_38C1600->serial_number_word2 =
14056                             adv_dvc_varp->cfg->serial2;
14057                         ep_38C1600->serial_number_word3 =
14058                             adv_dvc_varp->cfg->serial3;
14059                 }
14060
14061                 /*
14062                  * Set the adapter's target id bit in the 'init_tidmask' field.
14063                  */
14064                 boardp->init_tidmask |=
14065                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
14066         }
14067
14068         /*
14069          * Channels are numbered beginning with 0. For AdvanSys one host
14070          * structure supports one channel. Multi-channel boards have a
14071          * separate host structure for each channel.
14072          */
14073         shost->max_channel = 0;
14074         if (ASC_NARROW_BOARD(boardp)) {
14075                 shost->max_id = ASC_MAX_TID + 1;
14076                 shost->max_lun = ASC_MAX_LUN + 1;
14077                 shost->max_cmd_len = ASC_MAX_CDB_LEN;
14078
14079                 shost->io_port = asc_dvc_varp->iop_base;
14080                 boardp->asc_n_io_port = ASC_IOADR_GAP;
14081                 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
14082
14083                 /* Set maximum number of queues the adapter can handle. */
14084                 shost->can_queue = asc_dvc_varp->max_total_qng;
14085         } else {
14086                 shost->max_id = ADV_MAX_TID + 1;
14087                 shost->max_lun = ADV_MAX_LUN + 1;
14088                 shost->max_cmd_len = ADV_MAX_CDB_LEN;
14089
14090                 /*
14091                  * Save the I/O Port address and length even though
14092                  * I/O ports are not used to access Wide boards.
14093                  * Instead the Wide boards are accessed with
14094                  * PCI Memory Mapped I/O.
14095                  */
14096                 shost->io_port = iop;
14097
14098                 shost->this_id = adv_dvc_varp->chip_scsi_id;
14099
14100                 /* Set maximum number of queues the adapter can handle. */
14101                 shost->can_queue = adv_dvc_varp->max_host_qng;
14102         }
14103
14104         /*
14105          * Following v1.3.89, 'cmd_per_lun' is no longer needed
14106          * and should be set to zero.
14107          *
14108          * But because of a bug introduced in v1.3.89 if the driver is
14109          * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
14110          * SCSI function 'allocate_device' will panic. To allow the driver
14111          * to work as a module in these kernels set 'cmd_per_lun' to 1.
14112          *
14113          * Note: This is wrong.  cmd_per_lun should be set to the depth
14114          * you want on untagged devices always.
14115          #ifdef MODULE
14116          */
14117         shost->cmd_per_lun = 1;
14118 /* #else
14119             shost->cmd_per_lun = 0;
14120 #endif */
14121
14122         /*
14123          * Set the maximum number of scatter-gather elements the
14124          * adapter can handle.
14125          */
14126         if (ASC_NARROW_BOARD(boardp)) {
14127                 /*
14128                  * Allow two commands with 'sg_tablesize' scatter-gather
14129                  * elements to be executed simultaneously. This value is
14130                  * the theoretical hardware limit. It may be decreased
14131                  * below.
14132                  */
14133                 shost->sg_tablesize =
14134                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
14135                      ASC_SG_LIST_PER_Q) + 1;
14136         } else {
14137                 shost->sg_tablesize = ADV_MAX_SG_LIST;
14138         }
14139
14140         /*
14141          * The value of 'sg_tablesize' can not exceed the SCSI
14142          * mid-level driver definition of SG_ALL. SG_ALL also
14143          * must not be exceeded, because it is used to define the
14144          * size of the scatter-gather table in 'struct asc_sg_head'.
14145          */
14146         if (shost->sg_tablesize > SG_ALL) {
14147                 shost->sg_tablesize = SG_ALL;
14148         }
14149
14150         ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
14151
14152         /* BIOS start address. */
14153         if (ASC_NARROW_BOARD(boardp)) {
14154                 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
14155                                                     asc_dvc_varp->bus_type);
14156         } else {
14157                 /*
14158                  * Fill-in BIOS board variables. The Wide BIOS saves
14159                  * information in LRAM that is used by the driver.
14160                  */
14161                 AdvReadWordLram(adv_dvc_varp->iop_base,
14162                                 BIOS_SIGNATURE, boardp->bios_signature);
14163                 AdvReadWordLram(adv_dvc_varp->iop_base,
14164                                 BIOS_VERSION, boardp->bios_version);
14165                 AdvReadWordLram(adv_dvc_varp->iop_base,
14166                                 BIOS_CODESEG, boardp->bios_codeseg);
14167                 AdvReadWordLram(adv_dvc_varp->iop_base,
14168                                 BIOS_CODELEN, boardp->bios_codelen);
14169
14170                 ASC_DBG2(1,
14171                          "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
14172                          boardp->bios_signature, boardp->bios_version);
14173
14174                 ASC_DBG2(1,
14175                          "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
14176                          boardp->bios_codeseg, boardp->bios_codelen);
14177
14178                 /*
14179                  * If the BIOS saved a valid signature, then fill in
14180                  * the BIOS code segment base address.
14181                  */
14182                 if (boardp->bios_signature == 0x55AA) {
14183                         /*
14184                          * Convert x86 realmode code segment to a linear
14185                          * address by shifting left 4.
14186                          */
14187                         shost->base = ((ulong)boardp->bios_codeseg << 4);
14188                 } else {
14189                         shost->base = 0;
14190                 }
14191         }
14192
14193         /*
14194          * Register Board Resources - I/O Port, DMA, IRQ
14195          */
14196
14197         /* Register DMA Channel for Narrow boards. */
14198         shost->dma_channel = NO_ISA_DMA;        /* Default to no ISA DMA. */
14199 #ifdef CONFIG_ISA
14200         if (ASC_NARROW_BOARD(boardp)) {
14201                 /* Register DMA channel for ISA bus. */
14202                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
14203                         shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
14204                         ret = request_dma(shost->dma_channel, DRV_NAME);
14205                         if (ret) {
14206                                 ASC_PRINT3
14207                                     ("advansys_board_found: board %d: request_dma() %d failed %d\n",
14208                                      boardp->id, shost->dma_channel, ret);
14209                                 goto err_free_proc;
14210                         }
14211                         AscEnableIsaDma(shost->dma_channel);
14212                 }
14213         }
14214 #endif /* CONFIG_ISA */
14215
14216         /* Register IRQ Number. */
14217         ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", boardp->irq);
14218
14219         ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
14220                           DRV_NAME, shost);
14221
14222         if (ret) {
14223                 if (ret == -EBUSY) {
14224                         ASC_PRINT2
14225                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
14226                              boardp->id, boardp->irq);
14227                 } else if (ret == -EINVAL) {
14228                         ASC_PRINT2
14229                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
14230                              boardp->id, boardp->irq);
14231                 } else {
14232                         ASC_PRINT3
14233                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
14234                              boardp->id, boardp->irq, ret);
14235                 }
14236                 goto err_free_dma;
14237         }
14238
14239         /*
14240          * Initialize board RISC chip and enable interrupts.
14241          */
14242         if (ASC_NARROW_BOARD(boardp)) {
14243                 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
14244                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
14245
14246                 if (warn_code || asc_dvc_varp->err_code) {
14247                         ASC_PRINT4("advansys_board_found: board %d error: "
14248                                    "init_state 0x%x, warn 0x%x, error 0x%x\n",
14249                                    boardp->id, asc_dvc_varp->init_state,
14250                                    warn_code, asc_dvc_varp->err_code);
14251                         if (asc_dvc_varp->err_code)
14252                                 ret = -ENODEV;
14253                 }
14254         } else {
14255                 if (advansys_wide_init_chip(boardp, adv_dvc_varp))
14256                         ret = -ENODEV;
14257         }
14258
14259         if (ret)
14260                 goto err_free_wide_mem;
14261
14262         ASC_DBG_PRT_SCSI_HOST(2, shost);
14263
14264         ret = scsi_add_host(shost, boardp->dev);
14265         if (ret)
14266                 goto err_free_wide_mem;
14267
14268         scsi_scan_host(shost);
14269         return 0;
14270
14271  err_free_wide_mem:
14272         advansys_wide_free_mem(boardp);
14273         free_irq(boardp->irq, shost);
14274  err_free_dma:
14275         if (shost->dma_channel != NO_ISA_DMA)
14276                 free_dma(shost->dma_channel);
14277  err_free_proc:
14278         kfree(boardp->prtbuf);
14279  err_unmap:
14280         if (boardp->ioremap_addr)
14281                 iounmap(boardp->ioremap_addr);
14282  err_shost:
14283         return ret;
14284 }
14285
14286 /*
14287  * advansys_release()
14288  *
14289  * Release resources allocated for a single AdvanSys adapter.
14290  */
14291 static int advansys_release(struct Scsi_Host *shost)
14292 {
14293         asc_board_t *boardp;
14294
14295         ASC_DBG(1, "advansys_release: begin\n");
14296         scsi_remove_host(shost);
14297         boardp = ASC_BOARDP(shost);
14298         free_irq(boardp->irq, shost);
14299         if (shost->dma_channel != NO_ISA_DMA) {
14300                 ASC_DBG(1, "advansys_release: free_dma()\n");
14301                 free_dma(shost->dma_channel);
14302         }
14303         if (!ASC_NARROW_BOARD(boardp)) {
14304                 iounmap(boardp->ioremap_addr);
14305                 advansys_wide_free_mem(boardp);
14306         }
14307         kfree(boardp->prtbuf);
14308         scsi_host_put(shost);
14309         ASC_DBG(1, "advansys_release: end\n");
14310         return 0;
14311 }
14312
14313 #define ASC_IOADR_TABLE_MAX_IX  11
14314
14315 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
14316         0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
14317         0x0210, 0x0230, 0x0250, 0x0330
14318 };
14319
14320 /*
14321  * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw.  It decodes as:
14322  * 00: 10
14323  * 01: 11
14324  * 10: 12
14325  * 11: 15
14326  */
14327 static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
14328 {
14329         unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14330         unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
14331         if (chip_irq == 13)
14332                 chip_irq = 15;
14333         return chip_irq;
14334 }
14335
14336 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
14337 {
14338         int err = -ENODEV;
14339         PortAddr iop_base = _asc_def_iop_base[id];
14340         struct Scsi_Host *shost;
14341         struct asc_board *board;
14342
14343         if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14344                 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
14345                          iop_base);
14346                 return -ENODEV;
14347         }
14348         ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
14349         if (!AscFindSignature(iop_base))
14350                 goto release_region;
14351         if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
14352                 goto release_region;
14353
14354         err = -ENOMEM;
14355         shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14356         if (!shost)
14357                 goto release_region;
14358
14359         board = ASC_BOARDP(shost);
14360         board->irq = advansys_isa_irq_no(iop_base);
14361         board->dev = dev;
14362
14363         err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
14364         if (err)
14365                 goto free_host;
14366
14367         dev_set_drvdata(dev, shost);
14368         return 0;
14369
14370  free_host:
14371         scsi_host_put(shost);
14372  release_region:
14373         release_region(iop_base, ASC_IOADR_GAP);
14374         return err;
14375 }
14376
14377 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
14378 {
14379         int ioport = _asc_def_iop_base[id];
14380         advansys_release(dev_get_drvdata(dev));
14381         release_region(ioport, ASC_IOADR_GAP);
14382         return 0;
14383 }
14384
14385 static struct isa_driver advansys_isa_driver = {
14386         .probe          = advansys_isa_probe,
14387         .remove         = __devexit_p(advansys_isa_remove),
14388         .driver = {
14389                 .owner  = THIS_MODULE,
14390                 .name   = DRV_NAME,
14391         },
14392 };
14393
14394 /*
14395  * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw.  It decodes as:
14396  * 000: invalid
14397  * 001: 10
14398  * 010: 11
14399  * 011: 12
14400  * 100: invalid
14401  * 101: 14
14402  * 110: 15
14403  * 111: invalid
14404  */
14405 static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
14406 {
14407         unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14408         unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
14409         if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
14410                 return 0;
14411         return chip_irq;
14412 }
14413
14414 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14415 {
14416         int err = -ENODEV;
14417         PortAddr iop_base = _asc_def_iop_base[id];
14418         struct Scsi_Host *shost;
14419         struct asc_board *board;
14420
14421         if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14422                 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
14423                          iop_base);
14424                 return -ENODEV;
14425         }
14426         ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
14427         if (!AscFindSignature(iop_base))
14428                 goto release_region;
14429         /*
14430          * I don't think this condition can actually happen, but the old
14431          * driver did it, and the chances of finding a VLB setup in 2007
14432          * to do testing with is slight to none.
14433          */
14434         if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14435                 goto release_region;
14436
14437         err = -ENOMEM;
14438         shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14439         if (!shost)
14440                 goto release_region;
14441
14442         board = ASC_BOARDP(shost);
14443         board->irq = advansys_vlb_irq_no(iop_base);
14444         board->dev = dev;
14445
14446         err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14447         if (err)
14448                 goto free_host;
14449
14450         dev_set_drvdata(dev, shost);
14451         return 0;
14452
14453  free_host:
14454         scsi_host_put(shost);
14455  release_region:
14456         release_region(iop_base, ASC_IOADR_GAP);
14457         return -ENODEV;
14458 }
14459
14460 static struct isa_driver advansys_vlb_driver = {
14461         .probe          = advansys_vlb_probe,
14462         .remove         = __devexit_p(advansys_isa_remove),
14463         .driver = {
14464                 .owner  = THIS_MODULE,
14465                 .name   = "advansys_vlb",
14466         },
14467 };
14468
14469 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14470         { "ABP7401" },
14471         { "ABP7501" },
14472         { "" }
14473 };
14474
14475 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14476
14477 /*
14478  * EISA is a little more tricky than PCI; each EISA device may have two
14479  * channels, and this driver is written to make each channel its own Scsi_Host
14480  */
14481 struct eisa_scsi_data {
14482         struct Scsi_Host *host[2];
14483 };
14484
14485 /*
14486  * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw.  It decodes as:
14487  * 000: 10
14488  * 001: 11
14489  * 010: 12
14490  * 011: invalid
14491  * 100: 14
14492  * 101: 15
14493  * 110: invalid
14494  * 111: invalid
14495  */
14496 static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14497 {
14498         unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
14499         unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
14500         if ((chip_irq == 13) || (chip_irq > 15))
14501                 return 0;
14502         return chip_irq;
14503 }
14504
14505 static int __devinit advansys_eisa_probe(struct device *dev)
14506 {
14507         int i, ioport, irq = 0;
14508         int err;
14509         struct eisa_device *edev = to_eisa_device(dev);
14510         struct eisa_scsi_data *data;
14511
14512         err = -ENOMEM;
14513         data = kzalloc(sizeof(*data), GFP_KERNEL);
14514         if (!data)
14515                 goto fail;
14516         ioport = edev->base_addr + 0xc30;
14517
14518         err = -ENODEV;
14519         for (i = 0; i < 2; i++, ioport += 0x20) {
14520                 struct asc_board *board;
14521                 struct Scsi_Host *shost;
14522                 if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
14523                         printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14524                                ioport + ASC_IOADR_GAP - 1);
14525                         continue;
14526                 }
14527                 if (!AscFindSignature(ioport)) {
14528                         release_region(ioport, ASC_IOADR_GAP);
14529                         continue;
14530                 }
14531
14532                 /*
14533                  * I don't know why we need to do this for EISA chips, but
14534                  * not for any others.  It looks to be equivalent to
14535                  * AscGetChipCfgMsw, but I may have overlooked something,
14536                  * so I'm not converting it until I get an EISA board to
14537                  * test with.
14538                  */
14539                 inw(ioport + 4);
14540
14541                 if (!irq)
14542                         irq = advansys_eisa_irq_no(edev);
14543
14544                 err = -ENOMEM;
14545                 shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14546                 if (!shost)
14547                         goto release_region;
14548
14549                 board = ASC_BOARDP(shost);
14550                 board->irq = irq;
14551                 board->dev = dev;
14552
14553                 err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14554                 if (!err) {
14555                         data->host[i] = shost;
14556                         continue;
14557                 }
14558
14559                 scsi_host_put(shost);
14560  release_region:
14561                 release_region(ioport, ASC_IOADR_GAP);
14562                 break;
14563         }
14564
14565         if (err)
14566                 goto free_data;
14567         dev_set_drvdata(dev, data);
14568         return 0;
14569
14570  free_data:
14571         kfree(data->host[0]);
14572         kfree(data->host[1]);
14573         kfree(data);
14574  fail:
14575         return err;
14576 }
14577
14578 static __devexit int advansys_eisa_remove(struct device *dev)
14579 {
14580         int i;
14581         struct eisa_scsi_data *data = dev_get_drvdata(dev);
14582
14583         for (i = 0; i < 2; i++) {
14584                 int ioport;
14585                 struct Scsi_Host *shost = data->host[i];
14586                 if (!shost)
14587                         continue;
14588                 ioport = shost->io_port;
14589                 advansys_release(shost);
14590                 release_region(ioport, ASC_IOADR_GAP);
14591         }
14592
14593         kfree(data);
14594         return 0;
14595 }
14596
14597 static struct eisa_driver advansys_eisa_driver = {
14598         .id_table =             advansys_eisa_table,
14599         .driver = {
14600                 .name =         DRV_NAME,
14601                 .probe =        advansys_eisa_probe,
14602                 .remove =       __devexit_p(advansys_eisa_remove),
14603         }
14604 };
14605
14606 /* PCI Devices supported by this driver */
14607 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
14608         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14609          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14610         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14611          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14612         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14613          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14614         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14615          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14616         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14617          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14618         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14619          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14620         {}
14621 };
14622
14623 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
14624
14625 static void __devinit advansys_set_latency(struct pci_dev *pdev)
14626 {
14627         if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14628             (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14629                 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14630         } else {
14631                 u8 latency;
14632                 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14633                 if (latency < 0x20)
14634                         pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14635         }
14636 }
14637
14638 static int __devinit
14639 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14640 {
14641         int err, ioport;
14642         struct Scsi_Host *shost;
14643         struct asc_board *board;
14644
14645         err = pci_enable_device(pdev);
14646         if (err)
14647                 goto fail;
14648         err = pci_request_regions(pdev, DRV_NAME);
14649         if (err)
14650                 goto disable_device;
14651         pci_set_master(pdev);
14652         advansys_set_latency(pdev);
14653
14654         err = -ENODEV;
14655         if (pci_resource_len(pdev, 0) == 0)
14656                 goto release_region;
14657
14658         ioport = pci_resource_start(pdev, 0);
14659
14660         err = -ENOMEM;
14661         shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14662         if (!shost)
14663                 goto release_region;
14664
14665         board = ASC_BOARDP(shost);
14666         board->irq = pdev->irq;
14667         board->dev = &pdev->dev;
14668
14669         if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14670             pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14671             pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
14672                 board->flags |= ASC_IS_WIDE_BOARD;
14673         }
14674
14675         err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14676         if (err)
14677                 goto free_host;
14678
14679         pci_set_drvdata(pdev, shost);
14680         return 0;
14681
14682  free_host:
14683         scsi_host_put(shost);
14684  release_region:
14685         pci_release_regions(pdev);
14686  disable_device:
14687         pci_disable_device(pdev);
14688  fail:
14689         return err;
14690 }
14691
14692 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14693 {
14694         advansys_release(pci_get_drvdata(pdev));
14695         pci_release_regions(pdev);
14696         pci_disable_device(pdev);
14697 }
14698
14699 static struct pci_driver advansys_pci_driver = {
14700         .name =         DRV_NAME,
14701         .id_table =     advansys_pci_tbl,
14702         .probe =        advansys_pci_probe,
14703         .remove =       __devexit_p(advansys_pci_remove),
14704 };
14705
14706 static int __init advansys_init(void)
14707 {
14708         int error;
14709
14710         error = isa_register_driver(&advansys_isa_driver,
14711                                     ASC_IOADR_TABLE_MAX_IX);
14712         if (error)
14713                 goto fail;
14714
14715         error = isa_register_driver(&advansys_vlb_driver,
14716                                     ASC_IOADR_TABLE_MAX_IX);
14717         if (error)
14718                 goto unregister_isa;
14719
14720         error = eisa_driver_register(&advansys_eisa_driver);
14721         if (error)
14722                 goto unregister_vlb;
14723
14724         error = pci_register_driver(&advansys_pci_driver);
14725         if (error)
14726                 goto unregister_eisa;
14727
14728         return 0;
14729
14730  unregister_eisa:
14731         eisa_driver_unregister(&advansys_eisa_driver);
14732  unregister_vlb:
14733         isa_unregister_driver(&advansys_vlb_driver);
14734  unregister_isa:
14735         isa_unregister_driver(&advansys_isa_driver);
14736  fail:
14737         return error;
14738 }
14739
14740 static void __exit advansys_exit(void)
14741 {
14742         pci_unregister_driver(&advansys_pci_driver);
14743         eisa_driver_unregister(&advansys_eisa_driver);
14744         isa_unregister_driver(&advansys_vlb_driver);
14745         isa_unregister_driver(&advansys_isa_driver);
14746 }
14747
14748 module_init(advansys_init);
14749 module_exit(advansys_exit);
14750
14751 MODULE_LICENSE("GPL");