[SCSI] advansys: Create AdvBuildCarrierFreelist
[linux-2.6] / drivers / scsi / advansys.c
1 #define ASC_VERSION "3.4"       /* AdvanSys Driver Version */
2
3 /*
4  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5  *
6  * Copyright (c) 1995-2000 Advanced System Products, Inc.
7  * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8  * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
9  * All Rights Reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  */
16
17 /*
18  * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19  * changed its name to ConnectCom Solutions, Inc.
20  * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
21  */
22
23 #include <linux/module.h>
24 #include <linux/string.h>
25 #include <linux/kernel.h>
26 #include <linux/types.h>
27 #include <linux/ioport.h>
28 #include <linux/interrupt.h>
29 #include <linux/delay.h>
30 #include <linux/slab.h>
31 #include <linux/mm.h>
32 #include <linux/proc_fs.h>
33 #include <linux/init.h>
34 #include <linux/blkdev.h>
35 #include <linux/isa.h>
36 #include <linux/eisa.h>
37 #include <linux/pci.h>
38 #include <linux/spinlock.h>
39 #include <linux/dma-mapping.h>
40
41 #include <asm/io.h>
42 #include <asm/system.h>
43 #include <asm/dma.h>
44
45 #include <scsi/scsi_cmnd.h>
46 #include <scsi/scsi_device.h>
47 #include <scsi/scsi_tcq.h>
48 #include <scsi/scsi.h>
49 #include <scsi/scsi_host.h>
50
51 /* FIXME:
52  *
53  *  1. Although all of the necessary command mapping places have the
54  *     appropriate dma_map.. APIs, the driver still processes its internal
55  *     queue using bus_to_virt() and virt_to_bus() which are illegal under
56  *     the API.  The entire queue processing structure will need to be
57  *     altered to fix this.
58  *  2. Need to add memory mapping workaround. Test the memory mapping.
59  *     If it doesn't work revert to I/O port access. Can a test be done
60  *     safely?
61  *  3. Handle an interrupt not working. Keep an interrupt counter in
62  *     the interrupt handler. In the timeout function if the interrupt
63  *     has not occurred then print a message and run in polled mode.
64  *  4. Need to add support for target mode commands, cf. CAM XPT.
65  *  5. check DMA mapping functions for failure
66  *  6. Remove internal queueing
67  *  7. Use scsi_transport_spi
68  *  8. advansys_info is not safe against multiple simultaneous callers
69  *  9. Kill boardp->id
70  * 10. Add module_param to override ISA/VLB ioport array
71  */
72 #warning this driver is still not properly converted to the DMA API
73
74 /* Enable driver assertions. */
75 #define ADVANSYS_ASSERT
76
77 /* Enable driver /proc statistics. */
78 #define ADVANSYS_STATS
79
80 /* Enable driver tracing. */
81 /* #define ADVANSYS_DEBUG */
82
83 /*
84  * --- Asc Library Constants and Macros
85  */
86
87 #define ASC_LIB_VERSION_MAJOR  1
88 #define ASC_LIB_VERSION_MINOR  24
89 #define ASC_LIB_SERIAL_NUMBER  123
90
91 /*
92  * Portable Data Types
93  *
94  * Any instance where a 32-bit long or pointer type is assumed
95  * for precision or HW defined structures, the following define
96  * types must be used. In Linux the char, short, and int types
97  * are all consistent at 8, 16, and 32 bits respectively. Pointers
98  * and long types are 64 bits on Alpha and UltraSPARC.
99  */
100 #define ASC_PADDR __u32         /* Physical/Bus address data type. */
101 #define ASC_VADDR __u32         /* Virtual address data type. */
102 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
103 #define ASC_SDCNT __s32         /* Signed Data count type. */
104
105 /*
106  * These macros are used to convert a virtual address to a
107  * 32-bit value. This currently can be used on Linux Alpha
108  * which uses 64-bit virtual address but a 32-bit bus address.
109  * This is likely to break in the future, but doing this now
110  * will give us time to change the HW and FW to handle 64-bit
111  * addresses.
112  */
113 #define ASC_VADDR_TO_U32   virt_to_bus
114 #define ASC_U32_TO_VADDR   bus_to_virt
115
116 typedef unsigned char uchar;
117
118 #ifndef TRUE
119 #define TRUE     (1)
120 #endif
121 #ifndef FALSE
122 #define FALSE    (0)
123 #endif
124
125 #define EOF      (-1)
126 #define ERR      (-1)
127 #define UW_ERR   (uint)(0xFFFF)
128 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
129
130 #define  ASC_DVCLIB_CALL_DONE     (1)
131 #define  ASC_DVCLIB_CALL_FAILED   (0)
132 #define  ASC_DVCLIB_CALL_ERROR    (-1)
133
134 #define PCI_VENDOR_ID_ASP               0x10cd
135 #define PCI_DEVICE_ID_ASP_1200A         0x1100
136 #define PCI_DEVICE_ID_ASP_ABP940        0x1200
137 #define PCI_DEVICE_ID_ASP_ABP940U       0x1300
138 #define PCI_DEVICE_ID_ASP_ABP940UW      0x2300
139 #define PCI_DEVICE_ID_38C0800_REV1      0x2500
140 #define PCI_DEVICE_ID_38C1600_REV1      0x2700
141
142 /*
143  * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
144  * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
145  * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
146  * SRB structure.
147  */
148 #define CC_VERY_LONG_SG_LIST 0
149 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
150
151 #define PortAddr                 unsigned short /* port address size  */
152 #define inp(port)                inb(port)
153 #define outp(port, byte)         outb((byte), (port))
154
155 #define inpw(port)               inw(port)
156 #define outpw(port, word)        outw((word), (port))
157
158 #define ASC_MAX_SG_QUEUE    7
159 #define ASC_MAX_SG_LIST     255
160
161 #define ASC_CS_TYPE  unsigned short
162
163 #define ASC_IS_ISA          (0x0001)
164 #define ASC_IS_ISAPNP       (0x0081)
165 #define ASC_IS_EISA         (0x0002)
166 #define ASC_IS_PCI          (0x0004)
167 #define ASC_IS_PCI_ULTRA    (0x0104)
168 #define ASC_IS_PCMCIA       (0x0008)
169 #define ASC_IS_MCA          (0x0020)
170 #define ASC_IS_VL           (0x0040)
171 #define ASC_ISA_PNP_PORT_ADDR  (0x279)
172 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
173 #define ASC_IS_WIDESCSI_16  (0x0100)
174 #define ASC_IS_WIDESCSI_32  (0x0200)
175 #define ASC_IS_BIG_ENDIAN   (0x8000)
176 #define ASC_CHIP_MIN_VER_VL      (0x01)
177 #define ASC_CHIP_MAX_VER_VL      (0x07)
178 #define ASC_CHIP_MIN_VER_PCI     (0x09)
179 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
180 #define ASC_CHIP_VER_PCI_BIT     (0x08)
181 #define ASC_CHIP_MIN_VER_ISA     (0x11)
182 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
183 #define ASC_CHIP_MAX_VER_ISA     (0x27)
184 #define ASC_CHIP_VER_ISA_BIT     (0x30)
185 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
186 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
187 #define ASC_CHIP_VER_PCI             0x08
188 #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
189 #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
190 #define ASC_CHIP_MIN_VER_EISA (0x41)
191 #define ASC_CHIP_MAX_VER_EISA (0x47)
192 #define ASC_CHIP_VER_EISA_BIT (0x40)
193 #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
194 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
195 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
196 #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
197 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
198 #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
199 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
200 #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
201 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
202 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
203 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
204
205 #define ASC_SCSI_ID_BITS  3
206 #define ASC_SCSI_TIX_TYPE     uchar
207 #define ASC_ALL_DEVICE_BIT_SET  0xFF
208 #define ASC_SCSI_BIT_ID_TYPE  uchar
209 #define ASC_MAX_TID       7
210 #define ASC_MAX_LUN       7
211 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
212 #define ASC_MAX_SENSE_LEN   32
213 #define ASC_MIN_SENSE_LEN   14
214 #define ASC_MAX_CDB_LEN     12
215 #define ASC_SCSI_RESET_HOLD_TIME_US  60
216
217 /*
218  * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
219  * and CmdDt (Command Support Data) field bit definitions.
220  */
221 #define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
222 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
223 #define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
224 #define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
225
226 #define ASC_SCSIDIR_NOCHK    0x00
227 #define ASC_SCSIDIR_T2H      0x08
228 #define ASC_SCSIDIR_H2T      0x10
229 #define ASC_SCSIDIR_NODATA   0x18
230 #define SCSI_ASC_NOMEDIA          0x3A
231 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
232 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
233 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
234 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
235 #define MS_SDTR_LEN    0x03
236 #define MS_WDTR_LEN    0x02
237
238 #define ASC_SG_LIST_PER_Q   7
239 #define QS_FREE        0x00
240 #define QS_READY       0x01
241 #define QS_DISC1       0x02
242 #define QS_DISC2       0x04
243 #define QS_BUSY        0x08
244 #define QS_ABORTED     0x40
245 #define QS_DONE        0x80
246 #define QC_NO_CALLBACK   0x01
247 #define QC_SG_SWAP_QUEUE 0x02
248 #define QC_SG_HEAD       0x04
249 #define QC_DATA_IN       0x08
250 #define QC_DATA_OUT      0x10
251 #define QC_URGENT        0x20
252 #define QC_MSG_OUT       0x40
253 #define QC_REQ_SENSE     0x80
254 #define QCSG_SG_XFER_LIST  0x02
255 #define QCSG_SG_XFER_MORE  0x04
256 #define QCSG_SG_XFER_END   0x08
257 #define QD_IN_PROGRESS       0x00
258 #define QD_NO_ERROR          0x01
259 #define QD_ABORTED_BY_HOST   0x02
260 #define QD_WITH_ERROR        0x04
261 #define QD_INVALID_REQUEST   0x80
262 #define QD_INVALID_HOST_NUM  0x81
263 #define QD_INVALID_DEVICE    0x82
264 #define QD_ERR_INTERNAL      0xFF
265 #define QHSTA_NO_ERROR               0x00
266 #define QHSTA_M_SEL_TIMEOUT          0x11
267 #define QHSTA_M_DATA_OVER_RUN        0x12
268 #define QHSTA_M_DATA_UNDER_RUN       0x12
269 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
270 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
271 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
272 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
273 #define QHSTA_D_HOST_ABORT_FAILED       0x23
274 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
275 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
276 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
277 #define QHSTA_M_WTM_TIMEOUT         0x41
278 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
279 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
280 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
281 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
282 #define QHSTA_M_BAD_TAG_CODE        0x46
283 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
284 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
285 #define QHSTA_D_LRAM_CMP_ERROR        0x81
286 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
287 #define ASC_FLAG_SCSIQ_REQ        0x01
288 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
289 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
290 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
291 #define ASC_FLAG_WIN16            0x10
292 #define ASC_FLAG_WIN32            0x20
293 #define ASC_FLAG_ISA_OVER_16MB    0x40
294 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
295 #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
296 #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
297 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
298 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
299 #define ASC_SCSIQ_CPY_BEG              4
300 #define ASC_SCSIQ_SGHD_CPY_BEG         2
301 #define ASC_SCSIQ_B_FWD                0
302 #define ASC_SCSIQ_B_BWD                1
303 #define ASC_SCSIQ_B_STATUS             2
304 #define ASC_SCSIQ_B_QNO                3
305 #define ASC_SCSIQ_B_CNTL               4
306 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
307 #define ASC_SCSIQ_D_DATA_ADDR          8
308 #define ASC_SCSIQ_D_DATA_CNT          12
309 #define ASC_SCSIQ_B_SENSE_LEN         20
310 #define ASC_SCSIQ_DONE_INFO_BEG       22
311 #define ASC_SCSIQ_D_SRBPTR            22
312 #define ASC_SCSIQ_B_TARGET_IX         26
313 #define ASC_SCSIQ_B_CDB_LEN           28
314 #define ASC_SCSIQ_B_TAG_CODE          29
315 #define ASC_SCSIQ_W_VM_ID             30
316 #define ASC_SCSIQ_DONE_STATUS         32
317 #define ASC_SCSIQ_HOST_STATUS         33
318 #define ASC_SCSIQ_SCSI_STATUS         34
319 #define ASC_SCSIQ_CDB_BEG             36
320 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
321 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
322 #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
323 #define ASC_SCSIQ_B_SG_WK_QP          49
324 #define ASC_SCSIQ_B_SG_WK_IX          50
325 #define ASC_SCSIQ_W_ALT_DC1           52
326 #define ASC_SCSIQ_B_LIST_CNT          6
327 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
328 #define ASC_SGQ_B_SG_CNTL             4
329 #define ASC_SGQ_B_SG_HEAD_QP          5
330 #define ASC_SGQ_B_SG_LIST_CNT         6
331 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
332 #define ASC_SGQ_LIST_BEG              8
333 #define ASC_DEF_SCSI1_QNG    4
334 #define ASC_MAX_SCSI1_QNG    4
335 #define ASC_DEF_SCSI2_QNG    16
336 #define ASC_MAX_SCSI2_QNG    32
337 #define ASC_TAG_CODE_MASK    0x23
338 #define ASC_STOP_REQ_RISC_STOP      0x01
339 #define ASC_STOP_ACK_RISC_STOP      0x03
340 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
341 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
342 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
343 #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
344 #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
345 #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
346 #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
347 #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
348 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
349 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
350
351 typedef struct asc_scsiq_1 {
352         uchar status;
353         uchar q_no;
354         uchar cntl;
355         uchar sg_queue_cnt;
356         uchar target_id;
357         uchar target_lun;
358         ASC_PADDR data_addr;
359         ASC_DCNT data_cnt;
360         ASC_PADDR sense_addr;
361         uchar sense_len;
362         uchar extra_bytes;
363 } ASC_SCSIQ_1;
364
365 typedef struct asc_scsiq_2 {
366         ASC_VADDR srb_ptr;
367         uchar target_ix;
368         uchar flag;
369         uchar cdb_len;
370         uchar tag_code;
371         ushort vm_id;
372 } ASC_SCSIQ_2;
373
374 typedef struct asc_scsiq_3 {
375         uchar done_stat;
376         uchar host_stat;
377         uchar scsi_stat;
378         uchar scsi_msg;
379 } ASC_SCSIQ_3;
380
381 typedef struct asc_scsiq_4 {
382         uchar cdb[ASC_MAX_CDB_LEN];
383         uchar y_first_sg_list_qp;
384         uchar y_working_sg_qp;
385         uchar y_working_sg_ix;
386         uchar y_res;
387         ushort x_req_count;
388         ushort x_reconnect_rtn;
389         ASC_PADDR x_saved_data_addr;
390         ASC_DCNT x_saved_data_cnt;
391 } ASC_SCSIQ_4;
392
393 typedef struct asc_q_done_info {
394         ASC_SCSIQ_2 d2;
395         ASC_SCSIQ_3 d3;
396         uchar q_status;
397         uchar q_no;
398         uchar cntl;
399         uchar sense_len;
400         uchar extra_bytes;
401         uchar res;
402         ASC_DCNT remain_bytes;
403 } ASC_QDONE_INFO;
404
405 typedef struct asc_sg_list {
406         ASC_PADDR addr;
407         ASC_DCNT bytes;
408 } ASC_SG_LIST;
409
410 typedef struct asc_sg_head {
411         ushort entry_cnt;
412         ushort queue_cnt;
413         ushort entry_to_copy;
414         ushort res;
415         ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
416 } ASC_SG_HEAD;
417
418 #define ASC_MIN_SG_LIST   2
419
420 typedef struct asc_min_sg_head {
421         ushort entry_cnt;
422         ushort queue_cnt;
423         ushort entry_to_copy;
424         ushort res;
425         ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
426 } ASC_MIN_SG_HEAD;
427
428 #define QCX_SORT        (0x0001)
429 #define QCX_COALEASE    (0x0002)
430
431 typedef struct asc_scsi_q {
432         ASC_SCSIQ_1 q1;
433         ASC_SCSIQ_2 q2;
434         uchar *cdbptr;
435         ASC_SG_HEAD *sg_head;
436         ushort remain_sg_entry_cnt;
437         ushort next_sg_index;
438 } ASC_SCSI_Q;
439
440 typedef struct asc_scsi_req_q {
441         ASC_SCSIQ_1 r1;
442         ASC_SCSIQ_2 r2;
443         uchar *cdbptr;
444         ASC_SG_HEAD *sg_head;
445         uchar *sense_ptr;
446         ASC_SCSIQ_3 r3;
447         uchar cdb[ASC_MAX_CDB_LEN];
448         uchar sense[ASC_MIN_SENSE_LEN];
449 } ASC_SCSI_REQ_Q;
450
451 typedef struct asc_scsi_bios_req_q {
452         ASC_SCSIQ_1 r1;
453         ASC_SCSIQ_2 r2;
454         uchar *cdbptr;
455         ASC_SG_HEAD *sg_head;
456         uchar *sense_ptr;
457         ASC_SCSIQ_3 r3;
458         uchar cdb[ASC_MAX_CDB_LEN];
459         uchar sense[ASC_MIN_SENSE_LEN];
460 } ASC_SCSI_BIOS_REQ_Q;
461
462 typedef struct asc_risc_q {
463         uchar fwd;
464         uchar bwd;
465         ASC_SCSIQ_1 i1;
466         ASC_SCSIQ_2 i2;
467         ASC_SCSIQ_3 i3;
468         ASC_SCSIQ_4 i4;
469 } ASC_RISC_Q;
470
471 typedef struct asc_sg_list_q {
472         uchar seq_no;
473         uchar q_no;
474         uchar cntl;
475         uchar sg_head_qp;
476         uchar sg_list_cnt;
477         uchar sg_cur_list_cnt;
478 } ASC_SG_LIST_Q;
479
480 typedef struct asc_risc_sg_list_q {
481         uchar fwd;
482         uchar bwd;
483         ASC_SG_LIST_Q sg;
484         ASC_SG_LIST sg_list[7];
485 } ASC_RISC_SG_LIST_Q;
486
487 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
488 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
489 #define ASCQ_ERR_NO_ERROR             0
490 #define ASCQ_ERR_IO_NOT_FOUND         1
491 #define ASCQ_ERR_LOCAL_MEM            2
492 #define ASCQ_ERR_CHKSUM               3
493 #define ASCQ_ERR_START_CHIP           4
494 #define ASCQ_ERR_INT_TARGET_ID        5
495 #define ASCQ_ERR_INT_LOCAL_MEM        6
496 #define ASCQ_ERR_HALT_RISC            7
497 #define ASCQ_ERR_GET_ASPI_ENTRY       8
498 #define ASCQ_ERR_CLOSE_ASPI           9
499 #define ASCQ_ERR_HOST_INQUIRY         0x0A
500 #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
501 #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
502 #define ASCQ_ERR_Q_STATUS             0x0D
503 #define ASCQ_ERR_WR_SCSIQ             0x0E
504 #define ASCQ_ERR_PC_ADDR              0x0F
505 #define ASCQ_ERR_SYN_OFFSET           0x10
506 #define ASCQ_ERR_SYN_XFER_TIME        0x11
507 #define ASCQ_ERR_LOCK_DMA             0x12
508 #define ASCQ_ERR_UNLOCK_DMA           0x13
509 #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
510 #define ASCQ_ERR_MICRO_CODE_HALT      0x15
511 #define ASCQ_ERR_SET_LRAM_ADDR        0x16
512 #define ASCQ_ERR_CUR_QNG              0x17
513 #define ASCQ_ERR_SG_Q_LINKS           0x18
514 #define ASCQ_ERR_SCSIQ_PTR            0x19
515 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
516 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
517 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
518 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
519 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
520 #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
521 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
522 #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
523 #define ASCQ_ERR_SEND_SCSI_Q          0x22
524 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
525 #define ASCQ_ERR_RESET_SDTR           0x24
526
527 /*
528  * Warning code values are set in ASC_DVC_VAR  'warn_code'.
529  */
530 #define ASC_WARN_NO_ERROR             0x0000
531 #define ASC_WARN_IO_PORT_ROTATE       0x0001
532 #define ASC_WARN_EEPROM_CHKSUM        0x0002
533 #define ASC_WARN_IRQ_MODIFIED         0x0004
534 #define ASC_WARN_AUTO_CONFIG          0x0008
535 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
536 #define ASC_WARN_EEPROM_RECOVER       0x0020
537 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
538 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
539
540 /*
541  * Error code values are set in ASC_DVC_VAR  'err_code'.
542  */
543 #define ASC_IERR_WRITE_EEPROM         0x0001
544 #define ASC_IERR_MCODE_CHKSUM         0x0002
545 #define ASC_IERR_SET_PC_ADDR          0x0004
546 #define ASC_IERR_START_STOP_CHIP      0x0008
547 #define ASC_IERR_IRQ_NO               0x0010
548 #define ASC_IERR_SET_IRQ_NO           0x0020
549 #define ASC_IERR_CHIP_VERSION         0x0040
550 #define ASC_IERR_SET_SCSI_ID          0x0080
551 #define ASC_IERR_GET_PHY_ADDR         0x0100
552 #define ASC_IERR_BAD_SIGNATURE        0x0200
553 #define ASC_IERR_NO_BUS_TYPE          0x0400
554 #define ASC_IERR_SCAM                 0x0800
555 #define ASC_IERR_SET_SDTR             0x1000
556 #define ASC_IERR_RW_LRAM              0x8000
557
558 #define ASC_DEF_IRQ_NO  10
559 #define ASC_MAX_IRQ_NO  15
560 #define ASC_MIN_IRQ_NO  10
561 #define ASC_MIN_REMAIN_Q        (0x02)
562 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
563 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
564 #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
565 #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
566 #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
567 #define ASC_MAX_TOTAL_QNG 240
568 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
569 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
570 #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
571 #define ASC_MAX_INRAM_TAG_QNG   16
572 #define ASC_IOADR_TABLE_MAX_IX  11
573 #define ASC_IOADR_GAP   0x10
574 #define ASC_LIB_SCSIQ_WK_SP        256
575 #define ASC_MAX_SYN_XFER_NO        16
576 #define ASC_SYN_MAX_OFFSET         0x0F
577 #define ASC_DEF_SDTR_OFFSET        0x0F
578 #define ASC_DEF_SDTR_INDEX         0x00
579 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
580 #define SYN_XFER_NS_0  25
581 #define SYN_XFER_NS_1  30
582 #define SYN_XFER_NS_2  35
583 #define SYN_XFER_NS_3  40
584 #define SYN_XFER_NS_4  50
585 #define SYN_XFER_NS_5  60
586 #define SYN_XFER_NS_6  70
587 #define SYN_XFER_NS_7  85
588 #define SYN_ULTRA_XFER_NS_0    12
589 #define SYN_ULTRA_XFER_NS_1    19
590 #define SYN_ULTRA_XFER_NS_2    25
591 #define SYN_ULTRA_XFER_NS_3    32
592 #define SYN_ULTRA_XFER_NS_4    38
593 #define SYN_ULTRA_XFER_NS_5    44
594 #define SYN_ULTRA_XFER_NS_6    50
595 #define SYN_ULTRA_XFER_NS_7    57
596 #define SYN_ULTRA_XFER_NS_8    63
597 #define SYN_ULTRA_XFER_NS_9    69
598 #define SYN_ULTRA_XFER_NS_10   75
599 #define SYN_ULTRA_XFER_NS_11   82
600 #define SYN_ULTRA_XFER_NS_12   88
601 #define SYN_ULTRA_XFER_NS_13   94
602 #define SYN_ULTRA_XFER_NS_14  100
603 #define SYN_ULTRA_XFER_NS_15  107
604
605 typedef struct ext_msg {
606         uchar msg_type;
607         uchar msg_len;
608         uchar msg_req;
609         union {
610                 struct {
611                         uchar sdtr_xfer_period;
612                         uchar sdtr_req_ack_offset;
613                 } sdtr;
614                 struct {
615                         uchar wdtr_width;
616                 } wdtr;
617                 struct {
618                         uchar mdp_b3;
619                         uchar mdp_b2;
620                         uchar mdp_b1;
621                         uchar mdp_b0;
622                 } mdp;
623         } u_ext_msg;
624         uchar res;
625 } EXT_MSG;
626
627 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
628 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
629 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
630 #define mdp_b3          u_ext_msg.mdp_b3
631 #define mdp_b2          u_ext_msg.mdp_b2
632 #define mdp_b1          u_ext_msg.mdp_b1
633 #define mdp_b0          u_ext_msg.mdp_b0
634
635 typedef struct asc_dvc_cfg {
636         ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
637         ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
638         ASC_SCSI_BIT_ID_TYPE disc_enable;
639         ASC_SCSI_BIT_ID_TYPE sdtr_enable;
640         uchar chip_scsi_id;
641         uchar isa_dma_speed;
642         uchar isa_dma_channel;
643         uchar chip_version;
644         ushort lib_serial_no;
645         ushort lib_version;
646         ushort mcode_date;
647         ushort mcode_version;
648         uchar max_tag_qng[ASC_MAX_TID + 1];
649         uchar *overrun_buf;
650         uchar sdtr_period_offset[ASC_MAX_TID + 1];
651         uchar adapter_info[6];
652 } ASC_DVC_CFG;
653
654 #define ASC_DEF_DVC_CNTL       0xFFFF
655 #define ASC_DEF_CHIP_SCSI_ID   7
656 #define ASC_DEF_ISA_DMA_SPEED  4
657 #define ASC_INIT_STATE_NULL          0x0000
658 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
659 #define ASC_INIT_STATE_END_GET_CFG   0x0002
660 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
661 #define ASC_INIT_STATE_END_SET_CFG   0x0008
662 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
663 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
664 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
665 #define ASC_INIT_STATE_END_INQUIRY   0x0080
666 #define ASC_INIT_RESET_SCSI_DONE     0x0100
667 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
668 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
669 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
670 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
671 #define ASC_MIN_TAGGED_CMD  7
672 #define ASC_MAX_SCSI_RESET_WAIT      30
673
674 struct asc_dvc_var;             /* Forward Declaration. */
675
676 typedef struct asc_dvc_var {
677         PortAddr iop_base;
678         ushort err_code;
679         ushort dvc_cntl;
680         ushort bug_fix_cntl;
681         ushort bus_type;
682         ASC_SCSI_BIT_ID_TYPE init_sdtr;
683         ASC_SCSI_BIT_ID_TYPE sdtr_done;
684         ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
685         ASC_SCSI_BIT_ID_TYPE unit_not_ready;
686         ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
687         ASC_SCSI_BIT_ID_TYPE start_motor;
688         uchar scsi_reset_wait;
689         uchar chip_no;
690         char is_in_int;
691         uchar max_total_qng;
692         uchar cur_total_qng;
693         uchar in_critical_cnt;
694         uchar irq_no;
695         uchar last_q_shortage;
696         ushort init_state;
697         uchar cur_dvc_qng[ASC_MAX_TID + 1];
698         uchar max_dvc_qng[ASC_MAX_TID + 1];
699         ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
700         ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
701         uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
702         ASC_DVC_CFG *cfg;
703         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
704         char redo_scam;
705         ushort res2;
706         uchar dos_int13_table[ASC_MAX_TID + 1];
707         ASC_DCNT max_dma_count;
708         ASC_SCSI_BIT_ID_TYPE no_scam;
709         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
710         uchar max_sdtr_index;
711         uchar host_init_sdtr_index;
712         struct asc_board *drv_ptr;
713         ASC_DCNT uc_break;
714 } ASC_DVC_VAR;
715
716 typedef struct asc_dvc_inq_info {
717         uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
718 } ASC_DVC_INQ_INFO;
719
720 typedef struct asc_cap_info {
721         ASC_DCNT lba;
722         ASC_DCNT blk_size;
723 } ASC_CAP_INFO;
724
725 typedef struct asc_cap_info_array {
726         ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
727 } ASC_CAP_INFO_ARRAY;
728
729 #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
730 #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
731 #define ASC_CNTL_INITIATOR         (ushort)0x0001
732 #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
733 #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
734 #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
735 #define ASC_CNTL_NO_SCAM           (ushort)0x0010
736 #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
737 #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
738 #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
739 #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
740 #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
741 #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
742 #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
743 #define ASC_CNTL_BURST_MODE        (ushort)0x2000
744 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
745 #define ASC_EEP_DVC_CFG_BEG_VL    2
746 #define ASC_EEP_MAX_DVC_ADDR_VL   15
747 #define ASC_EEP_DVC_CFG_BEG      32
748 #define ASC_EEP_MAX_DVC_ADDR     45
749 #define ASC_EEP_DEFINED_WORDS    10
750 #define ASC_EEP_MAX_ADDR         63
751 #define ASC_EEP_RES_WORDS         0
752 #define ASC_EEP_MAX_RETRY        20
753 #define ASC_MAX_INIT_BUSY_RETRY   8
754 #define ASC_EEP_ISA_PNP_WSIZE    16
755
756 /*
757  * These macros keep the chip SCSI id and ISA DMA speed
758  * bitfields in board order. C bitfields aren't portable
759  * between big and little-endian platforms so they are
760  * not used.
761  */
762
763 #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
764 #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
765 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
766    ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
767 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
768    ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
769
770 typedef struct asceep_config {
771         ushort cfg_lsw;
772         ushort cfg_msw;
773         uchar init_sdtr;
774         uchar disc_enable;
775         uchar use_cmd_qng;
776         uchar start_motor;
777         uchar max_total_qng;
778         uchar max_tag_qng;
779         uchar bios_scan;
780         uchar power_up_wait;
781         uchar no_scam;
782         uchar id_speed;         /* low order 4 bits is chip scsi id */
783         /* high order 4 bits is isa dma speed */
784         uchar dos_int13_table[ASC_MAX_TID + 1];
785         uchar adapter_info[6];
786         ushort cntl;
787         ushort chksum;
788 } ASCEEP_CONFIG;
789
790 #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
791 #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
792 #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
793
794 #define ASC_EEP_CMD_READ          0x80
795 #define ASC_EEP_CMD_WRITE         0x40
796 #define ASC_EEP_CMD_WRITE_ABLE    0x30
797 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
798 #define ASC_OVERRUN_BSIZE  0x00000048UL
799 #define ASC_CTRL_BREAK_ONCE        0x0001
800 #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
801 #define ASCV_MSGOUT_BEG         0x0000
802 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
803 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
804 #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
805 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
806 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
807 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
808 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
809 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
810 #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
811 #define ASCV_BREAK_ADDR           (ushort)0x0028
812 #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
813 #define ASCV_BREAK_CONTROL        (ushort)0x002C
814 #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
815
816 #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
817 #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
818 #define ASCV_MCODE_SIZE_W     (ushort)0x0034
819 #define ASCV_STOP_CODE_B      (ushort)0x0036
820 #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
821 #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
822 #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
823 #define ASCV_HALTCODE_W       (ushort)0x0040
824 #define ASCV_CHKSUM_W         (ushort)0x0042
825 #define ASCV_MC_DATE_W        (ushort)0x0044
826 #define ASCV_MC_VER_W         (ushort)0x0046
827 #define ASCV_NEXTRDY_B        (ushort)0x0048
828 #define ASCV_DONENEXT_B       (ushort)0x0049
829 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
830 #define ASCV_SCSIBUSY_B       (ushort)0x004B
831 #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
832 #define ASCV_CURCDB_B         (ushort)0x004D
833 #define ASCV_RCLUN_B          (ushort)0x004E
834 #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
835 #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
836 #define ASCV_DISC_ENABLE_B    (ushort)0x0052
837 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
838 #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
839 #define ASCV_MCODE_CNTL_B     (ushort)0x0056
840 #define ASCV_NULL_TARGET_B    (ushort)0x0057
841 #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
842 #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
843 #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
844 #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
845 #define ASCV_HOST_FLAG_B      (ushort)0x005D
846 #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
847 #define ASCV_VER_SERIAL_B     (ushort)0x0065
848 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
849 #define ASCV_WTM_FLAG_B       (ushort)0x0068
850 #define ASCV_RISC_FLAG_B      (ushort)0x006A
851 #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
852 #define ASC_HOST_FLAG_IN_ISR        0x01
853 #define ASC_HOST_FLAG_ACK_INT       0x02
854 #define ASC_RISC_FLAG_GEN_INT      0x01
855 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
856 #define IOP_CTRL         (0x0F)
857 #define IOP_STATUS       (0x0E)
858 #define IOP_INT_ACK      IOP_STATUS
859 #define IOP_REG_IFC      (0x0D)
860 #define IOP_SYN_OFFSET    (0x0B)
861 #define IOP_EXTRA_CONTROL (0x0D)
862 #define IOP_REG_PC        (0x0C)
863 #define IOP_RAM_ADDR      (0x0A)
864 #define IOP_RAM_DATA      (0x08)
865 #define IOP_EEP_DATA      (0x06)
866 #define IOP_EEP_CMD       (0x07)
867 #define IOP_VERSION       (0x03)
868 #define IOP_CONFIG_HIGH   (0x04)
869 #define IOP_CONFIG_LOW    (0x02)
870 #define IOP_SIG_BYTE      (0x01)
871 #define IOP_SIG_WORD      (0x00)
872 #define IOP_REG_DC1      (0x0E)
873 #define IOP_REG_DC0      (0x0C)
874 #define IOP_REG_SB       (0x0B)
875 #define IOP_REG_DA1      (0x0A)
876 #define IOP_REG_DA0      (0x08)
877 #define IOP_REG_SC       (0x09)
878 #define IOP_DMA_SPEED    (0x07)
879 #define IOP_REG_FLAG     (0x07)
880 #define IOP_FIFO_H       (0x06)
881 #define IOP_FIFO_L       (0x04)
882 #define IOP_REG_ID       (0x05)
883 #define IOP_REG_QP       (0x03)
884 #define IOP_REG_IH       (0x02)
885 #define IOP_REG_IX       (0x01)
886 #define IOP_REG_AX       (0x00)
887 #define IFC_REG_LOCK      (0x00)
888 #define IFC_REG_UNLOCK    (0x09)
889 #define IFC_WR_EN_FILTER  (0x10)
890 #define IFC_RD_NO_EEPROM  (0x10)
891 #define IFC_SLEW_RATE     (0x20)
892 #define IFC_ACT_NEG       (0x40)
893 #define IFC_INP_FILTER    (0x80)
894 #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
895 #define SC_SEL   (uchar)(0x80)
896 #define SC_BSY   (uchar)(0x40)
897 #define SC_ACK   (uchar)(0x20)
898 #define SC_REQ   (uchar)(0x10)
899 #define SC_ATN   (uchar)(0x08)
900 #define SC_IO    (uchar)(0x04)
901 #define SC_CD    (uchar)(0x02)
902 #define SC_MSG   (uchar)(0x01)
903 #define SEC_SCSI_CTL         (uchar)(0x80)
904 #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
905 #define SEC_SLEW_RATE        (uchar)(0x20)
906 #define SEC_ENABLE_FILTER    (uchar)(0x10)
907 #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
908 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
909 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
910 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
911 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
912 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
913 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
914 #define ASC_MAX_QNO        0xF8
915 #define ASC_DATA_SEC_BEG   (ushort)0x0080
916 #define ASC_DATA_SEC_END   (ushort)0x0080
917 #define ASC_CODE_SEC_BEG   (ushort)0x0080
918 #define ASC_CODE_SEC_END   (ushort)0x0080
919 #define ASC_QADR_BEG       (0x4000)
920 #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
921 #define ASC_QADR_END       (ushort)0x7FFF
922 #define ASC_QLAST_ADR      (ushort)0x7FC0
923 #define ASC_QBLK_SIZE      0x40
924 #define ASC_BIOS_DATA_QBEG 0xF8
925 #define ASC_MIN_ACTIVE_QNO 0x01
926 #define ASC_QLINK_END      0xFF
927 #define ASC_EEPROM_WORDS   0x10
928 #define ASC_MAX_MGS_LEN    0x10
929 #define ASC_BIOS_ADDR_DEF  0xDC00
930 #define ASC_BIOS_SIZE      0x3800
931 #define ASC_BIOS_RAM_OFF   0x3800
932 #define ASC_BIOS_RAM_SIZE  0x800
933 #define ASC_BIOS_MIN_ADDR  0xC000
934 #define ASC_BIOS_MAX_ADDR  0xEC00
935 #define ASC_BIOS_BANK_SIZE 0x0400
936 #define ASC_MCODE_START_ADDR  0x0080
937 #define ASC_CFG0_HOST_INT_ON    0x0020
938 #define ASC_CFG0_BIOS_ON        0x0040
939 #define ASC_CFG0_VERA_BURST_ON  0x0080
940 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
941 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
942 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
943 #define ASC_CFG_MSW_CLR_MASK    0x3080
944 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
945 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
946 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
947 #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
948 #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
949 #define CSW_TEST2             (ASC_CS_TYPE)0x0400
950 #define CSW_TEST3             (ASC_CS_TYPE)0x0200
951 #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
952 #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
953 #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
954 #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
955 #define CSW_HALTED            (ASC_CS_TYPE)0x0010
956 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
957 #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
958 #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
959 #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
960 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
961 #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
962 #define CIW_TEST1        (ASC_CS_TYPE)0x0200
963 #define CIW_TEST2        (ASC_CS_TYPE)0x0400
964 #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
965 #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
966 #define CC_CHIP_RESET   (uchar)0x80
967 #define CC_SCSI_RESET   (uchar)0x40
968 #define CC_HALT         (uchar)0x20
969 #define CC_SINGLE_STEP  (uchar)0x10
970 #define CC_DMA_ABLE     (uchar)0x08
971 #define CC_TEST         (uchar)0x04
972 #define CC_BANK_ONE     (uchar)0x02
973 #define CC_DIAG         (uchar)0x01
974 #define ASC_1000_ID0W      0x04C1
975 #define ASC_1000_ID0W_FIX  0x00C1
976 #define ASC_1000_ID1B      0x25
977 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
978 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
979 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
980 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
981 #define INS_HALTINT        (ushort)0x6281
982 #define INS_HALT           (ushort)0x6280
983 #define INS_SINT           (ushort)0x6200
984 #define INS_RFLAG_WTM      (ushort)0x7380
985 #define ASC_MC_SAVE_CODE_WSIZE  0x500
986 #define ASC_MC_SAVE_DATA_WSIZE  0x40
987
988 typedef struct asc_mc_saved {
989         ushort data[ASC_MC_SAVE_DATA_WSIZE];
990         ushort code[ASC_MC_SAVE_CODE_WSIZE];
991 } ASC_MC_SAVED;
992
993 #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
994 #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
995 #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
996 #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
997 #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
998 #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
999 #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1000 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1001 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1002 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1003 #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1004 #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1005 #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1006 #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1007 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1008 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1009 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1010 #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1011 #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1012 #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1013 #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1014 #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1015 #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1016 #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1017 #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1018 #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1019 #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1020 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1021 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1022 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1023 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1024 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1025 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1026 #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1027 #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1028 #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1029 #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1030 #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1031 #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1032 #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1033 #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1034 #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1035 #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1036 #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1037 #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1038 #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1039 #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1040 #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1041 #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1042 #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1043 #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1044 #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1045 #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1046 #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1047 #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1048 #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1049 #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1050 #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1051 #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1052 #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1053 #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1054 #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1055 #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1056 #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1057 #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1058 #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
1059 #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
1060 #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
1061
1062 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1063 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1064 static void AscWaitEEPRead(void);
1065 static void AscWaitEEPWrite(void);
1066 static ushort AscReadEEPWord(PortAddr, uchar);
1067 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1068 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1069 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1070 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1071 static int AscStartChip(PortAddr);
1072 static int AscStopChip(PortAddr);
1073 static void AscSetChipIH(PortAddr, ushort);
1074 static int AscIsChipHalted(PortAddr);
1075 static void AscAckInterrupt(PortAddr);
1076 static void AscDisableInterrupt(PortAddr);
1077 static void AscEnableInterrupt(PortAddr);
1078 static void AscSetBank(PortAddr, uchar);
1079 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1080 #ifdef CONFIG_ISA
1081 static uchar AscGetIsaDmaSpeed(PortAddr);
1082 #endif /* CONFIG_ISA */
1083 static uchar AscReadLramByte(PortAddr, ushort);
1084 static ushort AscReadLramWord(PortAddr, ushort);
1085 #if CC_VERY_LONG_SG_LIST
1086 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1087 #endif /* CC_VERY_LONG_SG_LIST */
1088 static void AscWriteLramWord(PortAddr, ushort, ushort);
1089 static void AscWriteLramByte(PortAddr, ushort, uchar);
1090 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1091 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1092 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1093 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1094 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1095 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1096 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1097 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1098 static int AscTestExternalLram(ASC_DVC_VAR *);
1099 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1100 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1101 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1102 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1103 static uchar AscAllocFreeQueue(PortAddr, uchar);
1104 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1105 static int AscHostReqRiscHalt(PortAddr);
1106 static int AscStopQueueExe(PortAddr);
1107 static int AscSendScsiQueue(ASC_DVC_VAR *,
1108                             ASC_SCSI_Q *scsiq, uchar n_q_required);
1109 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1110 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1111 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1112 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1113 static ushort AscInitLram(ASC_DVC_VAR *);
1114 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1115 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1116 static int AscIsrChipHalted(ASC_DVC_VAR *);
1117 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1118                                    ASC_QDONE_INFO *, ASC_DCNT);
1119 static int AscIsrQDone(ASC_DVC_VAR *);
1120 #ifdef CONFIG_ISA
1121 static ushort AscGetEisaChipCfg(PortAddr);
1122 #endif /* CONFIG_ISA */
1123 static uchar AscGetChipScsiCtrl(PortAddr);
1124 static uchar AscGetChipVersion(PortAddr, ushort);
1125 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1126 static void AscToggleIRQAct(PortAddr);
1127 static inline ulong DvcEnterCritical(void);
1128 static inline void DvcLeaveCritical(ulong);
1129 static void DvcSleepMilliSecond(ASC_DCNT);
1130 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1131 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1132 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1133 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1134 static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
1135 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1136 static int AscISR(ASC_DVC_VAR *);
1137 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1138 static int AscSgListToQueue(int);
1139 #ifdef CONFIG_ISA
1140 static void AscEnableIsaDma(uchar);
1141 #endif /* CONFIG_ISA */
1142 static const char *advansys_info(struct Scsi_Host *shost);
1143
1144 /*
1145  * --- Adv Library Constants and Macros
1146  */
1147
1148 #define ADV_LIB_VERSION_MAJOR  5
1149 #define ADV_LIB_VERSION_MINOR  14
1150
1151 /*
1152  * Define Adv Library required special types.
1153  */
1154
1155 /*
1156  * Portable Data Types
1157  *
1158  * Any instance where a 32-bit long or pointer type is assumed
1159  * for precision or HW defined structures, the following define
1160  * types must be used. In Linux the char, short, and int types
1161  * are all consistent at 8, 16, and 32 bits respectively. Pointers
1162  * and long types are 64 bits on Alpha and UltraSPARC.
1163  */
1164 #define ADV_PADDR __u32         /* Physical address data type. */
1165 #define ADV_VADDR __u32         /* Virtual address data type. */
1166 #define ADV_DCNT  __u32         /* Unsigned Data count type. */
1167 #define ADV_SDCNT __s32         /* Signed Data count type. */
1168
1169 /*
1170  * These macros are used to convert a virtual address to a
1171  * 32-bit value. This currently can be used on Linux Alpha
1172  * which uses 64-bit virtual address but a 32-bit bus address.
1173  * This is likely to break in the future, but doing this now
1174  * will give us time to change the HW and FW to handle 64-bit
1175  * addresses.
1176  */
1177 #define ADV_VADDR_TO_U32   virt_to_bus
1178 #define ADV_U32_TO_VADDR   bus_to_virt
1179
1180 #define AdvPortAddr  void __iomem *     /* Virtual memory address size */
1181
1182 /*
1183  * Define Adv Library required memory access macros.
1184  */
1185 #define ADV_MEM_READB(addr) readb(addr)
1186 #define ADV_MEM_READW(addr) readw(addr)
1187 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
1188 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
1189 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
1190
1191 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
1192
1193 /*
1194  * For wide  boards a CDB length maximum of 16 bytes
1195  * is supported.
1196  */
1197 #define ADV_MAX_CDB_LEN     16
1198
1199 /*
1200  * Define total number of simultaneous maximum element scatter-gather
1201  * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
1202  * maximum number of outstanding commands per wide host adapter. Each
1203  * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
1204  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
1205  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
1206  * structures or 255 scatter-gather elements.
1207  *
1208  */
1209 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
1210
1211 /*
1212  * Define Adv Library required maximum number of scatter-gather
1213  * elements per request.
1214  */
1215 #define ADV_MAX_SG_LIST         255
1216
1217 /* Number of SG blocks needed. */
1218 #define ADV_NUM_SG_BLOCK \
1219     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
1220
1221 /* Total contiguous memory needed for SG blocks. */
1222 #define ADV_SG_TOTAL_MEM_SIZE \
1223     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
1224
1225 #define ADV_PAGE_SIZE PAGE_SIZE
1226
1227 #define ADV_NUM_PAGE_CROSSING \
1228     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
1229
1230 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
1231 #define ADV_EEP_DVC_CFG_END             (0x15)
1232 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
1233 #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
1234
1235 #define ADV_EEP_DELAY_MS                100
1236
1237 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
1238 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
1239 /*
1240  * For the ASC3550 Bit 13 is Termination Polarity control bit.
1241  * For later ICs Bit 13 controls whether the CIS (Card Information
1242  * Service Section) is loaded from EEPROM.
1243  */
1244 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
1245 #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
1246 /*
1247  * ASC38C1600 Bit 11
1248  *
1249  * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1250  * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1251  * Function 0 will specify INT B.
1252  *
1253  * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1254  * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1255  * Function 1 will specify INT A.
1256  */
1257 #define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
1258
1259 typedef struct adveep_3550_config {
1260         /* Word Offset, Description */
1261
1262         ushort cfg_lsw;         /* 00 power up initialization */
1263         /*  bit 13 set - Term Polarity Control */
1264         /*  bit 14 set - BIOS Enable */
1265         /*  bit 15 set - Big Endian Mode */
1266         ushort cfg_msw;         /* 01 unused      */
1267         ushort disc_enable;     /* 02 disconnect enable */
1268         ushort wdtr_able;       /* 03 Wide DTR able */
1269         ushort sdtr_able;       /* 04 Synchronous DTR able */
1270         ushort start_motor;     /* 05 send start up motor */
1271         ushort tagqng_able;     /* 06 tag queuing able */
1272         ushort bios_scan;       /* 07 BIOS device control */
1273         ushort scam_tolerant;   /* 08 no scam */
1274
1275         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1276         uchar bios_boot_delay;  /*    power up wait */
1277
1278         uchar scsi_reset_delay; /* 10 reset delay */
1279         uchar bios_id_lun;      /*    first boot device scsi id & lun */
1280         /*    high nibble is lun */
1281         /*    low nibble is scsi id */
1282
1283         uchar termination;      /* 11 0 - automatic */
1284         /*    1 - low off / high off */
1285         /*    2 - low off / high on */
1286         /*    3 - low on  / high on */
1287         /*    There is no low on  / high off */
1288
1289         uchar reserved1;        /*    reserved byte (not used) */
1290
1291         ushort bios_ctrl;       /* 12 BIOS control bits */
1292         /*  bit 0  BIOS don't act as initiator. */
1293         /*  bit 1  BIOS > 1 GB support */
1294         /*  bit 2  BIOS > 2 Disk Support */
1295         /*  bit 3  BIOS don't support removables */
1296         /*  bit 4  BIOS support bootable CD */
1297         /*  bit 5  BIOS scan enabled */
1298         /*  bit 6  BIOS support multiple LUNs */
1299         /*  bit 7  BIOS display of message */
1300         /*  bit 8  SCAM disabled */
1301         /*  bit 9  Reset SCSI bus during init. */
1302         /*  bit 10 */
1303         /*  bit 11 No verbose initialization. */
1304         /*  bit 12 SCSI parity enabled */
1305         /*  bit 13 */
1306         /*  bit 14 */
1307         /*  bit 15 */
1308         ushort ultra_able;      /* 13 ULTRA speed able */
1309         ushort reserved2;       /* 14 reserved */
1310         uchar max_host_qng;     /* 15 maximum host queuing */
1311         uchar max_dvc_qng;      /*    maximum per device queuing */
1312         ushort dvc_cntl;        /* 16 control bit for driver */
1313         ushort bug_fix;         /* 17 control bit for bug fix */
1314         ushort serial_number_word1;     /* 18 Board serial number word 1 */
1315         ushort serial_number_word2;     /* 19 Board serial number word 2 */
1316         ushort serial_number_word3;     /* 20 Board serial number word 3 */
1317         ushort check_sum;       /* 21 EEP check sum */
1318         uchar oem_name[16];     /* 22 OEM name */
1319         ushort dvc_err_code;    /* 30 last device driver error code */
1320         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1321         ushort adv_err_addr;    /* 32 last uc error address */
1322         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1323         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1324         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1325         ushort num_of_err;      /* 36 number of error */
1326 } ADVEEP_3550_CONFIG;
1327
1328 typedef struct adveep_38C0800_config {
1329         /* Word Offset, Description */
1330
1331         ushort cfg_lsw;         /* 00 power up initialization */
1332         /*  bit 13 set - Load CIS */
1333         /*  bit 14 set - BIOS Enable */
1334         /*  bit 15 set - Big Endian Mode */
1335         ushort cfg_msw;         /* 01 unused      */
1336         ushort disc_enable;     /* 02 disconnect enable */
1337         ushort wdtr_able;       /* 03 Wide DTR able */
1338         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
1339         ushort start_motor;     /* 05 send start up motor */
1340         ushort tagqng_able;     /* 06 tag queuing able */
1341         ushort bios_scan;       /* 07 BIOS device control */
1342         ushort scam_tolerant;   /* 08 no scam */
1343
1344         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1345         uchar bios_boot_delay;  /*    power up wait */
1346
1347         uchar scsi_reset_delay; /* 10 reset delay */
1348         uchar bios_id_lun;      /*    first boot device scsi id & lun */
1349         /*    high nibble is lun */
1350         /*    low nibble is scsi id */
1351
1352         uchar termination_se;   /* 11 0 - automatic */
1353         /*    1 - low off / high off */
1354         /*    2 - low off / high on */
1355         /*    3 - low on  / high on */
1356         /*    There is no low on  / high off */
1357
1358         uchar termination_lvd;  /* 11 0 - automatic */
1359         /*    1 - low off / high off */
1360         /*    2 - low off / high on */
1361         /*    3 - low on  / high on */
1362         /*    There is no low on  / high off */
1363
1364         ushort bios_ctrl;       /* 12 BIOS control bits */
1365         /*  bit 0  BIOS don't act as initiator. */
1366         /*  bit 1  BIOS > 1 GB support */
1367         /*  bit 2  BIOS > 2 Disk Support */
1368         /*  bit 3  BIOS don't support removables */
1369         /*  bit 4  BIOS support bootable CD */
1370         /*  bit 5  BIOS scan enabled */
1371         /*  bit 6  BIOS support multiple LUNs */
1372         /*  bit 7  BIOS display of message */
1373         /*  bit 8  SCAM disabled */
1374         /*  bit 9  Reset SCSI bus during init. */
1375         /*  bit 10 */
1376         /*  bit 11 No verbose initialization. */
1377         /*  bit 12 SCSI parity enabled */
1378         /*  bit 13 */
1379         /*  bit 14 */
1380         /*  bit 15 */
1381         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
1382         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
1383         uchar max_host_qng;     /* 15 maximum host queueing */
1384         uchar max_dvc_qng;      /*    maximum per device queuing */
1385         ushort dvc_cntl;        /* 16 control bit for driver */
1386         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
1387         ushort serial_number_word1;     /* 18 Board serial number word 1 */
1388         ushort serial_number_word2;     /* 19 Board serial number word 2 */
1389         ushort serial_number_word3;     /* 20 Board serial number word 3 */
1390         ushort check_sum;       /* 21 EEP check sum */
1391         uchar oem_name[16];     /* 22 OEM name */
1392         ushort dvc_err_code;    /* 30 last device driver error code */
1393         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1394         ushort adv_err_addr;    /* 32 last uc error address */
1395         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1396         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1397         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1398         ushort reserved36;      /* 36 reserved */
1399         ushort reserved37;      /* 37 reserved */
1400         ushort reserved38;      /* 38 reserved */
1401         ushort reserved39;      /* 39 reserved */
1402         ushort reserved40;      /* 40 reserved */
1403         ushort reserved41;      /* 41 reserved */
1404         ushort reserved42;      /* 42 reserved */
1405         ushort reserved43;      /* 43 reserved */
1406         ushort reserved44;      /* 44 reserved */
1407         ushort reserved45;      /* 45 reserved */
1408         ushort reserved46;      /* 46 reserved */
1409         ushort reserved47;      /* 47 reserved */
1410         ushort reserved48;      /* 48 reserved */
1411         ushort reserved49;      /* 49 reserved */
1412         ushort reserved50;      /* 50 reserved */
1413         ushort reserved51;      /* 51 reserved */
1414         ushort reserved52;      /* 52 reserved */
1415         ushort reserved53;      /* 53 reserved */
1416         ushort reserved54;      /* 54 reserved */
1417         ushort reserved55;      /* 55 reserved */
1418         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
1419         ushort cisprt_msw;      /* 57 CIS PTR MSW */
1420         ushort subsysvid;       /* 58 SubSystem Vendor ID */
1421         ushort subsysid;        /* 59 SubSystem ID */
1422         ushort reserved60;      /* 60 reserved */
1423         ushort reserved61;      /* 61 reserved */
1424         ushort reserved62;      /* 62 reserved */
1425         ushort reserved63;      /* 63 reserved */
1426 } ADVEEP_38C0800_CONFIG;
1427
1428 typedef struct adveep_38C1600_config {
1429         /* Word Offset, Description */
1430
1431         ushort cfg_lsw;         /* 00 power up initialization */
1432         /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
1433         /*       clear - Func. 0 INTA, Func. 1 INTB */
1434         /*  bit 13 set - Load CIS */
1435         /*  bit 14 set - BIOS Enable */
1436         /*  bit 15 set - Big Endian Mode */
1437         ushort cfg_msw;         /* 01 unused */
1438         ushort disc_enable;     /* 02 disconnect enable */
1439         ushort wdtr_able;       /* 03 Wide DTR able */
1440         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
1441         ushort start_motor;     /* 05 send start up motor */
1442         ushort tagqng_able;     /* 06 tag queuing able */
1443         ushort bios_scan;       /* 07 BIOS device control */
1444         ushort scam_tolerant;   /* 08 no scam */
1445
1446         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1447         uchar bios_boot_delay;  /*    power up wait */
1448
1449         uchar scsi_reset_delay; /* 10 reset delay */
1450         uchar bios_id_lun;      /*    first boot device scsi id & lun */
1451         /*    high nibble is lun */
1452         /*    low nibble is scsi id */
1453
1454         uchar termination_se;   /* 11 0 - automatic */
1455         /*    1 - low off / high off */
1456         /*    2 - low off / high on */
1457         /*    3 - low on  / high on */
1458         /*    There is no low on  / high off */
1459
1460         uchar termination_lvd;  /* 11 0 - automatic */
1461         /*    1 - low off / high off */
1462         /*    2 - low off / high on */
1463         /*    3 - low on  / high on */
1464         /*    There is no low on  / high off */
1465
1466         ushort bios_ctrl;       /* 12 BIOS control bits */
1467         /*  bit 0  BIOS don't act as initiator. */
1468         /*  bit 1  BIOS > 1 GB support */
1469         /*  bit 2  BIOS > 2 Disk Support */
1470         /*  bit 3  BIOS don't support removables */
1471         /*  bit 4  BIOS support bootable CD */
1472         /*  bit 5  BIOS scan enabled */
1473         /*  bit 6  BIOS support multiple LUNs */
1474         /*  bit 7  BIOS display of message */
1475         /*  bit 8  SCAM disabled */
1476         /*  bit 9  Reset SCSI bus during init. */
1477         /*  bit 10 Basic Integrity Checking disabled */
1478         /*  bit 11 No verbose initialization. */
1479         /*  bit 12 SCSI parity enabled */
1480         /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1481         /*  bit 14 */
1482         /*  bit 15 */
1483         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
1484         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
1485         uchar max_host_qng;     /* 15 maximum host queueing */
1486         uchar max_dvc_qng;      /*    maximum per device queuing */
1487         ushort dvc_cntl;        /* 16 control bit for driver */
1488         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
1489         ushort serial_number_word1;     /* 18 Board serial number word 1 */
1490         ushort serial_number_word2;     /* 19 Board serial number word 2 */
1491         ushort serial_number_word3;     /* 20 Board serial number word 3 */
1492         ushort check_sum;       /* 21 EEP check sum */
1493         uchar oem_name[16];     /* 22 OEM name */
1494         ushort dvc_err_code;    /* 30 last device driver error code */
1495         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1496         ushort adv_err_addr;    /* 32 last uc error address */
1497         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1498         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1499         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1500         ushort reserved36;      /* 36 reserved */
1501         ushort reserved37;      /* 37 reserved */
1502         ushort reserved38;      /* 38 reserved */
1503         ushort reserved39;      /* 39 reserved */
1504         ushort reserved40;      /* 40 reserved */
1505         ushort reserved41;      /* 41 reserved */
1506         ushort reserved42;      /* 42 reserved */
1507         ushort reserved43;      /* 43 reserved */
1508         ushort reserved44;      /* 44 reserved */
1509         ushort reserved45;      /* 45 reserved */
1510         ushort reserved46;      /* 46 reserved */
1511         ushort reserved47;      /* 47 reserved */
1512         ushort reserved48;      /* 48 reserved */
1513         ushort reserved49;      /* 49 reserved */
1514         ushort reserved50;      /* 50 reserved */
1515         ushort reserved51;      /* 51 reserved */
1516         ushort reserved52;      /* 52 reserved */
1517         ushort reserved53;      /* 53 reserved */
1518         ushort reserved54;      /* 54 reserved */
1519         ushort reserved55;      /* 55 reserved */
1520         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
1521         ushort cisprt_msw;      /* 57 CIS PTR MSW */
1522         ushort subsysvid;       /* 58 SubSystem Vendor ID */
1523         ushort subsysid;        /* 59 SubSystem ID */
1524         ushort reserved60;      /* 60 reserved */
1525         ushort reserved61;      /* 61 reserved */
1526         ushort reserved62;      /* 62 reserved */
1527         ushort reserved63;      /* 63 reserved */
1528 } ADVEEP_38C1600_CONFIG;
1529
1530 /*
1531  * EEPROM Commands
1532  */
1533 #define ASC_EEP_CMD_DONE             0x0200
1534 #define ASC_EEP_CMD_DONE_ERR         0x0001
1535
1536 /* cfg_word */
1537 #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
1538
1539 /* bios_ctrl */
1540 #define BIOS_CTRL_BIOS               0x0001
1541 #define BIOS_CTRL_EXTENDED_XLAT      0x0002
1542 #define BIOS_CTRL_GT_2_DISK          0x0004
1543 #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
1544 #define BIOS_CTRL_BOOTABLE_CD        0x0010
1545 #define BIOS_CTRL_MULTIPLE_LUN       0x0040
1546 #define BIOS_CTRL_DISPLAY_MSG        0x0080
1547 #define BIOS_CTRL_NO_SCAM            0x0100
1548 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
1549 #define BIOS_CTRL_INIT_VERBOSE       0x0800
1550 #define BIOS_CTRL_SCSI_PARITY        0x1000
1551 #define BIOS_CTRL_AIPP_DIS           0x2000
1552
1553 #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
1554
1555 #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
1556
1557 /*
1558  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1559  * a special 16K Adv Library and Microcode version. After the issue is
1560  * resolved, should restore 32K support.
1561  *
1562  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
1563  */
1564 #define ADV_38C1600_MEMSIZE  0x4000     /* 16 KB Internal Memory */
1565
1566 /*
1567  * Byte I/O register address from base of 'iop_base'.
1568  */
1569 #define IOPB_INTR_STATUS_REG    0x00
1570 #define IOPB_CHIP_ID_1          0x01
1571 #define IOPB_INTR_ENABLES       0x02
1572 #define IOPB_CHIP_TYPE_REV      0x03
1573 #define IOPB_RES_ADDR_4         0x04
1574 #define IOPB_RES_ADDR_5         0x05
1575 #define IOPB_RAM_DATA           0x06
1576 #define IOPB_RES_ADDR_7         0x07
1577 #define IOPB_FLAG_REG           0x08
1578 #define IOPB_RES_ADDR_9         0x09
1579 #define IOPB_RISC_CSR           0x0A
1580 #define IOPB_RES_ADDR_B         0x0B
1581 #define IOPB_RES_ADDR_C         0x0C
1582 #define IOPB_RES_ADDR_D         0x0D
1583 #define IOPB_SOFT_OVER_WR       0x0E
1584 #define IOPB_RES_ADDR_F         0x0F
1585 #define IOPB_MEM_CFG            0x10
1586 #define IOPB_RES_ADDR_11        0x11
1587 #define IOPB_GPIO_DATA          0x12
1588 #define IOPB_RES_ADDR_13        0x13
1589 #define IOPB_FLASH_PAGE         0x14
1590 #define IOPB_RES_ADDR_15        0x15
1591 #define IOPB_GPIO_CNTL          0x16
1592 #define IOPB_RES_ADDR_17        0x17
1593 #define IOPB_FLASH_DATA         0x18
1594 #define IOPB_RES_ADDR_19        0x19
1595 #define IOPB_RES_ADDR_1A        0x1A
1596 #define IOPB_RES_ADDR_1B        0x1B
1597 #define IOPB_RES_ADDR_1C        0x1C
1598 #define IOPB_RES_ADDR_1D        0x1D
1599 #define IOPB_RES_ADDR_1E        0x1E
1600 #define IOPB_RES_ADDR_1F        0x1F
1601 #define IOPB_DMA_CFG0           0x20
1602 #define IOPB_DMA_CFG1           0x21
1603 #define IOPB_TICKLE             0x22
1604 #define IOPB_DMA_REG_WR         0x23
1605 #define IOPB_SDMA_STATUS        0x24
1606 #define IOPB_SCSI_BYTE_CNT      0x25
1607 #define IOPB_HOST_BYTE_CNT      0x26
1608 #define IOPB_BYTE_LEFT_TO_XFER  0x27
1609 #define IOPB_BYTE_TO_XFER_0     0x28
1610 #define IOPB_BYTE_TO_XFER_1     0x29
1611 #define IOPB_BYTE_TO_XFER_2     0x2A
1612 #define IOPB_BYTE_TO_XFER_3     0x2B
1613 #define IOPB_ACC_GRP            0x2C
1614 #define IOPB_RES_ADDR_2D        0x2D
1615 #define IOPB_DEV_ID             0x2E
1616 #define IOPB_RES_ADDR_2F        0x2F
1617 #define IOPB_SCSI_DATA          0x30
1618 #define IOPB_RES_ADDR_31        0x31
1619 #define IOPB_RES_ADDR_32        0x32
1620 #define IOPB_SCSI_DATA_HSHK     0x33
1621 #define IOPB_SCSI_CTRL          0x34
1622 #define IOPB_RES_ADDR_35        0x35
1623 #define IOPB_RES_ADDR_36        0x36
1624 #define IOPB_RES_ADDR_37        0x37
1625 #define IOPB_RAM_BIST           0x38
1626 #define IOPB_PLL_TEST           0x39
1627 #define IOPB_PCI_INT_CFG        0x3A
1628 #define IOPB_RES_ADDR_3B        0x3B
1629 #define IOPB_RFIFO_CNT          0x3C
1630 #define IOPB_RES_ADDR_3D        0x3D
1631 #define IOPB_RES_ADDR_3E        0x3E
1632 #define IOPB_RES_ADDR_3F        0x3F
1633
1634 /*
1635  * Word I/O register address from base of 'iop_base'.
1636  */
1637 #define IOPW_CHIP_ID_0          0x00    /* CID0  */
1638 #define IOPW_CTRL_REG           0x02    /* CC    */
1639 #define IOPW_RAM_ADDR           0x04    /* LA    */
1640 #define IOPW_RAM_DATA           0x06    /* LD    */
1641 #define IOPW_RES_ADDR_08        0x08
1642 #define IOPW_RISC_CSR           0x0A    /* CSR   */
1643 #define IOPW_SCSI_CFG0          0x0C    /* CFG0  */
1644 #define IOPW_SCSI_CFG1          0x0E    /* CFG1  */
1645 #define IOPW_RES_ADDR_10        0x10
1646 #define IOPW_SEL_MASK           0x12    /* SM    */
1647 #define IOPW_RES_ADDR_14        0x14
1648 #define IOPW_FLASH_ADDR         0x16    /* FA    */
1649 #define IOPW_RES_ADDR_18        0x18
1650 #define IOPW_EE_CMD             0x1A    /* EC    */
1651 #define IOPW_EE_DATA            0x1C    /* ED    */
1652 #define IOPW_SFIFO_CNT          0x1E    /* SFC   */
1653 #define IOPW_RES_ADDR_20        0x20
1654 #define IOPW_Q_BASE             0x22    /* QB    */
1655 #define IOPW_QP                 0x24    /* QP    */
1656 #define IOPW_IX                 0x26    /* IX    */
1657 #define IOPW_SP                 0x28    /* SP    */
1658 #define IOPW_PC                 0x2A    /* PC    */
1659 #define IOPW_RES_ADDR_2C        0x2C
1660 #define IOPW_RES_ADDR_2E        0x2E
1661 #define IOPW_SCSI_DATA          0x30    /* SD    */
1662 #define IOPW_SCSI_DATA_HSHK     0x32    /* SDH   */
1663 #define IOPW_SCSI_CTRL          0x34    /* SC    */
1664 #define IOPW_HSHK_CFG           0x36    /* HCFG  */
1665 #define IOPW_SXFR_STATUS        0x36    /* SXS   */
1666 #define IOPW_SXFR_CNTL          0x38    /* SXL   */
1667 #define IOPW_SXFR_CNTH          0x3A    /* SXH   */
1668 #define IOPW_RES_ADDR_3C        0x3C
1669 #define IOPW_RFIFO_DATA         0x3E    /* RFD   */
1670
1671 /*
1672  * Doubleword I/O register address from base of 'iop_base'.
1673  */
1674 #define IOPDW_RES_ADDR_0         0x00
1675 #define IOPDW_RAM_DATA           0x04
1676 #define IOPDW_RES_ADDR_8         0x08
1677 #define IOPDW_RES_ADDR_C         0x0C
1678 #define IOPDW_RES_ADDR_10        0x10
1679 #define IOPDW_COMMA              0x14
1680 #define IOPDW_COMMB              0x18
1681 #define IOPDW_RES_ADDR_1C        0x1C
1682 #define IOPDW_SDMA_ADDR0         0x20
1683 #define IOPDW_SDMA_ADDR1         0x24
1684 #define IOPDW_SDMA_COUNT         0x28
1685 #define IOPDW_SDMA_ERROR         0x2C
1686 #define IOPDW_RDMA_ADDR0         0x30
1687 #define IOPDW_RDMA_ADDR1         0x34
1688 #define IOPDW_RDMA_COUNT         0x38
1689 #define IOPDW_RDMA_ERROR         0x3C
1690
1691 #define ADV_CHIP_ID_BYTE         0x25
1692 #define ADV_CHIP_ID_WORD         0x04C1
1693
1694 #define ADV_SC_SCSI_BUS_RESET    0x2000
1695
1696 #define ADV_INTR_ENABLE_HOST_INTR                   0x01
1697 #define ADV_INTR_ENABLE_SEL_INTR                    0x02
1698 #define ADV_INTR_ENABLE_DPR_INTR                    0x04
1699 #define ADV_INTR_ENABLE_RTA_INTR                    0x08
1700 #define ADV_INTR_ENABLE_RMA_INTR                    0x10
1701 #define ADV_INTR_ENABLE_RST_INTR                    0x20
1702 #define ADV_INTR_ENABLE_DPE_INTR                    0x40
1703 #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
1704
1705 #define ADV_INTR_STATUS_INTRA            0x01
1706 #define ADV_INTR_STATUS_INTRB            0x02
1707 #define ADV_INTR_STATUS_INTRC            0x04
1708
1709 #define ADV_RISC_CSR_STOP           (0x0000)
1710 #define ADV_RISC_TEST_COND          (0x2000)
1711 #define ADV_RISC_CSR_RUN            (0x4000)
1712 #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
1713
1714 #define ADV_CTRL_REG_HOST_INTR      0x0100
1715 #define ADV_CTRL_REG_SEL_INTR       0x0200
1716 #define ADV_CTRL_REG_DPR_INTR       0x0400
1717 #define ADV_CTRL_REG_RTA_INTR       0x0800
1718 #define ADV_CTRL_REG_RMA_INTR       0x1000
1719 #define ADV_CTRL_REG_RES_BIT14      0x2000
1720 #define ADV_CTRL_REG_DPE_INTR       0x4000
1721 #define ADV_CTRL_REG_POWER_DONE     0x8000
1722 #define ADV_CTRL_REG_ANY_INTR       0xFF00
1723
1724 #define ADV_CTRL_REG_CMD_RESET             0x00C6
1725 #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
1726 #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
1727 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
1728 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
1729
1730 #define ADV_TICKLE_NOP                      0x00
1731 #define ADV_TICKLE_A                        0x01
1732 #define ADV_TICKLE_B                        0x02
1733 #define ADV_TICKLE_C                        0x03
1734
1735 #define ADV_SCSI_CTRL_RSTOUT        0x2000
1736
1737 #define AdvIsIntPending(port) \
1738     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1739
1740 /*
1741  * SCSI_CFG0 Register bit definitions
1742  */
1743 #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
1744 #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
1745 #define EVEN_PARITY     0x1000  /* Select Even Parity */
1746 #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1747 #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
1748 #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
1749 #define SCAM_EN         0x0080  /* Enable SCAM selection */
1750 #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1751 #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1752 #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
1753 #define OUR_ID          0x000F  /* SCSI ID */
1754
1755 /*
1756  * SCSI_CFG1 Register bit definitions
1757  */
1758 #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
1759 #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1760 #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
1761 #define FILTER_SEL      0x0C00  /* Filter Period Selection */
1762 #define  FLTR_DISABLE    0x0000 /* Input Filtering Disabled */
1763 #define  FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1764 #define  FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1765 #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
1766 #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
1767 #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
1768 #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
1769 #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
1770 #define  TERM_CTL_H      0x0020 /* Enable External SCSI Upper Termination */
1771 #define  TERM_CTL_L      0x0010 /* Enable External SCSI Lower Termination */
1772 #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
1773
1774 /*
1775  * Addendum for ASC-38C0800 Chip
1776  *
1777  * The ASC-38C1600 Chip uses the same definitions except that the
1778  * bus mode override bits [12:10] have been moved to byte register
1779  * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1780  * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1781  * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1782  * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1783  * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1784  */
1785 #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
1786 #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
1787 #define  HVD             0x1000 /* HVD Device Detect */
1788 #define  LVD             0x0800 /* LVD Device Detect */
1789 #define  SE              0x0400 /* SE Device Detect */
1790 #define TERM_LVD        0x00C0  /* LVD Termination Bits */
1791 #define  TERM_LVD_HI     0x0080 /* Enable LVD Upper Termination */
1792 #define  TERM_LVD_LO     0x0040 /* Enable LVD Lower Termination */
1793 #define TERM_SE         0x0030  /* SE Termination Bits */
1794 #define  TERM_SE_HI      0x0020 /* Enable SE Upper Termination */
1795 #define  TERM_SE_LO      0x0010 /* Enable SE Lower Termination */
1796 #define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
1797 #define  C_DET3          0x0008 /* Cable Detect for LVD External Wide */
1798 #define  C_DET2          0x0004 /* Cable Detect for LVD Internal Wide */
1799 #define C_DET_SE        0x0003  /* SE Cable Detect Bits */
1800 #define  C_DET1          0x0002 /* Cable Detect for SE Internal Wide */
1801 #define  C_DET0          0x0001 /* Cable Detect for SE Internal Narrow */
1802
1803 #define CABLE_ILLEGAL_A 0x7
1804     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
1805
1806 #define CABLE_ILLEGAL_B 0xB
1807     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
1808
1809 /*
1810  * MEM_CFG Register bit definitions
1811  */
1812 #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
1813 #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
1814 #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
1815 #define  RAM_SZ_2KB      0x00   /* 2 KB */
1816 #define  RAM_SZ_4KB      0x04   /* 4 KB */
1817 #define  RAM_SZ_8KB      0x08   /* 8 KB */
1818 #define  RAM_SZ_16KB     0x0C   /* 16 KB */
1819 #define  RAM_SZ_32KB     0x10   /* 32 KB */
1820 #define  RAM_SZ_64KB     0x14   /* 64 KB */
1821
1822 /*
1823  * DMA_CFG0 Register bit definitions
1824  *
1825  * This register is only accessible to the host.
1826  */
1827 #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
1828 #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
1829 #define  FIFO_THRESH_16B  0x00  /* 16 bytes */
1830 #define  FIFO_THRESH_32B  0x20  /* 32 bytes */
1831 #define  FIFO_THRESH_48B  0x30  /* 48 bytes */
1832 #define  FIFO_THRESH_64B  0x40  /* 64 bytes */
1833 #define  FIFO_THRESH_80B  0x50  /* 80 bytes (default) */
1834 #define  FIFO_THRESH_96B  0x60  /* 96 bytes */
1835 #define  FIFO_THRESH_112B 0x70  /* 112 bytes */
1836 #define START_CTL       0x0C    /* DMA start conditions */
1837 #define  START_CTL_TH    0x00   /* Wait threshold level (default) */
1838 #define  START_CTL_ID    0x04   /* Wait SDMA/SBUS idle */
1839 #define  START_CTL_THID  0x08   /* Wait threshold and SDMA/SBUS idle */
1840 #define  START_CTL_EMFU  0x0C   /* Wait SDMA FIFO empty/full */
1841 #define READ_CMD        0x03    /* Memory Read Method */
1842 #define  READ_CMD_MR     0x00   /* Memory Read */
1843 #define  READ_CMD_MRL    0x02   /* Memory Read Long */
1844 #define  READ_CMD_MRM    0x03   /* Memory Read Multiple (default) */
1845
1846 /*
1847  * ASC-38C0800 RAM BIST Register bit definitions
1848  */
1849 #define RAM_TEST_MODE         0x80
1850 #define PRE_TEST_MODE         0x40
1851 #define NORMAL_MODE           0x00
1852 #define RAM_TEST_DONE         0x10
1853 #define RAM_TEST_STATUS       0x0F
1854 #define  RAM_TEST_HOST_ERROR   0x08
1855 #define  RAM_TEST_INTRAM_ERROR 0x04
1856 #define  RAM_TEST_RISC_ERROR   0x02
1857 #define  RAM_TEST_SCSI_ERROR   0x01
1858 #define  RAM_TEST_SUCCESS      0x00
1859 #define PRE_TEST_VALUE        0x05
1860 #define NORMAL_VALUE          0x00
1861
1862 /*
1863  * ASC38C1600 Definitions
1864  *
1865  * IOPB_PCI_INT_CFG Bit Field Definitions
1866  */
1867
1868 #define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
1869
1870 /*
1871  * Bit 1 can be set to change the interrupt for the Function to operate in
1872  * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1873  * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1874  * mode, otherwise the operating mode is undefined.
1875  */
1876 #define TOTEMPOLE       0x02
1877
1878 /*
1879  * Bit 0 can be used to change the Int Pin for the Function. The value is
1880  * 0 by default for both Functions with Function 0 using INT A and Function
1881  * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1882  * INT A is used.
1883  *
1884  * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1885  * value specified in the PCI Configuration Space.
1886  */
1887 #define INTAB           0x01
1888
1889 /* a_advlib.h */
1890
1891 /*
1892  * Adv Library Status Definitions
1893  */
1894 #define ADV_TRUE        1
1895 #define ADV_FALSE       0
1896 #define ADV_NOERROR     1
1897 #define ADV_SUCCESS     1
1898 #define ADV_BUSY        0
1899 #define ADV_ERROR       (-1)
1900
1901 /*
1902  * ADV_DVC_VAR 'warn_code' values
1903  */
1904 #define ASC_WARN_BUSRESET_ERROR         0x0001  /* SCSI Bus Reset error */
1905 #define ASC_WARN_EEPROM_CHKSUM          0x0002  /* EEP check sum error */
1906 #define ASC_WARN_EEPROM_TERMINATION     0x0004  /* EEP termination bad field */
1907 #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080  /* PCI config space set error */
1908 #define ASC_WARN_ERROR                  0xFFFF  /* ADV_ERROR return */
1909
1910 #define ADV_MAX_TID                     15      /* max. target identifier */
1911 #define ADV_MAX_LUN                     7       /* max. logical unit number */
1912
1913 /*
1914  * Error code values are set in ADV_DVC_VAR 'err_code'.
1915  */
1916 #define ASC_IERR_WRITE_EEPROM       0x0001      /* write EEPROM error */
1917 #define ASC_IERR_MCODE_CHKSUM       0x0002      /* micro code check sum error */
1918 #define ASC_IERR_NO_CARRIER         0x0004      /* No more carrier memory. */
1919 #define ASC_IERR_START_STOP_CHIP    0x0008      /* start/stop chip failed */
1920 #define ASC_IERR_CHIP_VERSION       0x0040      /* wrong chip version */
1921 #define ASC_IERR_SET_SCSI_ID        0x0080      /* set SCSI ID failed */
1922 #define ASC_IERR_HVD_DEVICE         0x0100      /* HVD attached to LVD connector. */
1923 #define ASC_IERR_BAD_SIGNATURE      0x0200      /* signature not found */
1924 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400      /* Illegal cable connection */
1925 #define ASC_IERR_SINGLE_END_DEVICE  0x0800      /* Single-end used w/differential */
1926 #define ASC_IERR_REVERSED_CABLE     0x1000      /* Narrow flat cable reversed */
1927 #define ASC_IERR_BIST_PRE_TEST      0x2000      /* BIST pre-test error */
1928 #define ASC_IERR_BIST_RAM_TEST      0x4000      /* BIST RAM test error */
1929 #define ASC_IERR_BAD_CHIPTYPE       0x8000      /* Invalid 'chip_type' setting. */
1930
1931 /*
1932  * Fixed locations of microcode operating variables.
1933  */
1934 #define ASC_MC_CODE_BEGIN_ADDR          0x0028  /* microcode start address */
1935 #define ASC_MC_CODE_END_ADDR            0x002A  /* microcode end address */
1936 #define ASC_MC_CODE_CHK_SUM             0x002C  /* microcode code checksum */
1937 #define ASC_MC_VERSION_DATE             0x0038  /* microcode version */
1938 #define ASC_MC_VERSION_NUM              0x003A  /* microcode number */
1939 #define ASC_MC_BIOSMEM                  0x0040  /* BIOS RISC Memory Start */
1940 #define ASC_MC_BIOSLEN                  0x0050  /* BIOS RISC Memory Length */
1941 #define ASC_MC_BIOS_SIGNATURE           0x0058  /* BIOS Signature 0x55AA */
1942 #define ASC_MC_BIOS_VERSION             0x005A  /* BIOS Version (2 bytes) */
1943 #define ASC_MC_SDTR_SPEED1              0x0090  /* SDTR Speed for TID 0-3 */
1944 #define ASC_MC_SDTR_SPEED2              0x0092  /* SDTR Speed for TID 4-7 */
1945 #define ASC_MC_SDTR_SPEED3              0x0094  /* SDTR Speed for TID 8-11 */
1946 #define ASC_MC_SDTR_SPEED4              0x0096  /* SDTR Speed for TID 12-15 */
1947 #define ASC_MC_CHIP_TYPE                0x009A
1948 #define ASC_MC_INTRB_CODE               0x009B
1949 #define ASC_MC_WDTR_ABLE                0x009C
1950 #define ASC_MC_SDTR_ABLE                0x009E
1951 #define ASC_MC_TAGQNG_ABLE              0x00A0
1952 #define ASC_MC_DISC_ENABLE              0x00A2
1953 #define ASC_MC_IDLE_CMD_STATUS          0x00A4
1954 #define ASC_MC_IDLE_CMD                 0x00A6
1955 #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
1956 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
1957 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
1958 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
1959 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
1960 #define ASC_MC_SDTR_DONE                0x00B6
1961 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
1962 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
1963 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
1964 #define ASC_MC_CONTROL_FLAG             0x0122  /* Microcode control flag. */
1965 #define ASC_MC_WDTR_DONE                0x0124
1966 #define ASC_MC_CAM_MODE_MASK            0x015E  /* CAM mode TID bitmask. */
1967 #define ASC_MC_ICQ                      0x0160
1968 #define ASC_MC_IRQ                      0x0164
1969 #define ASC_MC_PPR_ABLE                 0x017A
1970
1971 /*
1972  * BIOS LRAM variable absolute offsets.
1973  */
1974 #define BIOS_CODESEG    0x54
1975 #define BIOS_CODELEN    0x56
1976 #define BIOS_SIGNATURE  0x58
1977 #define BIOS_VERSION    0x5A
1978
1979 /*
1980  * Microcode Control Flags
1981  *
1982  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1983  * and handled by the microcode.
1984  */
1985 #define CONTROL_FLAG_IGNORE_PERR        0x0001  /* Ignore DMA Parity Errors */
1986 #define CONTROL_FLAG_ENABLE_AIPP        0x0002  /* Enabled AIPP checking. */
1987
1988 /*
1989  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1990  */
1991 #define HSHK_CFG_WIDE_XFR       0x8000
1992 #define HSHK_CFG_RATE           0x0F00
1993 #define HSHK_CFG_OFFSET         0x001F
1994
1995 #define ASC_DEF_MAX_HOST_QNG    0xFD    /* Max. number of host commands (253) */
1996 #define ASC_DEF_MIN_HOST_QNG    0x10    /* Min. number of host commands (16) */
1997 #define ASC_DEF_MAX_DVC_QNG     0x3F    /* Max. number commands per device (63) */
1998 #define ASC_DEF_MIN_DVC_QNG     0x04    /* Min. number commands per device (4) */
1999
2000 #define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2001 #define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
2002 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2003 #define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
2004 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2005
2006 #define ASC_QSC_NO_DISC     0x01        /* Don't allow disconnect for request. */
2007 #define ASC_QSC_NO_TAGMSG   0x02        /* Don't allow tag queuing for request. */
2008 #define ASC_QSC_NO_SYNC     0x04        /* Don't use Synch. transfer on request. */
2009 #define ASC_QSC_NO_WIDE     0x08        /* Don't use Wide transfer on request. */
2010 #define ASC_QSC_REDO_DTR    0x10        /* Renegotiate WDTR/SDTR before request. */
2011 /*
2012  * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2013  * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2014  */
2015 #define ASC_QSC_HEAD_TAG    0x40        /* Use Head Tag Message (0x21). */
2016 #define ASC_QSC_ORDERED_TAG 0x80        /* Use Ordered Tag Message (0x22). */
2017
2018 /*
2019  * All fields here are accessed by the board microcode and need to be
2020  * little-endian.
2021  */
2022 typedef struct adv_carr_t {
2023         ADV_VADDR carr_va;      /* Carrier Virtual Address */
2024         ADV_PADDR carr_pa;      /* Carrier Physical Address */
2025         ADV_VADDR areq_vpa;     /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2026         /*
2027          * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
2028          *
2029          * next_vpa [3:1]             Reserved Bits
2030          * next_vpa [0]               Done Flag set in Response Queue.
2031          */
2032         ADV_VADDR next_vpa;
2033 } ADV_CARR_T;
2034
2035 /*
2036  * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2037  */
2038 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
2039
2040 #define ASC_RQ_DONE             0x00000001
2041 #define ASC_RQ_GOOD             0x00000002
2042 #define ASC_CQ_STOPPER          0x00000000
2043
2044 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2045
2046 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2047     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2048         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2049
2050 #define ADV_CARRIER_BUFSIZE \
2051     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2052
2053 /*
2054  * ASC_SCSI_REQ_Q 'a_flag' definitions
2055  *
2056  * The Adv Library should limit use to the lower nibble (4 bits) of
2057  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2058  */
2059 #define ADV_POLL_REQUEST                0x01    /* poll for request completion */
2060 #define ADV_SCSIQ_DONE                  0x02    /* request done */
2061 #define ADV_DONT_RETRY                  0x08    /* don't do retry */
2062
2063 #define ADV_CHIP_ASC3550          0x01  /* Ultra-Wide IC */
2064 #define ADV_CHIP_ASC38C0800       0x02  /* Ultra2-Wide/LVD IC */
2065 #define ADV_CHIP_ASC38C1600       0x03  /* Ultra3-Wide/LVD2 IC */
2066
2067 /*
2068  * Adapter temporary configuration structure
2069  *
2070  * This structure can be discarded after initialization. Don't add
2071  * fields here needed after initialization.
2072  *
2073  * Field naming convention:
2074  *
2075  *  *_enable indicates the field enables or disables a feature. The
2076  *  value of the field is never reset.
2077  */
2078 typedef struct adv_dvc_cfg {
2079         ushort disc_enable;     /* enable disconnection */
2080         uchar chip_version;     /* chip version */
2081         uchar termination;      /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2082         ushort lib_version;     /* Adv Library version number */
2083         ushort control_flag;    /* Microcode Control Flag */
2084         ushort mcode_date;      /* Microcode date */
2085         ushort mcode_version;   /* Microcode version */
2086         ushort serial1;         /* EEPROM serial number word 1 */
2087         ushort serial2;         /* EEPROM serial number word 2 */
2088         ushort serial3;         /* EEPROM serial number word 3 */
2089 } ADV_DVC_CFG;
2090
2091 struct adv_dvc_var;
2092 struct adv_scsi_req_q;
2093
2094 /*
2095  * Adapter operation variable structure.
2096  *
2097  * One structure is required per host adapter.
2098  *
2099  * Field naming convention:
2100  *
2101  *  *_able indicates both whether a feature should be enabled or disabled
2102  *  and whether a device isi capable of the feature. At initialization
2103  *  this field may be set, but later if a device is found to be incapable
2104  *  of the feature, the field is cleared.
2105  */
2106 typedef struct adv_dvc_var {
2107         AdvPortAddr iop_base;   /* I/O port address */
2108         ushort err_code;        /* fatal error code */
2109         ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
2110         ushort wdtr_able;       /* try WDTR for a device */
2111         ushort sdtr_able;       /* try SDTR for a device */
2112         ushort ultra_able;      /* try SDTR Ultra speed for a device */
2113         ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
2114         ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
2115         ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
2116         ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
2117         ushort tagqng_able;     /* try tagged queuing with a device */
2118         ushort ppr_able;        /* PPR message capable per TID bitmask. */
2119         uchar max_dvc_qng;      /* maximum number of tagged commands per device */
2120         ushort start_motor;     /* start motor command allowed */
2121         uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
2122         uchar chip_no;          /* should be assigned by caller */
2123         uchar max_host_qng;     /* maximum number of Q'ed command allowed */
2124         uchar irq_no;           /* IRQ number */
2125         ushort no_scam;         /* scam_tolerant of EEPROM */
2126         struct asc_board *drv_ptr;      /* driver pointer to private structure */
2127         uchar chip_scsi_id;     /* chip SCSI target ID */
2128         uchar chip_type;
2129         uchar bist_err_code;
2130         ADV_CARR_T *carrier_buf;
2131         ADV_CARR_T *carr_freelist;      /* Carrier free list. */
2132         ADV_CARR_T *icq_sp;     /* Initiator command queue stopper pointer. */
2133         ADV_CARR_T *irq_sp;     /* Initiator response queue stopper pointer. */
2134         ushort carr_pending_cnt;        /* Count of pending carriers. */
2135         /*
2136          * Note: The following fields will not be used after initialization. The
2137          * driver may discard the buffer after initialization is done.
2138          */
2139         ADV_DVC_CFG *cfg;       /* temporary configuration structure  */
2140 } ADV_DVC_VAR;
2141
2142 #define NO_OF_SG_PER_BLOCK              15
2143
2144 typedef struct asc_sg_block {
2145         uchar reserved1;
2146         uchar reserved2;
2147         uchar reserved3;
2148         uchar sg_cnt;           /* Valid entries in block. */
2149         ADV_PADDR sg_ptr;       /* Pointer to next sg block. */
2150         struct {
2151                 ADV_PADDR sg_addr;      /* SG element address. */
2152                 ADV_DCNT sg_count;      /* SG element count. */
2153         } sg_list[NO_OF_SG_PER_BLOCK];
2154 } ADV_SG_BLOCK;
2155
2156 /*
2157  * ADV_SCSI_REQ_Q - microcode request structure
2158  *
2159  * All fields in this structure up to byte 60 are used by the microcode.
2160  * The microcode makes assumptions about the size and ordering of fields
2161  * in this structure. Do not change the structure definition here without
2162  * coordinating the change with the microcode.
2163  *
2164  * All fields accessed by microcode must be maintained in little_endian
2165  * order.
2166  */
2167 typedef struct adv_scsi_req_q {
2168         uchar cntl;             /* Ucode flags and state (ASC_MC_QC_*). */
2169         uchar target_cmd;
2170         uchar target_id;        /* Device target identifier. */
2171         uchar target_lun;       /* Device target logical unit number. */
2172         ADV_PADDR data_addr;    /* Data buffer physical address. */
2173         ADV_DCNT data_cnt;      /* Data count. Ucode sets to residual. */
2174         ADV_PADDR sense_addr;
2175         ADV_PADDR carr_pa;
2176         uchar mflag;
2177         uchar sense_len;
2178         uchar cdb_len;          /* SCSI CDB length. Must <= 16 bytes. */
2179         uchar scsi_cntl;
2180         uchar done_status;      /* Completion status. */
2181         uchar scsi_status;      /* SCSI status byte. */
2182         uchar host_status;      /* Ucode host status. */
2183         uchar sg_working_ix;
2184         uchar cdb[12];          /* SCSI CDB bytes 0-11. */
2185         ADV_PADDR sg_real_addr; /* SG list physical address. */
2186         ADV_PADDR scsiq_rptr;
2187         uchar cdb16[4];         /* SCSI CDB bytes 12-15. */
2188         ADV_VADDR scsiq_ptr;
2189         ADV_VADDR carr_va;
2190         /*
2191          * End of microcode structure - 60 bytes. The rest of the structure
2192          * is used by the Adv Library and ignored by the microcode.
2193          */
2194         ADV_VADDR srb_ptr;
2195         ADV_SG_BLOCK *sg_list_ptr;      /* SG list virtual address. */
2196         char *vdata_addr;       /* Data buffer virtual address. */
2197         uchar a_flag;
2198         uchar pad[2];           /* Pad out to a word boundary. */
2199 } ADV_SCSI_REQ_Q;
2200
2201 /*
2202  * Microcode idle loop commands
2203  */
2204 #define IDLE_CMD_COMPLETED           0
2205 #define IDLE_CMD_STOP_CHIP           0x0001
2206 #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
2207 #define IDLE_CMD_SEND_INT            0x0004
2208 #define IDLE_CMD_ABORT               0x0008
2209 #define IDLE_CMD_DEVICE_RESET        0x0010
2210 #define IDLE_CMD_SCSI_RESET_START    0x0020     /* Assert SCSI Bus Reset */
2211 #define IDLE_CMD_SCSI_RESET_END      0x0040     /* Deassert SCSI Bus Reset */
2212 #define IDLE_CMD_SCSIREQ             0x0080
2213
2214 #define IDLE_CMD_STATUS_SUCCESS      0x0001
2215 #define IDLE_CMD_STATUS_FAILURE      0x0002
2216
2217 /*
2218  * AdvSendIdleCmd() flag definitions.
2219  */
2220 #define ADV_NOWAIT     0x01
2221
2222 /*
2223  * Wait loop time out values.
2224  */
2225 #define SCSI_WAIT_10_SEC             10UL       /* 10 seconds */
2226 #define SCSI_WAIT_100_MSEC           100UL      /* 100 milliseconds */
2227 #define SCSI_US_PER_MSEC             1000       /* microseconds per millisecond */
2228 #define SCSI_MS_PER_SEC              1000UL     /* milliseconds per second */
2229 #define SCSI_MAX_RETRY               10 /* retry count */
2230
2231 #define ADV_ASYNC_RDMA_FAILURE          0x01    /* Fatal RDMA failure. */
2232 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02    /* Detected SCSI Bus Reset. */
2233 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03    /* Carrier Ready failure. */
2234 #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04    /* RDMAed-in data invalid. */
2235
2236 #define ADV_HOST_SCSI_BUS_RESET      0x80       /* Host Initiated SCSI Bus Reset. */
2237
2238 /*
2239  * Device drivers must define the following functions.
2240  */
2241 static inline ulong DvcEnterCritical(void);
2242 static inline void DvcLeaveCritical(ulong);
2243 static void DvcSleepMilliSecond(ADV_DCNT);
2244 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
2245                                uchar *, ASC_SDCNT *, int);
2246 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
2247
2248 /*
2249  * Adv Library functions available to drivers.
2250  */
2251 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
2252 static int AdvISR(ADV_DVC_VAR *);
2253 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
2254 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
2255 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
2256 static int AdvResetChipAndSB(ADV_DVC_VAR *);
2257 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
2258
2259 /*
2260  * Internal Adv Library functions.
2261  */
2262 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
2263 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
2264 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
2265 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
2266 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2267 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
2268 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2269 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
2270 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2271 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
2272 static void AdvWaitEEPCmd(AdvPortAddr);
2273 static ushort AdvReadEEPWord(AdvPortAddr, int);
2274
2275 /* Read byte from a register. */
2276 #define AdvReadByteRegister(iop_base, reg_off) \
2277      (ADV_MEM_READB((iop_base) + (reg_off)))
2278
2279 /* Write byte to a register. */
2280 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
2281      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
2282
2283 /* Read word (2 bytes) from a register. */
2284 #define AdvReadWordRegister(iop_base, reg_off) \
2285      (ADV_MEM_READW((iop_base) + (reg_off)))
2286
2287 /* Write word (2 bytes) to a register. */
2288 #define AdvWriteWordRegister(iop_base, reg_off, word) \
2289      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2290
2291 /* Write dword (4 bytes) to a register. */
2292 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2293      (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2294
2295 /* Read byte from LRAM. */
2296 #define AdvReadByteLram(iop_base, addr, byte) \
2297 do { \
2298     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2299     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2300 } while (0)
2301
2302 /* Write byte to LRAM. */
2303 #define AdvWriteByteLram(iop_base, addr, byte) \
2304     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2305      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2306
2307 /* Read word (2 bytes) from LRAM. */
2308 #define AdvReadWordLram(iop_base, addr, word) \
2309 do { \
2310     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2311     (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2312 } while (0)
2313
2314 /* Write word (2 bytes) to LRAM. */
2315 #define AdvWriteWordLram(iop_base, addr, word) \
2316     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2317      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2318
2319 /* Write little-endian double word (4 bytes) to LRAM */
2320 /* Because of unspecified C language ordering don't use auto-increment. */
2321 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2322     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2323       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2324                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2325      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2326       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2327                      cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2328
2329 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
2330 #define AdvReadWordAutoIncLram(iop_base) \
2331      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2332
2333 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
2334 #define AdvWriteWordAutoIncLram(iop_base, word) \
2335      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2336
2337 /*
2338  * Define macro to check for Condor signature.
2339  *
2340  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2341  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2342  */
2343 #define AdvFindSignature(iop_base) \
2344     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2345     ADV_CHIP_ID_BYTE) && \
2346      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2347     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
2348
2349 /*
2350  * Define macro to Return the version number of the chip at 'iop_base'.
2351  *
2352  * The second parameter 'bus_type' is currently unused.
2353  */
2354 #define AdvGetChipVersion(iop_base, bus_type) \
2355     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2356
2357 /*
2358  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2359  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2360  *
2361  * If the request has not yet been sent to the device it will simply be
2362  * aborted from RISC memory. If the request is disconnected it will be
2363  * aborted on reselection by sending an Abort Message to the target ID.
2364  *
2365  * Return value:
2366  *      ADV_TRUE(1) - Queue was successfully aborted.
2367  *      ADV_FALSE(0) - Queue was not found on the active queue list.
2368  */
2369 #define AdvAbortQueue(asc_dvc, scsiq) \
2370         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2371                        (ADV_DCNT) (scsiq))
2372
2373 /*
2374  * Send a Bus Device Reset Message to the specified target ID.
2375  *
2376  * All outstanding commands will be purged if sending the
2377  * Bus Device Reset Message is successful.
2378  *
2379  * Return Value:
2380  *      ADV_TRUE(1) - All requests on the target are purged.
2381  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2382  *                     are not purged.
2383  */
2384 #define AdvResetDevice(asc_dvc, target_id) \
2385         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2386                     (ADV_DCNT) (target_id))
2387
2388 /*
2389  * SCSI Wide Type definition.
2390  */
2391 #define ADV_SCSI_BIT_ID_TYPE   ushort
2392
2393 /*
2394  * AdvInitScsiTarget() 'cntl_flag' options.
2395  */
2396 #define ADV_SCAN_LUN           0x01
2397 #define ADV_CAPINFO_NOLUN      0x02
2398
2399 /*
2400  * Convert target id to target id bit mask.
2401  */
2402 #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
2403
2404 /*
2405  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2406  */
2407
2408 #define QD_NO_STATUS         0x00       /* Request not completed yet. */
2409 #define QD_NO_ERROR          0x01
2410 #define QD_ABORTED_BY_HOST   0x02
2411 #define QD_WITH_ERROR        0x04
2412
2413 #define QHSTA_NO_ERROR              0x00
2414 #define QHSTA_M_SEL_TIMEOUT         0x11
2415 #define QHSTA_M_DATA_OVER_RUN       0x12
2416 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2417 #define QHSTA_M_QUEUE_ABORTED       0x15
2418 #define QHSTA_M_SXFR_SDMA_ERR       0x16        /* SXFR_STATUS SCSI DMA Error */
2419 #define QHSTA_M_SXFR_SXFR_PERR      0x17        /* SXFR_STATUS SCSI Bus Parity Error */
2420 #define QHSTA_M_RDMA_PERR           0x18        /* RISC PCI DMA parity error */
2421 #define QHSTA_M_SXFR_OFF_UFLW       0x19        /* SXFR_STATUS Offset Underflow */
2422 #define QHSTA_M_SXFR_OFF_OFLW       0x20        /* SXFR_STATUS Offset Overflow */
2423 #define QHSTA_M_SXFR_WD_TMO         0x21        /* SXFR_STATUS Watchdog Timeout */
2424 #define QHSTA_M_SXFR_DESELECTED     0x22        /* SXFR_STATUS Deselected */
2425 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
2426 #define QHSTA_M_SXFR_XFR_OFLW       0x12        /* SXFR_STATUS Transfer Overflow */
2427 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24        /* SXFR_STATUS Transfer Phase Error */
2428 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25        /* SXFR_STATUS Unknown Error */
2429 #define QHSTA_M_SCSI_BUS_RESET      0x30        /* Request aborted from SBR */
2430 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31       /* Request aborted from unsol. SBR */
2431 #define QHSTA_M_BUS_DEVICE_RESET    0x32        /* Request aborted from BDR */
2432 #define QHSTA_M_DIRECTION_ERR       0x35        /* Data Phase mismatch */
2433 #define QHSTA_M_DIRECTION_ERR_HUNG  0x36        /* Data Phase mismatch and bus hang */
2434 #define QHSTA_M_WTM_TIMEOUT         0x41
2435 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
2436 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
2437 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2438 #define QHSTA_M_INVALID_DEVICE      0x45        /* Bad target ID */
2439 #define QHSTA_M_FROZEN_TIDQ         0x46        /* TID Queue frozen. */
2440 #define QHSTA_M_SGBACKUP_ERROR      0x47        /* Scatter-Gather backup error */
2441
2442 /*
2443  * DvcGetPhyAddr() flag arguments
2444  */
2445 #define ADV_IS_SCSIQ_FLAG       0x01    /* 'addr' is ASC_SCSI_REQ_Q pointer */
2446 #define ADV_ASCGETSGLIST_VADDR  0x02    /* 'addr' is AscGetSGList() virtual addr */
2447 #define ADV_IS_SENSE_FLAG       0x04    /* 'addr' is sense virtual pointer */
2448 #define ADV_IS_DATA_FLAG        0x08    /* 'addr' is data virtual pointer */
2449 #define ADV_IS_SGLIST_FLAG      0x10    /* 'addr' is sglist virtual pointer */
2450 #define ADV_IS_CARRIER_FLAG     0x20    /* 'addr' is ADV_CARR_T pointer */
2451
2452 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
2453 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
2454 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
2455 #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
2456
2457 /*
2458  * Total contiguous memory needed for driver SG blocks.
2459  *
2460  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2461  * number of scatter-gather elements the driver supports in a
2462  * single request.
2463  */
2464
2465 #define ADV_SG_LIST_MAX_BYTE_SIZE \
2466          (sizeof(ADV_SG_BLOCK) * \
2467           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2468
2469 /*
2470  * --- Driver Constants and Macros
2471  */
2472
2473 /* Reference Scsi_Host hostdata */
2474 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
2475
2476 /* asc_board_t flags */
2477 #define ASC_HOST_IN_RESET       0x01
2478 #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
2479 #define ASC_SELECT_QUEUE_DEPTHS 0x08
2480
2481 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2482 #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
2483
2484 #define NO_ISA_DMA              0xff    /* No ISA DMA Channel Used */
2485
2486 #define ASC_INFO_SIZE           128     /* advansys_info() line size */
2487
2488 #ifdef CONFIG_PROC_FS
2489 /* /proc/scsi/advansys/[0...] related definitions */
2490 #define ASC_PRTBUF_SIZE         2048
2491 #define ASC_PRTLINE_SIZE        160
2492
2493 #define ASC_PRT_NEXT() \
2494     if (cp) { \
2495         totlen += len; \
2496         leftlen -= len; \
2497         if (leftlen == 0) { \
2498             return totlen; \
2499         } \
2500         cp += len; \
2501     }
2502 #endif /* CONFIG_PROC_FS */
2503
2504 /* Asc Library return codes */
2505 #define ASC_TRUE        1
2506 #define ASC_FALSE       0
2507 #define ASC_NOERROR     1
2508 #define ASC_BUSY        0
2509 #define ASC_ERROR       (-1)
2510
2511 /* struct scsi_cmnd function return codes */
2512 #define STATUS_BYTE(byte)   (byte)
2513 #define MSG_BYTE(byte)      ((byte) << 8)
2514 #define HOST_BYTE(byte)     ((byte) << 16)
2515 #define DRIVER_BYTE(byte)   ((byte) << 24)
2516
2517 /*
2518  * The following definitions and macros are OS independent interfaces to
2519  * the queue functions:
2520  *  REQ - SCSI request structure
2521  *  REQP - pointer to SCSI request structure
2522  *  REQPTID(reqp) - reqp's target id
2523  *  REQPNEXT(reqp) - reqp's next pointer
2524  *  REQPNEXTP(reqp) - pointer to reqp's next pointer
2525  *  REQPTIME(reqp) - reqp's time stamp value
2526  *  REQTIMESTAMP() - system time stamp value
2527  */
2528 typedef struct scsi_cmnd REQ, *REQP;
2529 #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
2530 #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
2531 #define REQPTID(reqp)        ((reqp)->device->id)
2532 #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
2533 #define REQTIMESTAMP()       (jiffies)
2534
2535 #define REQTIMESTAT(function, ascq, reqp, tid) \
2536 { \
2537     /*
2538      * If the request time stamp is less than the system time stamp, then \
2539      * maybe the system time stamp wrapped. Set the request time to zero.\
2540      */ \
2541     if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
2542         REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
2543     } else { \
2544         /* Indicate an error occurred with the assertion. */ \
2545         ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
2546         REQPTIME(reqp) = 0; \
2547     } \
2548     /* Handle first minimum time case without external initialization. */ \
2549     if (((ascq)->q_tot_cnt[tid] == 1) ||  \
2550         (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
2551             (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
2552             ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
2553                 (function), (tid), (ascq)->q_min_tim[tid]); \
2554         } \
2555     if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
2556         (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
2557         ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
2558             (function), tid, (ascq)->q_max_tim[tid]); \
2559     } \
2560     (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
2561     /* Reset the time stamp field. */ \
2562     REQPTIME(reqp) = 0; \
2563 }
2564
2565 /* asc_enqueue() flags */
2566 #define ASC_FRONT       1
2567 #define ASC_BACK        2
2568
2569 /* asc_dequeue_list() argument */
2570 #define ASC_TID_ALL        (-1)
2571
2572 /* Return non-zero, if the queue is empty. */
2573 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
2574
2575 #ifndef ADVANSYS_STATS
2576 #define ASC_STATS(shost, counter)
2577 #define ASC_STATS_ADD(shost, counter, count)
2578 #else /* ADVANSYS_STATS */
2579 #define ASC_STATS(shost, counter) \
2580     (ASC_BOARDP(shost)->asc_stats.counter++)
2581
2582 #define ASC_STATS_ADD(shost, counter, count) \
2583     (ASC_BOARDP(shost)->asc_stats.counter += (count))
2584 #endif /* ADVANSYS_STATS */
2585
2586 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
2587
2588 /* If the result wraps when calculating tenths, return 0. */
2589 #define ASC_TENTHS(num, den) \
2590     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2591     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2592
2593 /*
2594  * Display a message to the console.
2595  */
2596 #define ASC_PRINT(s) \
2597     { \
2598         printk("advansys: "); \
2599         printk(s); \
2600     }
2601
2602 #define ASC_PRINT1(s, a1) \
2603     { \
2604         printk("advansys: "); \
2605         printk((s), (a1)); \
2606     }
2607
2608 #define ASC_PRINT2(s, a1, a2) \
2609     { \
2610         printk("advansys: "); \
2611         printk((s), (a1), (a2)); \
2612     }
2613
2614 #define ASC_PRINT3(s, a1, a2, a3) \
2615     { \
2616         printk("advansys: "); \
2617         printk((s), (a1), (a2), (a3)); \
2618     }
2619
2620 #define ASC_PRINT4(s, a1, a2, a3, a4) \
2621     { \
2622         printk("advansys: "); \
2623         printk((s), (a1), (a2), (a3), (a4)); \
2624     }
2625
2626 #ifndef ADVANSYS_DEBUG
2627
2628 #define ASC_DBG(lvl, s)
2629 #define ASC_DBG1(lvl, s, a1)
2630 #define ASC_DBG2(lvl, s, a1, a2)
2631 #define ASC_DBG3(lvl, s, a1, a2, a3)
2632 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
2633 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2634 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
2635 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2636 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2637 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2638 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2639 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
2640 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
2641 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
2642 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2643
2644 #else /* ADVANSYS_DEBUG */
2645
2646 /*
2647  * Debugging Message Levels:
2648  * 0: Errors Only
2649  * 1: High-Level Tracing
2650  * 2-N: Verbose Tracing
2651  */
2652
2653 #define ASC_DBG(lvl, s) \
2654     { \
2655         if (asc_dbglvl >= (lvl)) { \
2656             printk(s); \
2657         } \
2658     }
2659
2660 #define ASC_DBG1(lvl, s, a1) \
2661     { \
2662         if (asc_dbglvl >= (lvl)) { \
2663             printk((s), (a1)); \
2664         } \
2665     }
2666
2667 #define ASC_DBG2(lvl, s, a1, a2) \
2668     { \
2669         if (asc_dbglvl >= (lvl)) { \
2670             printk((s), (a1), (a2)); \
2671         } \
2672     }
2673
2674 #define ASC_DBG3(lvl, s, a1, a2, a3) \
2675     { \
2676         if (asc_dbglvl >= (lvl)) { \
2677             printk((s), (a1), (a2), (a3)); \
2678         } \
2679     }
2680
2681 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
2682     { \
2683         if (asc_dbglvl >= (lvl)) { \
2684             printk((s), (a1), (a2), (a3), (a4)); \
2685         } \
2686     }
2687
2688 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2689     { \
2690         if (asc_dbglvl >= (lvl)) { \
2691             asc_prt_scsi_host(s); \
2692         } \
2693     }
2694
2695 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
2696     { \
2697         if (asc_dbglvl >= (lvl)) { \
2698             asc_prt_scsi_cmnd(s); \
2699         } \
2700     }
2701
2702 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2703     { \
2704         if (asc_dbglvl >= (lvl)) { \
2705             asc_prt_asc_scsi_q(scsiqp); \
2706         } \
2707     }
2708
2709 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2710     { \
2711         if (asc_dbglvl >= (lvl)) { \
2712             asc_prt_asc_qdone_info(qdone); \
2713         } \
2714     }
2715
2716 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2717     { \
2718         if (asc_dbglvl >= (lvl)) { \
2719             asc_prt_adv_scsi_req_q(scsiqp); \
2720         } \
2721     }
2722
2723 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2724     { \
2725         if (asc_dbglvl >= (lvl)) { \
2726             asc_prt_hex((name), (start), (length)); \
2727         } \
2728     }
2729
2730 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2731         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2732
2733 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2734         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2735
2736 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2737         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2738 #endif /* ADVANSYS_DEBUG */
2739
2740 #ifndef ADVANSYS_ASSERT
2741 #define ASC_ASSERT(a)
2742 #else /* ADVANSYS_ASSERT */
2743
2744 #define ASC_ASSERT(a) \
2745     { \
2746         if (!(a)) { \
2747             printk("ASC_ASSERT() Failure: file %s, line %d\n", \
2748                 __FILE__, __LINE__); \
2749         } \
2750     }
2751
2752 #endif /* ADVANSYS_ASSERT */
2753
2754 /*
2755  * --- Driver Structures
2756  */
2757
2758 #ifdef ADVANSYS_STATS
2759
2760 /* Per board statistics structure */
2761 struct asc_stats {
2762         /* Driver Entrypoint Statistics */
2763         ADV_DCNT queuecommand;  /* # calls to advansys_queuecommand() */
2764         ADV_DCNT reset;         /* # calls to advansys_eh_bus_reset() */
2765         ADV_DCNT biosparam;     /* # calls to advansys_biosparam() */
2766         ADV_DCNT interrupt;     /* # advansys_interrupt() calls */
2767         ADV_DCNT callback;      /* # calls to asc/adv_isr_callback() */
2768         ADV_DCNT done;          /* # calls to request's scsi_done function */
2769         ADV_DCNT build_error;   /* # asc/adv_build_req() ASC_ERROR returns. */
2770         ADV_DCNT adv_build_noreq;       /* # adv_build_req() adv_req_t alloc. fail. */
2771         ADV_DCNT adv_build_nosg;        /* # adv_build_req() adv_sgblk_t alloc. fail. */
2772         /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2773         ADV_DCNT exe_noerror;   /* # ASC_NOERROR returns. */
2774         ADV_DCNT exe_busy;      /* # ASC_BUSY returns. */
2775         ADV_DCNT exe_error;     /* # ASC_ERROR returns. */
2776         ADV_DCNT exe_unknown;   /* # unknown returns. */
2777         /* Data Transfer Statistics */
2778         ADV_DCNT cont_cnt;      /* # non-scatter-gather I/O requests received */
2779         ADV_DCNT cont_xfer;     /* # contiguous transfer 512-bytes */
2780         ADV_DCNT sg_cnt;        /* # scatter-gather I/O requests received */
2781         ADV_DCNT sg_elem;       /* # scatter-gather elements */
2782         ADV_DCNT sg_xfer;       /* # scatter-gather transfer 512-bytes */
2783 };
2784 #endif /* ADVANSYS_STATS */
2785
2786 /*
2787  * Request queuing structure
2788  */
2789 typedef struct asc_queue {
2790         ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
2791         REQP q_first[ADV_MAX_TID + 1];  /* first queued request */
2792         REQP q_last[ADV_MAX_TID + 1];   /* last queued request */
2793 #ifdef ADVANSYS_STATS
2794         short q_cur_cnt[ADV_MAX_TID + 1];       /* current queue count */
2795         short q_max_cnt[ADV_MAX_TID + 1];       /* maximum queue count */
2796         ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1];    /* total enqueue count */
2797         ADV_DCNT q_tot_tim[ADV_MAX_TID + 1];    /* total time queued */
2798         ushort q_max_tim[ADV_MAX_TID + 1];      /* maximum time queued */
2799         ushort q_min_tim[ADV_MAX_TID + 1];      /* minimum time queued */
2800 #endif                          /* ADVANSYS_STATS */
2801 } asc_queue_t;
2802
2803 /*
2804  * Adv Library Request Structures
2805  *
2806  * The following two structures are used to process Wide Board requests.
2807  *
2808  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
2809  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
2810  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
2811  * Mid-Level SCSI request structure.
2812  *
2813  * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
2814  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
2815  * up to 255 scatter-gather elements may be used per request or
2816  * ADV_SCSI_REQ_Q.
2817  *
2818  * Both structures must be 32 byte aligned.
2819  */
2820 typedef struct adv_sgblk {
2821         ADV_SG_BLOCK sg_block;  /* Sgblock structure. */
2822         uchar align[32];        /* Sgblock structure padding. */
2823         struct adv_sgblk *next_sgblkp;  /* Next scatter-gather structure. */
2824 } adv_sgblk_t;
2825
2826 typedef struct adv_req {
2827         ADV_SCSI_REQ_Q scsi_req_q;      /* Adv Library request structure. */
2828         uchar align[32];        /* Request structure padding. */
2829         struct scsi_cmnd *cmndp;        /* Mid-Level SCSI command pointer. */
2830         adv_sgblk_t *sgblkp;    /* Adv Library scatter-gather pointer. */
2831         struct adv_req *next_reqp;      /* Next Request Structure. */
2832 } adv_req_t;
2833
2834 /*
2835  * Structure allocated for each board.
2836  *
2837  * This structure is allocated by scsi_host_alloc() at the end
2838  * of the 'Scsi_Host' structure starting at the 'hostdata'
2839  * field. It is guaranteed to be allocated from DMA-able memory.
2840  */
2841 typedef struct asc_board {
2842         struct device *dev;
2843         int id;                 /* Board Id */
2844         uint flags;             /* Board flags */
2845         union {
2846                 ASC_DVC_VAR asc_dvc_var;        /* Narrow board */
2847                 ADV_DVC_VAR adv_dvc_var;        /* Wide board */
2848         } dvc_var;
2849         union {
2850                 ASC_DVC_CFG asc_dvc_cfg;        /* Narrow board */
2851                 ADV_DVC_CFG adv_dvc_cfg;        /* Wide board */
2852         } dvc_cfg;
2853         ushort asc_n_io_port;   /* Number I/O ports. */
2854         asc_queue_t active;     /* Active command queue */
2855         asc_queue_t waiting;    /* Waiting command queue */
2856         asc_queue_t done;       /* Done command queue */
2857         ADV_SCSI_BIT_ID_TYPE init_tidmask;      /* Target init./valid mask */
2858         struct scsi_device *device[ADV_MAX_TID + 1];    /* Mid-Level Scsi Device */
2859         ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2860         ADV_SCSI_BIT_ID_TYPE queue_full;        /* Queue full mask */
2861         ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2862         union {
2863                 ASCEEP_CONFIG asc_eep;  /* Narrow EEPROM config. */
2864                 ADVEEP_3550_CONFIG adv_3550_eep;        /* 3550 EEPROM config. */
2865                 ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
2866                 ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
2867         } eep_config;
2868         ulong last_reset;       /* Saved last reset time */
2869         spinlock_t lock;        /* Board spinlock */
2870         /* /proc/scsi/advansys/[0...] */
2871         char *prtbuf;           /* /proc print buffer */
2872 #ifdef ADVANSYS_STATS
2873         struct asc_stats asc_stats;     /* Board statistics */
2874 #endif                          /* ADVANSYS_STATS */
2875         /*
2876          * The following fields are used only for Narrow Boards.
2877          */
2878         uchar sdtr_data[ASC_MAX_TID + 1];       /* SDTR information */
2879         /*
2880          * The following fields are used only for Wide Boards.
2881          */
2882         void __iomem *ioremap_addr;     /* I/O Memory remap address. */
2883         ushort ioport;          /* I/O Port address. */
2884         ADV_CARR_T *carrp;      /* ADV_CARR_T memory block. */
2885         adv_req_t *orig_reqp;   /* adv_req_t memory block. */
2886         adv_req_t *adv_reqp;    /* Request structures. */
2887         adv_sgblk_t *adv_sgblkp;        /* Scatter-gather structures. */
2888         ushort bios_signature;  /* BIOS Signature. */
2889         ushort bios_version;    /* BIOS Version. */
2890         ushort bios_codeseg;    /* BIOS Code Segment. */
2891         ushort bios_codelen;    /* BIOS Code Segment Length. */
2892 } asc_board_t;
2893
2894 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2895                                                         dvc_var.adv_dvc_var)
2896 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2897
2898 /* Number of boards detected in system. */
2899 static int asc_board_count;
2900
2901 /* Overrun buffer used by all narrow boards. */
2902 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
2903
2904 /*
2905  * Global structures required to issue a command.
2906  */
2907 static ASC_SCSI_Q asc_scsi_q = { {0} };
2908 static ASC_SG_HEAD asc_sg_head = { 0 };
2909
2910 #ifdef ADVANSYS_DEBUG
2911 static int asc_dbglvl = 3;
2912 #endif /* ADVANSYS_DEBUG */
2913
2914 /*
2915  * --- Driver Function Prototypes
2916  */
2917
2918 static int advansys_slave_configure(struct scsi_device *);
2919 static void asc_scsi_done_list(struct scsi_cmnd *);
2920 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
2921 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
2922 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
2923 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
2924 static void asc_enqueue(asc_queue_t *, REQP, int);
2925 static REQP asc_dequeue(asc_queue_t *, int);
2926 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
2927 static int asc_rmqueue(asc_queue_t *, REQP);
2928 static void asc_execute_queue(asc_queue_t *);
2929 #ifdef CONFIG_PROC_FS
2930 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
2931 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
2932 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
2933 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
2934 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
2935 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
2936 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
2937 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
2938 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
2939 static int asc_prt_line(char *, int, char *fmt, ...);
2940 #endif /* CONFIG_PROC_FS */
2941
2942 /* Statistics function prototypes. */
2943 #ifdef ADVANSYS_STATS
2944 #ifdef CONFIG_PROC_FS
2945 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
2946 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
2947 #endif /* CONFIG_PROC_FS */
2948 #endif /* ADVANSYS_STATS */
2949
2950 /* Debug function prototypes. */
2951 #ifdef ADVANSYS_DEBUG
2952 static void asc_prt_scsi_host(struct Scsi_Host *);
2953 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
2954 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
2955 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
2956 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
2957 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
2958 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
2959 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
2960 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
2961 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
2962 static void asc_prt_hex(char *f, uchar *, int);
2963 #endif /* ADVANSYS_DEBUG */
2964
2965 #ifdef CONFIG_PROC_FS
2966 /*
2967  * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
2968  *
2969  * *buffer: I/O buffer
2970  * **start: if inout == FALSE pointer into buffer where user read should start
2971  * offset: current offset into a /proc/scsi/advansys/[0...] file
2972  * length: length of buffer
2973  * hostno: Scsi_Host host_no
2974  * inout: TRUE - user is writing; FALSE - user is reading
2975  *
2976  * Return the number of bytes read from or written to a
2977  * /proc/scsi/advansys/[0...] file.
2978  *
2979  * Note: This function uses the per board buffer 'prtbuf' which is
2980  * allocated when the board is initialized in advansys_detect(). The
2981  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
2982  * used to write to the buffer. The way asc_proc_copy() is written
2983  * if 'prtbuf' is too small it will not be overwritten. Instead the
2984  * user just won't get all the available statistics.
2985  */
2986 static int
2987 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
2988                    off_t offset, int length, int inout)
2989 {
2990         asc_board_t *boardp;
2991         char *cp;
2992         int cplen;
2993         int cnt;
2994         int totcnt;
2995         int leftlen;
2996         char *curbuf;
2997         off_t advoffset;
2998 #ifdef ADVANSYS_STATS
2999         int tgt_id;
3000 #endif /* ADVANSYS_STATS */
3001
3002         ASC_DBG(1, "advansys_proc_info: begin\n");
3003
3004         /*
3005          * User write not supported.
3006          */
3007         if (inout == TRUE) {
3008                 return (-ENOSYS);
3009         }
3010
3011         /*
3012          * User read of /proc/scsi/advansys/[0...] file.
3013          */
3014
3015         boardp = ASC_BOARDP(shost);
3016
3017         /* Copy read data starting at the beginning of the buffer. */
3018         *start = buffer;
3019         curbuf = buffer;
3020         advoffset = 0;
3021         totcnt = 0;
3022         leftlen = length;
3023
3024         /*
3025          * Get board configuration information.
3026          *
3027          * advansys_info() returns the board string from its own static buffer.
3028          */
3029         cp = (char *)advansys_info(shost);
3030         strcat(cp, "\n");
3031         cplen = strlen(cp);
3032         /* Copy board information. */
3033         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3034         totcnt += cnt;
3035         leftlen -= cnt;
3036         if (leftlen == 0) {
3037                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3038                 return totcnt;
3039         }
3040         advoffset += cplen;
3041         curbuf += cnt;
3042
3043         /*
3044          * Display Wide Board BIOS Information.
3045          */
3046         if (ASC_WIDE_BOARD(boardp)) {
3047                 cp = boardp->prtbuf;
3048                 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
3049                 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3050                 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3051                                   cplen);
3052                 totcnt += cnt;
3053                 leftlen -= cnt;
3054                 if (leftlen == 0) {
3055                         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3056                         return totcnt;
3057                 }
3058                 advoffset += cplen;
3059                 curbuf += cnt;
3060         }
3061
3062         /*
3063          * Display driver information for each device attached to the board.
3064          */
3065         cp = boardp->prtbuf;
3066         cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
3067         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3068         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3069         totcnt += cnt;
3070         leftlen -= cnt;
3071         if (leftlen == 0) {
3072                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3073                 return totcnt;
3074         }
3075         advoffset += cplen;
3076         curbuf += cnt;
3077
3078         /*
3079          * Display EEPROM configuration for the board.
3080          */
3081         cp = boardp->prtbuf;
3082         if (ASC_NARROW_BOARD(boardp)) {
3083                 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3084         } else {
3085                 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
3086         }
3087         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3088         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3089         totcnt += cnt;
3090         leftlen -= cnt;
3091         if (leftlen == 0) {
3092                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3093                 return totcnt;
3094         }
3095         advoffset += cplen;
3096         curbuf += cnt;
3097
3098         /*
3099          * Display driver configuration and information for the board.
3100          */
3101         cp = boardp->prtbuf;
3102         cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
3103         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3104         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3105         totcnt += cnt;
3106         leftlen -= cnt;
3107         if (leftlen == 0) {
3108                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3109                 return totcnt;
3110         }
3111         advoffset += cplen;
3112         curbuf += cnt;
3113
3114 #ifdef ADVANSYS_STATS
3115         /*
3116          * Display driver statistics for the board.
3117          */
3118         cp = boardp->prtbuf;
3119         cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
3120         ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3121         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3122         totcnt += cnt;
3123         leftlen -= cnt;
3124         if (leftlen == 0) {
3125                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3126                 return totcnt;
3127         }
3128         advoffset += cplen;
3129         curbuf += cnt;
3130
3131         /*
3132          * Display driver statistics for each target.
3133          */
3134         for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
3135                 cp = boardp->prtbuf;
3136                 cplen = asc_prt_target_stats(shost, tgt_id, cp,
3137                                              ASC_PRTBUF_SIZE);
3138                 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
3139                 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3140                                     cplen);
3141                 totcnt += cnt;
3142                 leftlen -= cnt;
3143                 if (leftlen == 0) {
3144                         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3145                         return totcnt;
3146                 }
3147                 advoffset += cplen;
3148                 curbuf += cnt;
3149         }
3150 #endif /* ADVANSYS_STATS */
3151
3152         /*
3153          * Display Asc Library dynamic configuration information
3154          * for the board.
3155          */
3156         cp = boardp->prtbuf;
3157         if (ASC_NARROW_BOARD(boardp)) {
3158                 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
3159         } else {
3160                 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
3161         }
3162         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3163         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3164         totcnt += cnt;
3165         leftlen -= cnt;
3166         if (leftlen == 0) {
3167                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3168                 return totcnt;
3169         }
3170         advoffset += cplen;
3171         curbuf += cnt;
3172
3173         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3174
3175         return totcnt;
3176 }
3177 #endif /* CONFIG_PROC_FS */
3178
3179 /*
3180  * advansys_info()
3181  *
3182  * Return suitable for printing on the console with the argument
3183  * adapter's configuration information.
3184  *
3185  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
3186  * otherwise the static 'info' array will be overrun.
3187  */
3188 static const char *advansys_info(struct Scsi_Host *shost)
3189 {
3190         static char info[ASC_INFO_SIZE];
3191         asc_board_t *boardp;
3192         ASC_DVC_VAR *asc_dvc_varp;
3193         ADV_DVC_VAR *adv_dvc_varp;
3194         char *busname;
3195         char *widename = NULL;
3196
3197         boardp = ASC_BOARDP(shost);
3198         if (ASC_NARROW_BOARD(boardp)) {
3199                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3200                 ASC_DBG(1, "advansys_info: begin\n");
3201                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3202                         if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
3203                             ASC_IS_ISAPNP) {
3204                                 busname = "ISA PnP";
3205                         } else {
3206                                 busname = "ISA";
3207                         }
3208                         sprintf(info,
3209                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
3210                                 ASC_VERSION, busname,
3211                                 (ulong)shost->io_port,
3212                                 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3213                                 shost->irq, shost->dma_channel);
3214                 } else {
3215                         if (asc_dvc_varp->bus_type & ASC_IS_VL) {
3216                                 busname = "VL";
3217                         } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
3218                                 busname = "EISA";
3219                         } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
3220                                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
3221                                     == ASC_IS_PCI_ULTRA) {
3222                                         busname = "PCI Ultra";
3223                                 } else {
3224                                         busname = "PCI";
3225                                 }
3226                         } else {
3227                                 busname = "?";
3228                                 ASC_PRINT2("advansys_info: board %d: unknown "
3229                                            "bus type %d\n", boardp->id,
3230                                            asc_dvc_varp->bus_type);
3231                         }
3232                         sprintf(info,
3233                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
3234                                 ASC_VERSION, busname, (ulong)shost->io_port,
3235                                 (ulong)shost->io_port + ASC_IOADR_GAP - 1,
3236                                 shost->irq);
3237                 }
3238         } else {
3239                 /*
3240                  * Wide Adapter Information
3241                  *
3242                  * Memory-mapped I/O is used instead of I/O space to access
3243                  * the adapter, but display the I/O Port range. The Memory
3244                  * I/O address is displayed through the driver /proc file.
3245                  */
3246                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3247                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3248                         widename = "Ultra-Wide";
3249                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3250                         widename = "Ultra2-Wide";
3251                 } else {
3252                         widename = "Ultra3-Wide";
3253                 }
3254                 sprintf(info,
3255                         "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
3256                         ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
3257                         (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
3258         }
3259         ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
3260         ASC_DBG(1, "advansys_info: end\n");
3261         return info;
3262 }
3263
3264 /*
3265  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
3266  *
3267  * This function always returns 0. Command return status is saved
3268  * in the 'scp' result field.
3269  */
3270 static int
3271 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
3272 {
3273         struct Scsi_Host *shost;
3274         asc_board_t *boardp;
3275         ulong flags;
3276         struct scsi_cmnd *done_scp;
3277
3278         shost = scp->device->host;
3279         boardp = ASC_BOARDP(shost);
3280         ASC_STATS(shost, queuecommand);
3281
3282         /* host_lock taken by mid-level prior to call but need to protect */
3283         /* against own ISR */
3284         spin_lock_irqsave(&boardp->lock, flags);
3285
3286         /*
3287          * Block new commands while handling a reset or abort request.
3288          */
3289         if (boardp->flags & ASC_HOST_IN_RESET) {
3290                 ASC_DBG1(1,
3291                          "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
3292                          (ulong)scp);
3293                 scp->result = HOST_BYTE(DID_RESET);
3294
3295                 /*
3296                  * Add blocked requests to the board's 'done' queue. The queued
3297                  * requests will be completed at the end of the abort or reset
3298                  * handling.
3299                  */
3300                 asc_enqueue(&boardp->done, scp, ASC_BACK);
3301                 spin_unlock_irqrestore(&boardp->lock, flags);
3302                 return 0;
3303         }
3304
3305         /*
3306          * Attempt to execute any waiting commands for the board.
3307          */
3308         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
3309                 ASC_DBG(1,
3310                         "advansys_queuecommand: before asc_execute_queue() waiting\n");
3311                 asc_execute_queue(&boardp->waiting);
3312         }
3313
3314         /*
3315          * Save the function pointer to Linux mid-level 'done' function
3316          * and attempt to execute the command.
3317          *
3318          * If ASC_NOERROR is returned the request has been added to the
3319          * board's 'active' queue and will be completed by the interrupt
3320          * handler.
3321          *
3322          * If ASC_BUSY is returned add the request to the board's per
3323          * target waiting list. This is the first time the request has
3324          * been tried. Add it to the back of the waiting list. It will be
3325          * retried later.
3326          *
3327          * If an error occurred, the request will have been placed on the
3328          * board's 'done' queue and must be completed before returning.
3329          */
3330         scp->scsi_done = done;
3331         switch (asc_execute_scsi_cmnd(scp)) {
3332         case ASC_NOERROR:
3333                 break;
3334         case ASC_BUSY:
3335                 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
3336                 break;
3337         case ASC_ERROR:
3338         default:
3339                 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
3340                 /* Interrupts could be enabled here. */
3341                 asc_scsi_done_list(done_scp);
3342                 break;
3343         }
3344         spin_unlock_irqrestore(&boardp->lock, flags);
3345
3346         return 0;
3347 }
3348
3349 /*
3350  * advansys_reset()
3351  *
3352  * Reset the bus associated with the command 'scp'.
3353  *
3354  * This function runs its own thread. Interrupts must be blocked but
3355  * sleeping is allowed and no locking other than for host structures is
3356  * required. Returns SUCCESS or FAILED.
3357  */
3358 static int advansys_reset(struct scsi_cmnd *scp)
3359 {
3360         struct Scsi_Host *shost;
3361         asc_board_t *boardp;
3362         ASC_DVC_VAR *asc_dvc_varp;
3363         ADV_DVC_VAR *adv_dvc_varp;
3364         ulong flags;
3365         struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
3366         struct scsi_cmnd *tscp, *new_last_scp;
3367         int status;
3368         int ret = SUCCESS;
3369
3370         ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
3371
3372 #ifdef ADVANSYS_STATS
3373         if (scp->device->host != NULL) {
3374                 ASC_STATS(scp->device->host, reset);
3375         }
3376 #endif /* ADVANSYS_STATS */
3377
3378         if ((shost = scp->device->host) == NULL) {
3379                 scp->result = HOST_BYTE(DID_ERROR);
3380                 return FAILED;
3381         }
3382
3383         boardp = ASC_BOARDP(shost);
3384
3385         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
3386                    boardp->id);
3387         /*
3388          * Check for re-entrancy.
3389          */
3390         spin_lock_irqsave(&boardp->lock, flags);
3391         if (boardp->flags & ASC_HOST_IN_RESET) {
3392                 spin_unlock_irqrestore(&boardp->lock, flags);
3393                 return FAILED;
3394         }
3395         boardp->flags |= ASC_HOST_IN_RESET;
3396         spin_unlock_irqrestore(&boardp->lock, flags);
3397
3398         if (ASC_NARROW_BOARD(boardp)) {
3399                 /*
3400                  * Narrow Board
3401                  */
3402                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3403
3404                 /*
3405                  * Reset the chip and SCSI bus.
3406                  */
3407                 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
3408                 status = AscInitAsc1000Driver(asc_dvc_varp);
3409
3410                 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
3411                 if (asc_dvc_varp->err_code) {
3412                         ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3413                                    "error: 0x%x\n", boardp->id,
3414                                    asc_dvc_varp->err_code);
3415                         ret = FAILED;
3416                 } else if (status) {
3417                         ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
3418                                    "warning: 0x%x\n", boardp->id, status);
3419                 } else {
3420                         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3421                                    "successful.\n", boardp->id);
3422                 }
3423
3424                 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
3425                 spin_lock_irqsave(&boardp->lock, flags);
3426
3427         } else {
3428                 /*
3429                  * Wide Board
3430                  *
3431                  * If the suggest reset bus flags are set, then reset the bus.
3432                  * Otherwise only reset the device.
3433                  */
3434                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3435
3436                 /*
3437                  * Reset the target's SCSI bus.
3438                  */
3439                 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
3440                 switch (AdvResetChipAndSB(adv_dvc_varp)) {
3441                 case ASC_TRUE:
3442                         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3443                                    "successful.\n", boardp->id);
3444                         break;
3445                 case ASC_FALSE:
3446                 default:
3447                         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
3448                                    "error.\n", boardp->id);
3449                         ret = FAILED;
3450                         break;
3451                 }
3452                 spin_lock_irqsave(&boardp->lock, flags);
3453                 (void)AdvISR(adv_dvc_varp);
3454         }
3455         /* Board lock is held. */
3456
3457         /*
3458          * Dequeue all board 'done' requests. A pointer to the last request
3459          * is returned in 'last_scp'.
3460          */
3461         done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
3462
3463         /*
3464          * Dequeue all board 'active' requests for all devices and set
3465          * the request status to DID_RESET. A pointer to the last request
3466          * is returned in 'last_scp'.
3467          */
3468         if (done_scp == NULL) {
3469                 done_scp = asc_dequeue_list(&boardp->active, &last_scp,
3470                                             ASC_TID_ALL);
3471                 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
3472                         tscp->result = HOST_BYTE(DID_RESET);
3473                 }
3474         } else {
3475                 /* Append to 'done_scp' at the end with 'last_scp'. */
3476                 ASC_ASSERT(last_scp != NULL);
3477                 last_scp->host_scribble =
3478                     (unsigned char *)asc_dequeue_list(&boardp->active,
3479                                                       &new_last_scp,
3480                                                       ASC_TID_ALL);
3481                 if (new_last_scp != NULL) {
3482                         ASC_ASSERT(REQPNEXT(last_scp) != NULL);
3483                         for (tscp = REQPNEXT(last_scp); tscp;
3484                              tscp = REQPNEXT(tscp)) {
3485                                 tscp->result = HOST_BYTE(DID_RESET);
3486                         }
3487                         last_scp = new_last_scp;
3488                 }
3489         }
3490
3491         /*
3492          * Dequeue all 'waiting' requests and set the request status
3493          * to DID_RESET.
3494          */
3495         if (done_scp == NULL) {
3496                 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
3497                                             ASC_TID_ALL);
3498                 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
3499                         tscp->result = HOST_BYTE(DID_RESET);
3500                 }
3501         } else {
3502                 /* Append to 'done_scp' at the end with 'last_scp'. */
3503                 ASC_ASSERT(last_scp != NULL);
3504                 last_scp->host_scribble =
3505                     (unsigned char *)asc_dequeue_list(&boardp->waiting,
3506                                                       &new_last_scp,
3507                                                       ASC_TID_ALL);
3508                 if (new_last_scp != NULL) {
3509                         ASC_ASSERT(REQPNEXT(last_scp) != NULL);
3510                         for (tscp = REQPNEXT(last_scp); tscp;
3511                              tscp = REQPNEXT(tscp)) {
3512                                 tscp->result = HOST_BYTE(DID_RESET);
3513                         }
3514                         last_scp = new_last_scp;
3515                 }
3516         }
3517
3518         /* Save the time of the most recently completed reset. */
3519         boardp->last_reset = jiffies;
3520
3521         /* Clear reset flag. */
3522         boardp->flags &= ~ASC_HOST_IN_RESET;
3523         spin_unlock_irqrestore(&boardp->lock, flags);
3524
3525         /*
3526          * Complete all the 'done_scp' requests.
3527          */
3528         if (done_scp)
3529                 asc_scsi_done_list(done_scp);
3530
3531         ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
3532
3533         return ret;
3534 }
3535
3536 /*
3537  * advansys_biosparam()
3538  *
3539  * Translate disk drive geometry if the "BIOS greater than 1 GB"
3540  * support is enabled for a drive.
3541  *
3542  * ip (information pointer) is an int array with the following definition:
3543  * ip[0]: heads
3544  * ip[1]: sectors
3545  * ip[2]: cylinders
3546  */
3547 static int
3548 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
3549                    sector_t capacity, int ip[])
3550 {
3551         asc_board_t *boardp;
3552
3553         ASC_DBG(1, "advansys_biosparam: begin\n");
3554         ASC_STATS(sdev->host, biosparam);
3555         boardp = ASC_BOARDP(sdev->host);
3556         if (ASC_NARROW_BOARD(boardp)) {
3557                 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
3558                      ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
3559                         ip[0] = 255;
3560                         ip[1] = 63;
3561                 } else {
3562                         ip[0] = 64;
3563                         ip[1] = 32;
3564                 }
3565         } else {
3566                 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
3567                      BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
3568                         ip[0] = 255;
3569                         ip[1] = 63;
3570                 } else {
3571                         ip[0] = 64;
3572                         ip[1] = 32;
3573                 }
3574         }
3575         ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
3576         ASC_DBG(1, "advansys_biosparam: end\n");
3577         return 0;
3578 }
3579
3580 static struct scsi_host_template advansys_template = {
3581         .proc_name = "advansys",
3582 #ifdef CONFIG_PROC_FS
3583         .proc_info = advansys_proc_info,
3584 #endif
3585         .name = "advansys",
3586         .info = advansys_info,
3587         .queuecommand = advansys_queuecommand,
3588         .eh_bus_reset_handler = advansys_reset,
3589         .bios_param = advansys_biosparam,
3590         .slave_configure = advansys_slave_configure,
3591         /*
3592          * Because the driver may control an ISA adapter 'unchecked_isa_dma'
3593          * must be set. The flag will be cleared in advansys_board_found
3594          * for non-ISA adapters.
3595          */
3596         .unchecked_isa_dma = 1,
3597         /*
3598          * All adapters controlled by this driver are capable of large
3599          * scatter-gather lists. According to the mid-level SCSI documentation
3600          * this obviates any performance gain provided by setting
3601          * 'use_clustering'. But empirically while CPU utilization is increased
3602          * by enabling clustering, I/O throughput increases as well.
3603          */
3604         .use_clustering = ENABLE_CLUSTERING,
3605 };
3606
3607 /*
3608  * --- Miscellaneous Driver Functions
3609  */
3610
3611 /*
3612  * First-level interrupt handler.
3613  *
3614  * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
3615  * all boards are currently checked for interrupts on each interrupt, 'dev_id'
3616  * is not referenced. 'dev_id' could be used to identify an interrupt passed
3617  * to the AdvanSys driver which is for a device sharing an interrupt with
3618  * an AdvanSys adapter.
3619  */
3620 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
3621 {
3622         unsigned long flags;
3623         struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
3624         struct scsi_cmnd *new_last_scp;
3625         struct Scsi_Host *shost = dev_id;
3626         asc_board_t *boardp = ASC_BOARDP(shost);
3627         irqreturn_t result = IRQ_NONE;
3628
3629         ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
3630         spin_lock_irqsave(&boardp->lock, flags);
3631         if (ASC_NARROW_BOARD(boardp)) {
3632                 /*
3633                  * Narrow Board
3634                  */
3635                 if (AscIsIntPending(shost->io_port)) {
3636                         result = IRQ_HANDLED;
3637                         ASC_STATS(shost, interrupt);
3638                         ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
3639                         AscISR(&boardp->dvc_var.asc_dvc_var);
3640                 }
3641         } else {
3642                 /*
3643                  * Wide Board
3644                  */
3645                 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
3646                 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
3647                         result = IRQ_HANDLED;
3648                         ASC_STATS(shost, interrupt);
3649                 }
3650         }
3651
3652         /*
3653          * Start waiting requests and create a list of completed requests.
3654          *
3655          * If a reset request is being performed for the board, the reset
3656          * handler will complete pending requests after it has completed.
3657          */
3658         if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
3659                 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
3660                          "last_scp 0x%p\n", done_scp, last_scp);
3661
3662                 /* Start any waiting commands for the board. */
3663                 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
3664                         ASC_DBG(1, "advansys_interrupt: before "
3665                                 "asc_execute_queue()\n");
3666                         asc_execute_queue(&boardp->waiting);
3667                 }
3668
3669                 /*
3670                  * Add to the list of requests that must be completed.
3671                  *
3672                  * 'done_scp' will always be NULL on the first iteration of
3673                  * this loop. 'last_scp' is set at the same time as 'done_scp'.
3674                  */
3675                 if (done_scp == NULL) {
3676                         done_scp = asc_dequeue_list(&boardp->done,
3677                                                 &last_scp, ASC_TID_ALL);
3678                 } else {
3679                         ASC_ASSERT(last_scp != NULL);
3680                         last_scp->host_scribble =
3681                             (unsigned char *)asc_dequeue_list(&boardp->
3682                                                               done,
3683                                                               &new_last_scp,
3684                                                               ASC_TID_ALL);
3685                         if (new_last_scp != NULL) {
3686                                 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
3687                                 last_scp = new_last_scp;
3688                         }
3689                 }
3690         }
3691         spin_unlock_irqrestore(&boardp->lock, flags);
3692
3693         /*
3694          * If interrupts were enabled on entry, then they
3695          * are now enabled here.
3696          *
3697          * Complete all requests on the done list.
3698          */
3699
3700         asc_scsi_done_list(done_scp);
3701
3702         ASC_DBG(1, "advansys_interrupt: end\n");
3703         return result;
3704 }
3705
3706 static void
3707 advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
3708 {
3709         ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
3710         ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
3711
3712         if (sdev->lun == 0) {
3713                 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
3714                 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
3715                         asc_dvc->init_sdtr |= tid_bit;
3716                 } else {
3717                         asc_dvc->init_sdtr &= ~tid_bit;
3718                 }
3719
3720                 if (orig_init_sdtr != asc_dvc->init_sdtr)
3721                         AscAsyncFix(asc_dvc, sdev);
3722         }
3723
3724         if (sdev->tagged_supported) {
3725                 if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
3726                         if (sdev->lun == 0) {
3727                                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
3728                                 asc_dvc->use_tagged_qng |= tid_bit;
3729                         }
3730                         scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3731                                                 asc_dvc->max_dvc_qng[sdev->id]);
3732                 }
3733         } else {
3734                 if (sdev->lun == 0) {
3735                         asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
3736                         asc_dvc->use_tagged_qng &= ~tid_bit;
3737                 }
3738                 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
3739         }
3740
3741         if ((sdev->lun == 0) &&
3742             (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
3743                 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
3744                                  asc_dvc->cfg->disc_enable);
3745                 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
3746                                  asc_dvc->use_tagged_qng);
3747                 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
3748                                  asc_dvc->cfg->can_tagged_qng);
3749
3750                 asc_dvc->max_dvc_qng[sdev->id] =
3751                                         asc_dvc->cfg->max_tag_qng[sdev->id];
3752                 AscWriteLramByte(asc_dvc->iop_base,
3753                                  (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
3754                                  asc_dvc->max_dvc_qng[sdev->id]);
3755         }
3756 }
3757
3758 /*
3759  * Wide Transfers
3760  *
3761  * If the EEPROM enabled WDTR for the device and the device supports wide
3762  * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
3763  * write the new value to the microcode.
3764  */
3765 static void
3766 advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
3767 {
3768         unsigned short cfg_word;
3769         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
3770         if ((cfg_word & tidmask) != 0)
3771                 return;
3772
3773         cfg_word |= tidmask;
3774         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
3775
3776         /*
3777          * Clear the microcode SDTR and WDTR negotiation done indicators for
3778          * the target to cause it to negotiate with the new setting set above.
3779          * WDTR when accepted causes the target to enter asynchronous mode, so
3780          * SDTR must be negotiated.
3781          */
3782         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3783         cfg_word &= ~tidmask;
3784         AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3785         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3786         cfg_word &= ~tidmask;
3787         AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
3788 }
3789
3790 /*
3791  * Synchronous Transfers
3792  *
3793  * If the EEPROM enabled SDTR for the device and the device
3794  * supports synchronous transfers, then turn on the device's
3795  * 'sdtr_able' bit. Write the new value to the microcode.
3796  */
3797 static void
3798 advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
3799 {
3800         unsigned short cfg_word;
3801         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3802         if ((cfg_word & tidmask) != 0)
3803                 return;
3804
3805         cfg_word |= tidmask;
3806         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
3807
3808         /*
3809          * Clear the microcode "SDTR negotiation" done indicator for the
3810          * target to cause it to negotiate with the new setting set above.
3811          */
3812         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3813         cfg_word &= ~tidmask;
3814         AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
3815 }
3816
3817 /*
3818  * PPR (Parallel Protocol Request) Capable
3819  *
3820  * If the device supports DT mode, then it must be PPR capable.
3821  * The PPR message will be used in place of the SDTR and WDTR
3822  * messages to negotiate synchronous speed and offset, transfer
3823  * width, and protocol options.
3824  */
3825 static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
3826                                 AdvPortAddr iop_base, unsigned short tidmask)
3827 {
3828         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3829         adv_dvc->ppr_able |= tidmask;
3830         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
3831 }
3832
3833 static void
3834 advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
3835 {
3836         AdvPortAddr iop_base = adv_dvc->iop_base;
3837         unsigned short tidmask = 1 << sdev->id;
3838
3839         if (sdev->lun == 0) {
3840                 /*
3841                  * Handle WDTR, SDTR, and Tag Queuing. If the feature
3842                  * is enabled in the EEPROM and the device supports the
3843                  * feature, then enable it in the microcode.
3844                  */
3845
3846                 if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
3847                         advansys_wide_enable_wdtr(iop_base, tidmask);
3848                 if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
3849                         advansys_wide_enable_sdtr(iop_base, tidmask);
3850                 if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
3851                         advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
3852
3853                 /*
3854                  * Tag Queuing is disabled for the BIOS which runs in polled
3855                  * mode and would see no benefit from Tag Queuing. Also by
3856                  * disabling Tag Queuing in the BIOS devices with Tag Queuing
3857                  * bugs will at least work with the BIOS.
3858                  */
3859                 if ((adv_dvc->tagqng_able & tidmask) &&
3860                     sdev->tagged_supported) {
3861                         unsigned short cfg_word;
3862                         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
3863                         cfg_word |= tidmask;
3864                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
3865                                          cfg_word);
3866                         AdvWriteByteLram(iop_base,
3867                                          ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
3868                                          adv_dvc->max_dvc_qng);
3869                 }
3870         }
3871
3872         if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
3873                 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
3874                                         adv_dvc->max_dvc_qng);
3875         } else {
3876                 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
3877         }
3878 }
3879
3880 /*
3881  * Set the number of commands to queue per device for the
3882  * specified host adapter.
3883  */
3884 static int advansys_slave_configure(struct scsi_device *sdev)
3885 {
3886         asc_board_t *boardp = ASC_BOARDP(sdev->host);
3887         boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
3888
3889         /*
3890          * Save a pointer to the sdev and set its initial/maximum
3891          * queue depth.  Only save the pointer for a lun0 dev though.
3892          */
3893         if (sdev->lun == 0)
3894                 boardp->device[sdev->id] = sdev;
3895
3896         if (ASC_NARROW_BOARD(boardp))
3897                 advansys_narrow_slave_configure(sdev,
3898                                                 &boardp->dvc_var.asc_dvc_var);
3899         else
3900                 advansys_wide_slave_configure(sdev,
3901                                                 &boardp->dvc_var.adv_dvc_var);
3902
3903         return 0;
3904 }
3905
3906 /*
3907  * Complete all requests on the singly linked list pointed
3908  * to by 'scp'.
3909  *
3910  * Interrupts can be enabled on entry.
3911  */
3912 static void asc_scsi_done_list(struct scsi_cmnd *scp)
3913 {
3914         struct scsi_cmnd *tscp;
3915
3916         ASC_DBG(2, "asc_scsi_done_list: begin\n");
3917         while (scp != NULL) {
3918                 asc_board_t *boardp;
3919
3920                 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
3921                 tscp = REQPNEXT(scp);
3922                 scp->host_scribble = NULL;
3923
3924                 boardp = ASC_BOARDP(scp->device->host);
3925
3926                 if (scp->use_sg)
3927                         dma_unmap_sg(boardp->dev,
3928                                      (struct scatterlist *)scp->request_buffer,
3929                                      scp->use_sg, scp->sc_data_direction);
3930                 else if (scp->request_bufflen)
3931                         dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
3932                                          scp->request_bufflen,
3933                                          scp->sc_data_direction);
3934
3935                 ASC_STATS(scp->device->host, done);
3936                 ASC_ASSERT(scp->scsi_done != NULL);
3937
3938                 scp->scsi_done(scp);
3939
3940                 scp = tscp;
3941         }
3942         ASC_DBG(2, "asc_scsi_done_list: done\n");
3943         return;
3944 }
3945
3946 /*
3947  * Execute a single 'Scsi_Cmnd'.
3948  *
3949  * The function 'done' is called when the request has been completed.
3950  *
3951  * Scsi_Cmnd:
3952  *
3953  *  host - board controlling device
3954  *  device - device to send command
3955  *  target - target of device
3956  *  lun - lun of device
3957  *  cmd_len - length of SCSI CDB
3958  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
3959  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
3960  *
3961  *  if (use_sg == 0) {
3962  *    request_buffer - buffer address for request
3963  *    request_bufflen - length of request buffer
3964  *  } else {
3965  *    request_buffer - pointer to scatterlist structure
3966  *  }
3967  *
3968  *  sense_buffer - sense command buffer
3969  *
3970  *  result (4 bytes of an int):
3971  *    Byte Meaning
3972  *    0 SCSI Status Byte Code
3973  *    1 SCSI One Byte Message Code
3974  *    2 Host Error Code
3975  *    3 Mid-Level Error Code
3976  *
3977  *  host driver fields:
3978  *    SCp - Scsi_Pointer used for command processing status
3979  *    scsi_done - used to save caller's done function
3980  *    host_scribble - used for pointer to another struct scsi_cmnd
3981  *
3982  * If this function returns ASC_NOERROR the request has been enqueued
3983  * on the board's 'active' queue and will be completed from the
3984  * interrupt handler.
3985  *
3986  * If this function returns ASC_NOERROR the request has been enqueued
3987  * on the board's 'done' queue and must be completed by the caller.
3988  *
3989  * If ASC_BUSY is returned the request will be enqueued by the
3990  * caller on the target's waiting queue and re-tried later.
3991  */
3992 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
3993 {
3994         asc_board_t *boardp;
3995         ASC_DVC_VAR *asc_dvc_varp;
3996         ADV_DVC_VAR *adv_dvc_varp;
3997         ADV_SCSI_REQ_Q *adv_scsiqp;
3998         struct scsi_device *device;
3999         int ret;
4000
4001         ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4002                  (ulong)scp, (ulong)scp->scsi_done);
4003
4004         boardp = ASC_BOARDP(scp->device->host);
4005         device = boardp->device[scp->device->id];
4006
4007         if (ASC_NARROW_BOARD(boardp)) {
4008                 /*
4009                  * Build and execute Narrow Board request.
4010                  */
4011
4012                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4013
4014                 /*
4015                  * Build Asc Library request structure using the
4016                  * global structures 'asc_scsi_req' and 'asc_sg_head'.
4017                  *
4018                  * If an error is returned, then the request has been
4019                  * queued on the board done queue. It will be completed
4020                  * by the caller.
4021                  *
4022                  * asc_build_req() can not return ASC_BUSY.
4023                  */
4024                 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4025                         ASC_STATS(scp->device->host, build_error);
4026                         return ASC_ERROR;
4027                 }
4028
4029                 /*
4030                  * Execute the command. If there is no error, add the command
4031                  * to the active queue.
4032                  */
4033                 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4034                 case ASC_NOERROR:
4035                         ASC_STATS(scp->device->host, exe_noerror);
4036                         /*
4037                          * Increment monotonically increasing per device
4038                          * successful request counter. Wrapping doesn't matter.
4039                          */
4040                         boardp->reqcnt[scp->device->id]++;
4041                         asc_enqueue(&boardp->active, scp, ASC_BACK);
4042                         ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
4043                                 "ASC_NOERROR\n");
4044                         break;
4045                 case ASC_BUSY:
4046                         /*
4047                          * Caller will enqueue request on the target's waiting
4048                          * queue and retry later.
4049                          */
4050                         ASC_STATS(scp->device->host, exe_busy);
4051                         break;
4052                 case ASC_ERROR:
4053                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4054                                 "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4055                                 boardp->id, asc_dvc_varp->err_code);
4056                         ASC_STATS(scp->device->host, exe_error);
4057                         scp->result = HOST_BYTE(DID_ERROR);
4058                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4059                         break;
4060                 default:
4061                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4062                                 "AscExeScsiQueue() unknown, err_code 0x%x\n",
4063                                 boardp->id, asc_dvc_varp->err_code);
4064                         ASC_STATS(scp->device->host, exe_unknown);
4065                         scp->result = HOST_BYTE(DID_ERROR);
4066                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4067                         break;
4068                 }
4069         } else {
4070                 /*
4071                  * Build and execute Wide Board request.
4072                  */
4073                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4074
4075                 /*
4076                  * Build and get a pointer to an Adv Library request structure.
4077                  *
4078                  * If the request is successfully built then send it below,
4079                  * otherwise return with an error.
4080                  */
4081                 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4082                 case ASC_NOERROR:
4083                         ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
4084                                 "ASC_NOERROR\n");
4085                         break;
4086                 case ASC_BUSY:
4087                         ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4088                                 "ASC_BUSY\n");
4089                         /*
4090                          * If busy is returned the request has not been
4091                          * enqueued.  It will be enqueued by the caller on the
4092                          * target's waiting queue and retried later.
4093                          *
4094                          * The asc_stats fields 'adv_build_noreq' and
4095                          * 'adv_build_nosg' count wide board busy conditions.
4096                          * They are updated in adv_build_req and
4097                          * adv_get_sglist, respectively.
4098                          */
4099                         return ASC_BUSY;
4100                 case ASC_ERROR:
4101                         /* 
4102                          * If an error is returned, then the request has been
4103                          * queued on the board done queue. It will be completed
4104                          * by the caller.
4105                          */
4106                 default:
4107                         ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4108                                 "ASC_ERROR\n");
4109                         ASC_STATS(scp->device->host, build_error);
4110                         return ASC_ERROR;
4111                 }
4112
4113                 /*
4114                  * Execute the command. If there is no error, add the command
4115                  * to the active queue.
4116                  */
4117                 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4118                 case ASC_NOERROR:
4119                         ASC_STATS(scp->device->host, exe_noerror);
4120                         /*
4121                          * Increment monotonically increasing per device
4122                          * successful request counter. Wrapping doesn't matter.
4123                          */
4124                         boardp->reqcnt[scp->device->id]++;
4125                         asc_enqueue(&boardp->active, scp, ASC_BACK);
4126                         ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
4127                                 "ASC_NOERROR\n");
4128                         break;
4129                 case ASC_BUSY:
4130                         /*
4131                          * Caller will enqueue request on the target's waiting
4132                          * queue and retry later.
4133                          */
4134                         ASC_STATS(scp->device->host, exe_busy);
4135                         break;
4136                 case ASC_ERROR:
4137                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4138                                 "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4139                                 boardp->id, adv_dvc_varp->err_code);
4140                         ASC_STATS(scp->device->host, exe_error);
4141                         scp->result = HOST_BYTE(DID_ERROR);
4142                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4143                         break;
4144                 default:
4145                         ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
4146                                 "AdvExeScsiQueue() unknown, err_code 0x%x\n",
4147                                 boardp->id, adv_dvc_varp->err_code);
4148                         ASC_STATS(scp->device->host, exe_unknown);
4149                         scp->result = HOST_BYTE(DID_ERROR);
4150                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4151                         break;
4152                 }
4153         }
4154
4155         ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4156         return ret;
4157 }
4158
4159 /*
4160  * Build a request structure for the Asc Library (Narrow Board).
4161  *
4162  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4163  * used to build the request.
4164  *
4165  * If an error occurs, then queue the request on the board done
4166  * queue and return ASC_ERROR.
4167  */
4168 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4169 {
4170         /*
4171          * Mutually exclusive access is required to 'asc_scsi_q' and
4172          * 'asc_sg_head' until after the request is started.
4173          */
4174         memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4175
4176         /*
4177          * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4178          */
4179         asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4180
4181         /*
4182          * Build the ASC_SCSI_Q request.
4183          *
4184          * For narrow boards a CDB length maximum of 12 bytes
4185          * is supported.
4186          */
4187         if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4188                 ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
4189                         "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
4190                         ASC_MAX_CDB_LEN);
4191                 scp->result = HOST_BYTE(DID_ERROR);
4192                 asc_enqueue(&boardp->done, scp, ASC_BACK);
4193                 return ASC_ERROR;
4194         }
4195         asc_scsi_q.cdbptr = &scp->cmnd[0];
4196         asc_scsi_q.q2.cdb_len = scp->cmd_len;
4197         asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4198         asc_scsi_q.q1.target_lun = scp->device->lun;
4199         asc_scsi_q.q2.target_ix =
4200             ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4201         asc_scsi_q.q1.sense_addr =
4202             cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4203         asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4204
4205         /*
4206          * If there are any outstanding requests for the current target,
4207          * then every 255th request send an ORDERED request. This heuristic
4208          * tries to retain the benefit of request sorting while preventing
4209          * request starvation. 255 is the max number of tags or pending commands
4210          * a device may have outstanding.
4211          *
4212          * The request count is incremented below for every successfully
4213          * started request.
4214          *
4215          */
4216         if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
4217             (boardp->reqcnt[scp->device->id] % 255) == 0) {
4218                 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
4219         } else {
4220                 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
4221         }
4222
4223         /*
4224          * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
4225          * buffer command.
4226          */
4227         if (scp->use_sg == 0) {
4228                 /*
4229                  * CDB request of single contiguous buffer.
4230                  */
4231                 ASC_STATS(scp->device->host, cont_cnt);
4232                 scp->SCp.dma_handle = scp->request_bufflen ?
4233                     dma_map_single(boardp->dev, scp->request_buffer,
4234                                    scp->request_bufflen,
4235                                    scp->sc_data_direction) : 0;
4236                 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
4237                 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
4238                 ASC_STATS_ADD(scp->device->host, cont_xfer,
4239                               ASC_CEILING(scp->request_bufflen, 512));
4240                 asc_scsi_q.q1.sg_queue_cnt = 0;
4241                 asc_scsi_q.sg_head = NULL;
4242         } else {
4243                 /*
4244                  * CDB scatter-gather request list.
4245                  */
4246                 int sgcnt;
4247                 int use_sg;
4248                 struct scatterlist *slp;
4249
4250                 slp = (struct scatterlist *)scp->request_buffer;
4251                 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4252                                     scp->sc_data_direction);
4253
4254                 if (use_sg > scp->device->host->sg_tablesize) {
4255                         ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
4256                                    "sg_tablesize %d\n", boardp->id, use_sg,
4257                                    scp->device->host->sg_tablesize);
4258                         dma_unmap_sg(boardp->dev, slp, scp->use_sg,
4259                                      scp->sc_data_direction);
4260                         scp->result = HOST_BYTE(DID_ERROR);
4261                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4262                         return ASC_ERROR;
4263                 }
4264
4265                 ASC_STATS(scp->device->host, sg_cnt);
4266
4267                 /*
4268                  * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
4269                  * structure to point to it.
4270                  */
4271                 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
4272
4273                 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
4274                 asc_scsi_q.sg_head = &asc_sg_head;
4275                 asc_scsi_q.q1.data_cnt = 0;
4276                 asc_scsi_q.q1.data_addr = 0;
4277                 /* This is a byte value, otherwise it would need to be swapped. */
4278                 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
4279                 ASC_STATS_ADD(scp->device->host, sg_elem,
4280                               asc_sg_head.entry_cnt);
4281
4282                 /*
4283                  * Convert scatter-gather list into ASC_SG_HEAD list.
4284                  */
4285                 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
4286                         asc_sg_head.sg_list[sgcnt].addr =
4287                             cpu_to_le32(sg_dma_address(slp));
4288                         asc_sg_head.sg_list[sgcnt].bytes =
4289                             cpu_to_le32(sg_dma_len(slp));
4290                         ASC_STATS_ADD(scp->device->host, sg_xfer,
4291                                       ASC_CEILING(sg_dma_len(slp), 512));
4292                 }
4293         }
4294
4295         ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
4296         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
4297
4298         return ASC_NOERROR;
4299 }
4300
4301 /*
4302  * Build a request structure for the Adv Library (Wide Board).
4303  *
4304  * If an adv_req_t can not be allocated to issue the request,
4305  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
4306  *
4307  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
4308  * microcode for DMA addresses or math operations are byte swapped
4309  * to little-endian order.
4310  */
4311 static int
4312 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
4313               ADV_SCSI_REQ_Q **adv_scsiqpp)
4314 {
4315         adv_req_t *reqp;
4316         ADV_SCSI_REQ_Q *scsiqp;
4317         int i;
4318         int ret;
4319
4320         /*
4321          * Allocate an adv_req_t structure from the board to execute
4322          * the command.
4323          */
4324         if (boardp->adv_reqp == NULL) {
4325                 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
4326                 ASC_STATS(scp->device->host, adv_build_noreq);
4327                 return ASC_BUSY;
4328         } else {
4329                 reqp = boardp->adv_reqp;
4330                 boardp->adv_reqp = reqp->next_reqp;
4331                 reqp->next_reqp = NULL;
4332         }
4333
4334         /*
4335          * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
4336          */
4337         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
4338
4339         /*
4340          * Initialize the structure.
4341          */
4342         scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
4343
4344         /*
4345          * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
4346          */
4347         scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
4348
4349         /*
4350          * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
4351          */
4352         reqp->cmndp = scp;
4353
4354         /*
4355          * Build the ADV_SCSI_REQ_Q request.
4356          */
4357
4358         /*
4359          * Set CDB length and copy it to the request structure.
4360          * For wide  boards a CDB length maximum of 16 bytes
4361          * is supported.
4362          */
4363         if (scp->cmd_len > ADV_MAX_CDB_LEN) {
4364                 ASC_PRINT3
4365                     ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
4366                      boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
4367                 scp->result = HOST_BYTE(DID_ERROR);
4368                 asc_enqueue(&boardp->done, scp, ASC_BACK);
4369                 return ASC_ERROR;
4370         }
4371         scsiqp->cdb_len = scp->cmd_len;
4372         /* Copy first 12 CDB bytes to cdb[]. */
4373         for (i = 0; i < scp->cmd_len && i < 12; i++) {
4374                 scsiqp->cdb[i] = scp->cmnd[i];
4375         }
4376         /* Copy last 4 CDB bytes, if present, to cdb16[]. */
4377         for (; i < scp->cmd_len; i++) {
4378                 scsiqp->cdb16[i - 12] = scp->cmnd[i];
4379         }
4380
4381         scsiqp->target_id = scp->device->id;
4382         scsiqp->target_lun = scp->device->lun;
4383
4384         scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4385         scsiqp->sense_len = sizeof(scp->sense_buffer);
4386
4387         /*
4388          * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
4389          * buffer command.
4390          */
4391
4392         scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
4393         scsiqp->vdata_addr = scp->request_buffer;
4394         scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
4395
4396         if (scp->use_sg == 0) {
4397                 /*
4398                  * CDB request of single contiguous buffer.
4399                  */
4400                 reqp->sgblkp = NULL;
4401                 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
4402                 if (scp->request_bufflen) {
4403                         scsiqp->vdata_addr = scp->request_buffer;
4404                         scp->SCp.dma_handle =
4405                             dma_map_single(boardp->dev, scp->request_buffer,
4406                                            scp->request_bufflen,
4407                                            scp->sc_data_direction);
4408                 } else {
4409                         scsiqp->vdata_addr = NULL;
4410                         scp->SCp.dma_handle = 0;
4411                 }
4412                 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
4413                 scsiqp->sg_list_ptr = NULL;
4414                 scsiqp->sg_real_addr = 0;
4415                 ASC_STATS(scp->device->host, cont_cnt);
4416                 ASC_STATS_ADD(scp->device->host, cont_xfer,
4417                               ASC_CEILING(scp->request_bufflen, 512));
4418         } else {
4419                 /*
4420                  * CDB scatter-gather request list.
4421                  */
4422                 struct scatterlist *slp;
4423                 int use_sg;
4424
4425                 slp = (struct scatterlist *)scp->request_buffer;
4426                 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
4427                                     scp->sc_data_direction);
4428
4429                 if (use_sg > ADV_MAX_SG_LIST) {
4430                         ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
4431                                    "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
4432                                    scp->device->host->sg_tablesize);
4433                         dma_unmap_sg(boardp->dev, slp, scp->use_sg,
4434                                      scp->sc_data_direction);
4435                         scp->result = HOST_BYTE(DID_ERROR);
4436                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4437
4438                         /*
4439                          * Free the 'adv_req_t' structure by adding it back
4440                          * to the board free list.
4441                          */
4442                         reqp->next_reqp = boardp->adv_reqp;
4443                         boardp->adv_reqp = reqp;
4444
4445                         return ASC_ERROR;
4446                 }
4447
4448                 ret = adv_get_sglist(boardp, reqp, scp, use_sg);
4449                 if (ret != ADV_SUCCESS) {
4450                         /*
4451                          * Free the adv_req_t structure by adding it back to
4452                          * the board free list.
4453                          */
4454                         reqp->next_reqp = boardp->adv_reqp;
4455                         boardp->adv_reqp = reqp;
4456
4457                         return ret;
4458                 }
4459
4460                 ASC_STATS(scp->device->host, sg_cnt);
4461                 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
4462         }
4463
4464         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4465         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
4466
4467         *adv_scsiqpp = scsiqp;
4468
4469         return ASC_NOERROR;
4470 }
4471
4472 /*
4473  * Build scatter-gather list for Adv Library (Wide Board).
4474  *
4475  * Additional ADV_SG_BLOCK structures will need to be allocated
4476  * if the total number of scatter-gather elements exceeds
4477  * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
4478  * assumed to be physically contiguous.
4479  *
4480  * Return:
4481  *      ADV_SUCCESS(1) - SG List successfully created
4482  *      ADV_ERROR(-1) - SG List creation failed
4483  */
4484 static int
4485 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
4486                int use_sg)
4487 {
4488         adv_sgblk_t *sgblkp;
4489         ADV_SCSI_REQ_Q *scsiqp;
4490         struct scatterlist *slp;
4491         int sg_elem_cnt;
4492         ADV_SG_BLOCK *sg_block, *prev_sg_block;
4493         ADV_PADDR sg_block_paddr;
4494         int i;
4495
4496         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
4497         slp = (struct scatterlist *)scp->request_buffer;
4498         sg_elem_cnt = use_sg;
4499         prev_sg_block = NULL;
4500         reqp->sgblkp = NULL;
4501
4502         do {
4503                 /*
4504                  * Allocate a 'adv_sgblk_t' structure from the board free
4505                  * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
4506                  * (15) scatter-gather elements.
4507                  */
4508                 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
4509                         ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
4510                         ASC_STATS(scp->device->host, adv_build_nosg);
4511
4512                         /*
4513                          * Allocation failed. Free 'adv_sgblk_t' structures already
4514                          * allocated for the request.
4515                          */
4516                         while ((sgblkp = reqp->sgblkp) != NULL) {
4517                                 /* Remove 'sgblkp' from the request list. */
4518                                 reqp->sgblkp = sgblkp->next_sgblkp;
4519
4520                                 /* Add 'sgblkp' to the board free list. */
4521                                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4522                                 boardp->adv_sgblkp = sgblkp;
4523                         }
4524                         return ASC_BUSY;
4525                 } else {
4526                         /* Complete 'adv_sgblk_t' board allocation. */
4527                         boardp->adv_sgblkp = sgblkp->next_sgblkp;
4528                         sgblkp->next_sgblkp = NULL;
4529
4530                         /*
4531                          * Get 8 byte aligned virtual and physical addresses for
4532                          * the allocated ADV_SG_BLOCK structure.
4533                          */
4534                         sg_block =
4535                             (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
4536                         sg_block_paddr = virt_to_bus(sg_block);
4537
4538                         /*
4539                          * Check if this is the first 'adv_sgblk_t' for the request.
4540                          */
4541                         if (reqp->sgblkp == NULL) {
4542                                 /* Request's first scatter-gather block. */
4543                                 reqp->sgblkp = sgblkp;
4544
4545                                 /*
4546                                  * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
4547                                  * address pointers.
4548                                  */
4549                                 scsiqp->sg_list_ptr = sg_block;
4550                                 scsiqp->sg_real_addr =
4551                                     cpu_to_le32(sg_block_paddr);
4552                         } else {
4553                                 /* Request's second or later scatter-gather block. */
4554                                 sgblkp->next_sgblkp = reqp->sgblkp;
4555                                 reqp->sgblkp = sgblkp;
4556
4557                                 /*
4558                                  * Point the previous ADV_SG_BLOCK structure to
4559                                  * the newly allocated ADV_SG_BLOCK structure.
4560                                  */
4561                                 ASC_ASSERT(prev_sg_block != NULL);
4562                                 prev_sg_block->sg_ptr =
4563                                     cpu_to_le32(sg_block_paddr);
4564                         }
4565                 }
4566
4567                 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
4568                         sg_block->sg_list[i].sg_addr =
4569                             cpu_to_le32(sg_dma_address(slp));
4570                         sg_block->sg_list[i].sg_count =
4571                             cpu_to_le32(sg_dma_len(slp));
4572                         ASC_STATS_ADD(scp->device->host, sg_xfer,
4573                                       ASC_CEILING(sg_dma_len(slp), 512));
4574
4575                         if (--sg_elem_cnt == 0) {       /* Last ADV_SG_BLOCK and scatter-gather entry. */
4576                                 sg_block->sg_cnt = i + 1;
4577                                 sg_block->sg_ptr = 0L;  /* Last ADV_SG_BLOCK in list. */
4578                                 return ADV_SUCCESS;
4579                         }
4580                         slp++;
4581                 }
4582                 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
4583                 prev_sg_block = sg_block;
4584         }
4585         while (1);
4586         /* NOTREACHED */
4587 }
4588
4589 /*
4590  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
4591  *
4592  * Interrupt callback function for the Narrow SCSI Asc Library.
4593  */
4594 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
4595 {
4596         asc_board_t *boardp;
4597         struct scsi_cmnd *scp;
4598         struct Scsi_Host *shost;
4599
4600         ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
4601                  (ulong)asc_dvc_varp, (ulong)qdonep);
4602         ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
4603
4604         /*
4605          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4606          * command that has been completed.
4607          */
4608         scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
4609         ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
4610
4611         if (scp == NULL) {
4612                 ASC_PRINT("asc_isr_callback: scp is NULL\n");
4613                 return;
4614         }
4615         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4616
4617         shost = scp->device->host;
4618         ASC_STATS(shost, callback);
4619         ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
4620
4621         /*
4622          * If the request isn't found on the active queue, it may
4623          * have been removed to handle a reset request.
4624          * Display a message and return.
4625          */
4626         boardp = ASC_BOARDP(shost);
4627         ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
4628         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
4629                 ASC_PRINT2
4630                     ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
4631                      boardp->id, (ulong)scp);
4632                 return;
4633         }
4634
4635         /*
4636          * 'qdonep' contains the command's ending status.
4637          */
4638         switch (qdonep->d3.done_stat) {
4639         case QD_NO_ERROR:
4640                 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
4641                 scp->result = 0;
4642
4643                 /*
4644                  * Check for an underrun condition.
4645                  *
4646                  * If there was no error and an underrun condition, then
4647                  * return the number of underrun bytes.
4648                  */
4649                 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
4650                     qdonep->remain_bytes <= scp->request_bufflen) {
4651                         ASC_DBG1(1,
4652                                  "asc_isr_callback: underrun condition %u bytes\n",
4653                                  (unsigned)qdonep->remain_bytes);
4654                         scp->resid = qdonep->remain_bytes;
4655                 }
4656                 break;
4657
4658         case QD_WITH_ERROR:
4659                 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
4660                 switch (qdonep->d3.host_stat) {
4661                 case QHSTA_NO_ERROR:
4662                         if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
4663                                 ASC_DBG(2,
4664                                         "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4665                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4666                                                   sizeof(scp->sense_buffer));
4667                                 /*
4668                                  * Note: The 'status_byte()' macro used by target drivers
4669                                  * defined in scsi.h shifts the status byte returned by
4670                                  * host drivers right by 1 bit. This is why target drivers
4671                                  * also use right shifted status byte definitions. For
4672                                  * instance target drivers use CHECK_CONDITION, defined to
4673                                  * 0x1, instead of the SCSI defined check condition value
4674                                  * of 0x2. Host drivers are supposed to return the status
4675                                  * byte as it is defined by SCSI.
4676                                  */
4677                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4678                                     STATUS_BYTE(qdonep->d3.scsi_stat);
4679                         } else {
4680                                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
4681                         }
4682                         break;
4683
4684                 default:
4685                         /* QHSTA error occurred */
4686                         ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
4687                                  qdonep->d3.host_stat);
4688                         scp->result = HOST_BYTE(DID_BAD_TARGET);
4689                         break;
4690                 }
4691                 break;
4692
4693         case QD_ABORTED_BY_HOST:
4694                 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
4695                 scp->result =
4696                     HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
4697                                                     scsi_msg) |
4698                     STATUS_BYTE(qdonep->d3.scsi_stat);
4699                 break;
4700
4701         default:
4702                 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
4703                          qdonep->d3.done_stat);
4704                 scp->result =
4705                     HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
4706                                                     scsi_msg) |
4707                     STATUS_BYTE(qdonep->d3.scsi_stat);
4708                 break;
4709         }
4710
4711         /*
4712          * If the 'init_tidmask' bit isn't already set for the target and the
4713          * current request finished normally, then set the bit for the target
4714          * to indicate that a device is present.
4715          */
4716         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4717             qdonep->d3.done_stat == QD_NO_ERROR &&
4718             qdonep->d3.host_stat == QHSTA_NO_ERROR) {
4719                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4720         }
4721
4722         /*
4723          * Because interrupts may be enabled by the 'struct scsi_cmnd' done
4724          * function, add the command to the end of the board's done queue.
4725          * The done function for the command will be called from
4726          * advansys_interrupt().
4727          */
4728         asc_enqueue(&boardp->done, scp, ASC_BACK);
4729
4730         return;
4731 }
4732
4733 /*
4734  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
4735  *
4736  * Callback function for the Wide SCSI Adv Library.
4737  */
4738 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
4739 {
4740         asc_board_t *boardp;
4741         adv_req_t *reqp;
4742         adv_sgblk_t *sgblkp;
4743         struct scsi_cmnd *scp;
4744         struct Scsi_Host *shost;
4745         ADV_DCNT resid_cnt;
4746
4747         ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
4748                  (ulong)adv_dvc_varp, (ulong)scsiqp);
4749         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
4750
4751         /*
4752          * Get the adv_req_t structure for the command that has been
4753          * completed. The adv_req_t structure actually contains the
4754          * completed ADV_SCSI_REQ_Q structure.
4755          */
4756         reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
4757         ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
4758         if (reqp == NULL) {
4759                 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
4760                 return;
4761         }
4762
4763         /*
4764          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
4765          * command that has been completed.
4766          *
4767          * Note: The adv_req_t request structure and adv_sgblk_t structure,
4768          * if any, are dropped, because a board structure pointer can not be
4769          * determined.
4770          */
4771         scp = reqp->cmndp;
4772         ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
4773         if (scp == NULL) {
4774                 ASC_PRINT
4775                     ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
4776                 return;
4777         }
4778         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
4779
4780         shost = scp->device->host;
4781         ASC_STATS(shost, callback);
4782         ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
4783
4784         /*
4785          * If the request isn't found on the active queue, it may have been
4786          * removed to handle a reset request. Display a message and return.
4787          *
4788          * Note: Because the structure may still be in use don't attempt
4789          * to free the adv_req_t and adv_sgblk_t, if any, structures.
4790          */
4791         boardp = ASC_BOARDP(shost);
4792         ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
4793         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
4794                 ASC_PRINT2
4795                     ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
4796                      boardp->id, (ulong)scp);
4797                 return;
4798         }
4799
4800         /*
4801          * 'done_status' contains the command's ending status.
4802          */
4803         switch (scsiqp->done_status) {
4804         case QD_NO_ERROR:
4805                 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
4806                 scp->result = 0;
4807
4808                 /*
4809                  * Check for an underrun condition.
4810                  *
4811                  * If there was no error and an underrun condition, then
4812                  * then return the number of underrun bytes.
4813                  */
4814                 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
4815                 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
4816                     resid_cnt <= scp->request_bufflen) {
4817                         ASC_DBG1(1,
4818                                  "adv_isr_callback: underrun condition %lu bytes\n",
4819                                  (ulong)resid_cnt);
4820                         scp->resid = resid_cnt;
4821                 }
4822                 break;
4823
4824         case QD_WITH_ERROR:
4825                 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
4826                 switch (scsiqp->host_status) {
4827                 case QHSTA_NO_ERROR:
4828                         if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
4829                                 ASC_DBG(2,
4830                                         "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
4831                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
4832                                                   sizeof(scp->sense_buffer));
4833                                 /*
4834                                  * Note: The 'status_byte()' macro used by target drivers
4835                                  * defined in scsi.h shifts the status byte returned by
4836                                  * host drivers right by 1 bit. This is why target drivers
4837                                  * also use right shifted status byte definitions. For
4838                                  * instance target drivers use CHECK_CONDITION, defined to
4839                                  * 0x1, instead of the SCSI defined check condition value
4840                                  * of 0x2. Host drivers are supposed to return the status
4841                                  * byte as it is defined by SCSI.
4842                                  */
4843                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
4844                                     STATUS_BYTE(scsiqp->scsi_status);
4845                         } else {
4846                                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
4847                         }
4848                         break;
4849
4850                 default:
4851                         /* Some other QHSTA error occurred. */
4852                         ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
4853                                  scsiqp->host_status);
4854                         scp->result = HOST_BYTE(DID_BAD_TARGET);
4855                         break;
4856                 }
4857                 break;
4858
4859         case QD_ABORTED_BY_HOST:
4860                 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
4861                 scp->result =
4862                     HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
4863                 break;
4864
4865         default:
4866                 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
4867                          scsiqp->done_status);
4868                 scp->result =
4869                     HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
4870                 break;
4871         }
4872
4873         /*
4874          * If the 'init_tidmask' bit isn't already set for the target and the
4875          * current request finished normally, then set the bit for the target
4876          * to indicate that a device is present.
4877          */
4878         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
4879             scsiqp->done_status == QD_NO_ERROR &&
4880             scsiqp->host_status == QHSTA_NO_ERROR) {
4881                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4882         }
4883
4884         /*
4885          * Because interrupts may be enabled by the 'struct scsi_cmnd' done
4886          * function, add the command to the end of the board's done queue.
4887          * The done function for the command will be called from
4888          * advansys_interrupt().
4889          */
4890         asc_enqueue(&boardp->done, scp, ASC_BACK);
4891
4892         /*
4893          * Free all 'adv_sgblk_t' structures allocated for the request.
4894          */
4895         while ((sgblkp = reqp->sgblkp) != NULL) {
4896                 /* Remove 'sgblkp' from the request list. */
4897                 reqp->sgblkp = sgblkp->next_sgblkp;
4898
4899                 /* Add 'sgblkp' to the board free list. */
4900                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
4901                 boardp->adv_sgblkp = sgblkp;
4902         }
4903
4904         /*
4905          * Free the adv_req_t structure used with the command by adding
4906          * it back to the board free list.
4907          */
4908         reqp->next_reqp = boardp->adv_reqp;
4909         boardp->adv_reqp = reqp;
4910
4911         ASC_DBG(1, "adv_isr_callback: done\n");
4912
4913         return;
4914 }
4915
4916 /*
4917  * adv_async_callback() - Adv Library asynchronous event callback function.
4918  */
4919 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
4920 {
4921         switch (code) {
4922         case ADV_ASYNC_SCSI_BUS_RESET_DET:
4923                 /*
4924                  * The firmware detected a SCSI Bus reset.
4925                  */
4926                 ASC_DBG(0,
4927                         "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
4928                 break;
4929
4930         case ADV_ASYNC_RDMA_FAILURE:
4931                 /*
4932                  * Handle RDMA failure by resetting the SCSI Bus and
4933                  * possibly the chip if it is unresponsive. Log the error
4934                  * with a unique code.
4935                  */
4936                 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
4937                 AdvResetChipAndSB(adv_dvc_varp);
4938                 break;
4939
4940         case ADV_HOST_SCSI_BUS_RESET:
4941                 /*
4942                  * Host generated SCSI bus reset occurred.
4943                  */
4944                 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
4945                 break;
4946
4947         default:
4948                 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
4949                 break;
4950         }
4951 }
4952
4953 /*
4954  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
4955  * to indicate a command is queued for the device.
4956  *
4957  * 'flag' may be either ASC_FRONT or ASC_BACK.
4958  *
4959  * 'REQPNEXT(reqp)' returns reqp's next pointer.
4960  */
4961 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
4962 {
4963         int tid;
4964
4965         ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
4966                  (ulong)ascq, (ulong)reqp, flag);
4967         ASC_ASSERT(reqp != NULL);
4968         ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
4969         tid = REQPTID(reqp);
4970         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
4971         if (flag == ASC_FRONT) {
4972                 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
4973                 ascq->q_first[tid] = reqp;
4974                 /* If the queue was empty, set the last pointer. */
4975                 if (ascq->q_last[tid] == NULL) {
4976                         ascq->q_last[tid] = reqp;
4977                 }
4978         } else {                /* ASC_BACK */
4979                 if (ascq->q_last[tid] != NULL) {
4980                         ascq->q_last[tid]->host_scribble =
4981                             (unsigned char *)reqp;
4982                 }
4983                 ascq->q_last[tid] = reqp;
4984                 reqp->host_scribble = NULL;
4985                 /* If the queue was empty, set the first pointer. */
4986                 if (ascq->q_first[tid] == NULL) {
4987                         ascq->q_first[tid] = reqp;
4988                 }
4989         }
4990         /* The queue has at least one entry, set its bit. */
4991         ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
4992 #ifdef ADVANSYS_STATS
4993         /* Maintain request queue statistics. */
4994         ascq->q_tot_cnt[tid]++;
4995         ascq->q_cur_cnt[tid]++;
4996         if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
4997                 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
4998                 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
4999                          tid, ascq->q_max_cnt[tid]);
5000         }
5001         REQPTIME(reqp) = REQTIMESTAMP();
5002 #endif /* ADVANSYS_STATS */
5003         ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5004         return;
5005 }
5006
5007 /*
5008  * Return first queued 'REQP' on the specified queue for
5009  * the specified target device. Clear the 'tidmask' bit for
5010  * the device if no more commands are left queued for it.
5011  *
5012  * 'REQPNEXT(reqp)' returns reqp's next pointer.
5013  */
5014 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5015 {
5016         REQP reqp;
5017
5018         ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5019         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5020         if ((reqp = ascq->q_first[tid]) != NULL) {
5021                 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5022                 ascq->q_first[tid] = REQPNEXT(reqp);
5023                 /* If the queue is empty, clear its bit and the last pointer. */
5024                 if (ascq->q_first[tid] == NULL) {
5025                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5026                         ASC_ASSERT(ascq->q_last[tid] == reqp);
5027                         ascq->q_last[tid] = NULL;
5028                 }
5029 #ifdef ADVANSYS_STATS
5030                 /* Maintain request queue statistics. */
5031                 ascq->q_cur_cnt[tid]--;
5032                 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5033                 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5034 #endif /* ADVANSYS_STATS */
5035         }
5036         ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5037         return reqp;
5038 }
5039
5040 /*
5041  * Return a pointer to a singly linked list of all the requests queued
5042  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5043  *
5044  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5045  * the last request returned in the singly linked list.
5046  *
5047  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5048  * then all queued requests are concatenated into one list and
5049  * returned.
5050  *
5051  * Note: If 'lastpp' is used to append a new list to the end of
5052  * an old list, only change the old list last pointer if '*lastpp'
5053  * (or the function return value) is not NULL, i.e. use a temporary
5054  * variable for 'lastpp' and check its value after the function return
5055  * before assigning it to the list last pointer.
5056  *
5057  * Unfortunately collecting queuing time statistics adds overhead to
5058  * the function that isn't inherent to the function's algorithm.
5059  */
5060 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5061 {
5062         REQP firstp, lastp;
5063         int i;
5064
5065         ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5066         ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5067
5068         /*
5069          * If 'tid' is not ASC_TID_ALL, return requests only for
5070          * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5071          * requests for all tids.
5072          */
5073         if (tid != ASC_TID_ALL) {
5074                 /* Return all requests for the specified 'tid'. */
5075                 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5076                         /* List is empty; Set first and last return pointers to NULL. */
5077                         firstp = lastp = NULL;
5078                 } else {
5079                         firstp = ascq->q_first[tid];
5080                         lastp = ascq->q_last[tid];
5081                         ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5082                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5083 #ifdef ADVANSYS_STATS
5084                         {
5085                                 REQP reqp;
5086                                 ascq->q_cur_cnt[tid] = 0;
5087                                 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5088                                         REQTIMESTAT("asc_dequeue_list", ascq,
5089                                                     reqp, tid);
5090                                 }
5091                         }
5092 #endif /* ADVANSYS_STATS */
5093                 }
5094         } else {
5095                 /* Return all requests for all tids. */
5096                 firstp = lastp = NULL;
5097                 for (i = 0; i <= ADV_MAX_TID; i++) {
5098                         if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5099                                 if (firstp == NULL) {
5100                                         firstp = ascq->q_first[i];
5101                                         lastp = ascq->q_last[i];
5102                                 } else {
5103                                         ASC_ASSERT(lastp != NULL);
5104                                         lastp->host_scribble =
5105                                             (unsigned char *)ascq->q_first[i];
5106                                         lastp = ascq->q_last[i];
5107                                 }
5108                                 ascq->q_first[i] = ascq->q_last[i] = NULL;
5109                                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5110 #ifdef ADVANSYS_STATS
5111                                 ascq->q_cur_cnt[i] = 0;
5112 #endif /* ADVANSYS_STATS */
5113                         }
5114                 }
5115 #ifdef ADVANSYS_STATS
5116                 {
5117                         REQP reqp;
5118                         for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5119                                 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5120                                             reqp->device->id);
5121                         }
5122                 }
5123 #endif /* ADVANSYS_STATS */
5124         }
5125         if (lastpp) {
5126                 *lastpp = lastp;
5127         }
5128         ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5129         return firstp;
5130 }
5131
5132 /*
5133  * Remove the specified 'REQP' from the specified queue for
5134  * the specified target device. Clear the 'tidmask' bit for the
5135  * device if no more commands are left queued for it.
5136  *
5137  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5138  *
5139  * Return ASC_TRUE if the command was found and removed,
5140  * otherwise return ASC_FALSE.
5141  */
5142 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5143 {
5144         REQP currp, prevp;
5145         int tid;
5146         int ret = ASC_FALSE;
5147
5148         ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5149                  (ulong)ascq, (ulong)reqp);
5150         ASC_ASSERT(reqp != NULL);
5151
5152         tid = REQPTID(reqp);
5153         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5154
5155         /*
5156          * Handle the common case of 'reqp' being the first
5157          * entry on the queue.
5158          */
5159         if (reqp == ascq->q_first[tid]) {
5160                 ret = ASC_TRUE;
5161                 ascq->q_first[tid] = REQPNEXT(reqp);
5162                 /* If the queue is now empty, clear its bit and the last pointer. */
5163                 if (ascq->q_first[tid] == NULL) {
5164                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5165                         ASC_ASSERT(ascq->q_last[tid] == reqp);
5166                         ascq->q_last[tid] = NULL;
5167                 }
5168         } else if (ascq->q_first[tid] != NULL) {
5169                 ASC_ASSERT(ascq->q_last[tid] != NULL);
5170                 /*
5171                  * Because the case of 'reqp' being the first entry has been
5172                  * handled above and it is known the queue is not empty, if
5173                  * 'reqp' is found on the queue it is guaranteed the queue will
5174                  * not become empty and that 'q_first[tid]' will not be changed.
5175                  *
5176                  * Set 'prevp' to the first entry, 'currp' to the second entry,
5177                  * and search for 'reqp'.
5178                  */
5179                 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5180                      currp; prevp = currp, currp = REQPNEXT(currp)) {
5181                         if (currp == reqp) {
5182                                 ret = ASC_TRUE;
5183                                 prevp->host_scribble =
5184                                     (unsigned char *)REQPNEXT(currp);
5185                                 reqp->host_scribble = NULL;
5186                                 if (ascq->q_last[tid] == reqp) {
5187                                         ascq->q_last[tid] = prevp;
5188                                 }
5189                                 break;
5190                         }
5191                 }
5192         }
5193 #ifdef ADVANSYS_STATS
5194         /* Maintain request queue statistics. */
5195         if (ret == ASC_TRUE) {
5196                 ascq->q_cur_cnt[tid]--;
5197                 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5198         }
5199         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5200 #endif /* ADVANSYS_STATS */
5201         ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
5202         return ret;
5203 }
5204
5205 /*
5206  * Execute as many queued requests as possible for the specified queue.
5207  *
5208  * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
5209  */
5210 static void asc_execute_queue(asc_queue_t *ascq)
5211 {
5212         ADV_SCSI_BIT_ID_TYPE scan_tidmask;
5213         REQP reqp;
5214         int i;
5215
5216         ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
5217         /*
5218          * Execute queued commands for devices attached to
5219          * the current board in round-robin fashion.
5220          */
5221         scan_tidmask = ascq->q_tidmask;
5222         do {
5223                 for (i = 0; i <= ADV_MAX_TID; i++) {
5224                         if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
5225                                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
5226                                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5227                                 } else
5228                                     if (asc_execute_scsi_cmnd
5229                                         ((struct scsi_cmnd *)reqp)
5230                                         == ASC_BUSY) {
5231                                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5232                                         /*
5233                                          * The request returned ASC_BUSY. Enqueue at the front of
5234                                          * target's waiting list to maintain correct ordering.
5235                                          */
5236                                         asc_enqueue(ascq, reqp, ASC_FRONT);
5237                                 }
5238                         }
5239                 }
5240         } while (scan_tidmask);
5241         return;
5242 }
5243
5244 #ifdef CONFIG_PROC_FS
5245 /*
5246  * asc_prt_board_devices()
5247  *
5248  * Print driver information for devices attached to the board.
5249  *
5250  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5251  * cf. asc_prt_line().
5252  *
5253  * Return the number of characters copied into 'cp'. No more than
5254  * 'cplen' characters will be copied to 'cp'.
5255  */
5256 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
5257 {
5258         asc_board_t *boardp;
5259         int leftlen;
5260         int totlen;
5261         int len;
5262         int chip_scsi_id;
5263         int i;
5264
5265         boardp = ASC_BOARDP(shost);
5266         leftlen = cplen;
5267         totlen = len = 0;
5268
5269         len = asc_prt_line(cp, leftlen,
5270                            "\nDevice Information for AdvanSys SCSI Host %d:\n",
5271                            shost->host_no);
5272         ASC_PRT_NEXT();
5273
5274         if (ASC_NARROW_BOARD(boardp)) {
5275                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
5276         } else {
5277                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
5278         }
5279
5280         len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
5281         ASC_PRT_NEXT();
5282         for (i = 0; i <= ADV_MAX_TID; i++) {
5283                 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
5284                         len = asc_prt_line(cp, leftlen, " %X,", i);
5285                         ASC_PRT_NEXT();
5286                 }
5287         }
5288         len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
5289         ASC_PRT_NEXT();
5290
5291         return totlen;
5292 }
5293
5294 /*
5295  * Display Wide Board BIOS Information.
5296  */
5297 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
5298 {
5299         asc_board_t *boardp;
5300         int leftlen;
5301         int totlen;
5302         int len;
5303         ushort major, minor, letter;
5304
5305         boardp = ASC_BOARDP(shost);
5306         leftlen = cplen;
5307         totlen = len = 0;
5308
5309         len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
5310         ASC_PRT_NEXT();
5311
5312         /*
5313          * If the BIOS saved a valid signature, then fill in
5314          * the BIOS code segment base address.
5315          */
5316         if (boardp->bios_signature != 0x55AA) {
5317                 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
5318                 ASC_PRT_NEXT();
5319                 len = asc_prt_line(cp, leftlen,
5320                                    "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
5321                 ASC_PRT_NEXT();
5322                 len = asc_prt_line(cp, leftlen,
5323                                    "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
5324                 ASC_PRT_NEXT();
5325         } else {
5326                 major = (boardp->bios_version >> 12) & 0xF;
5327                 minor = (boardp->bios_version >> 8) & 0xF;
5328                 letter = (boardp->bios_version & 0xFF);
5329
5330                 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
5331                                    major, minor,
5332                                    letter >= 26 ? '?' : letter + 'A');
5333                 ASC_PRT_NEXT();
5334
5335                 /*
5336                  * Current available ROM BIOS release is 3.1I for UW
5337                  * and 3.2I for U2W. This code doesn't differentiate
5338                  * UW and U2W boards.
5339                  */
5340                 if (major < 3 || (major <= 3 && minor < 1) ||
5341                     (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
5342                         len = asc_prt_line(cp, leftlen,
5343                                            "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
5344                         ASC_PRT_NEXT();
5345                         len = asc_prt_line(cp, leftlen,
5346                                            "ftp://ftp.connectcom.net/pub\n");
5347                         ASC_PRT_NEXT();
5348                 }
5349         }
5350
5351         return totlen;
5352 }
5353
5354 /*
5355  * Add serial number to information bar if signature AAh
5356  * is found in at bit 15-9 (7 bits) of word 1.
5357  *
5358  * Serial Number consists fo 12 alpha-numeric digits.
5359  *
5360  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
5361  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
5362  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
5363  *       5 - Product revision (A-J)    Word0:  "         "
5364  *
5365  *           Signature                 Word1: 15-9 (7 bits)
5366  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
5367  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
5368  *
5369  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
5370  *
5371  * Note 1: Only production cards will have a serial number.
5372  *
5373  * Note 2: Signature is most significant 7 bits (0xFE).
5374  *
5375  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
5376  */
5377 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
5378 {
5379         ushort w, num;
5380
5381         if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
5382                 return ASC_FALSE;
5383         } else {
5384                 /*
5385                  * First word - 6 digits.
5386                  */
5387                 w = serialnum[0];
5388
5389                 /* Product type - 1st digit. */
5390                 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
5391                         /* Product type is P=Prototype */
5392                         *cp += 0x8;
5393                 }
5394                 cp++;
5395
5396                 /* Manufacturing location - 2nd digit. */
5397                 *cp++ = 'A' + ((w & 0x1C00) >> 10);
5398
5399                 /* Product ID - 3rd, 4th digits. */
5400                 num = w & 0x3FF;
5401                 *cp++ = '0' + (num / 100);
5402                 num %= 100;
5403                 *cp++ = '0' + (num / 10);
5404
5405                 /* Product revision - 5th digit. */
5406                 *cp++ = 'A' + (num % 10);
5407
5408                 /*
5409                  * Second word
5410                  */
5411                 w = serialnum[1];
5412
5413                 /*
5414                  * Year - 6th digit.
5415                  *
5416                  * If bit 15 of third word is set, then the
5417                  * last digit of the year is greater than 7.
5418                  */
5419                 if (serialnum[2] & 0x8000) {
5420                         *cp++ = '8' + ((w & 0x1C0) >> 6);
5421                 } else {
5422                         *cp++ = '0' + ((w & 0x1C0) >> 6);
5423                 }
5424
5425                 /* Week of year - 7th, 8th digits. */
5426                 num = w & 0x003F;
5427                 *cp++ = '0' + num / 10;
5428                 num %= 10;
5429                 *cp++ = '0' + num;
5430
5431                 /*
5432                  * Third word
5433                  */
5434                 w = serialnum[2] & 0x7FFF;
5435
5436                 /* Serial number - 9th digit. */
5437                 *cp++ = 'A' + (w / 1000);
5438
5439                 /* 10th, 11th, 12th digits. */
5440                 num = w % 1000;
5441                 *cp++ = '0' + num / 100;
5442                 num %= 100;
5443                 *cp++ = '0' + num / 10;
5444                 num %= 10;
5445                 *cp++ = '0' + num;
5446
5447                 *cp = '\0';     /* Null Terminate the string. */
5448                 return ASC_TRUE;
5449         }
5450 }
5451
5452 /*
5453  * asc_prt_asc_board_eeprom()
5454  *
5455  * Print board EEPROM configuration.
5456  *
5457  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5458  * cf. asc_prt_line().
5459  *
5460  * Return the number of characters copied into 'cp'. No more than
5461  * 'cplen' characters will be copied to 'cp'.
5462  */
5463 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
5464 {
5465         asc_board_t *boardp;
5466         ASC_DVC_VAR *asc_dvc_varp;
5467         int leftlen;
5468         int totlen;
5469         int len;
5470         ASCEEP_CONFIG *ep;
5471         int i;
5472 #ifdef CONFIG_ISA
5473         int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
5474 #endif /* CONFIG_ISA */
5475         uchar serialstr[13];
5476
5477         boardp = ASC_BOARDP(shost);
5478         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5479         ep = &boardp->eep_config.asc_eep;
5480
5481         leftlen = cplen;
5482         totlen = len = 0;
5483
5484         len = asc_prt_line(cp, leftlen,
5485                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
5486                            shost->host_no);
5487         ASC_PRT_NEXT();
5488
5489         if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
5490             == ASC_TRUE) {
5491                 len =
5492                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
5493                                  serialstr);
5494                 ASC_PRT_NEXT();
5495         } else {
5496                 if (ep->adapter_info[5] == 0xBB) {
5497                         len = asc_prt_line(cp, leftlen,
5498                                            " Default Settings Used for EEPROM-less Adapter.\n");
5499                         ASC_PRT_NEXT();
5500                 } else {
5501                         len = asc_prt_line(cp, leftlen,
5502                                            " Serial Number Signature Not Present.\n");
5503                         ASC_PRT_NEXT();
5504                 }
5505         }
5506
5507         len = asc_prt_line(cp, leftlen,
5508                            " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5509                            ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
5510                            ep->max_tag_qng);
5511         ASC_PRT_NEXT();
5512
5513         len = asc_prt_line(cp, leftlen,
5514                            " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
5515         ASC_PRT_NEXT();
5516
5517         len = asc_prt_line(cp, leftlen, " Target ID:           ");
5518         ASC_PRT_NEXT();
5519         for (i = 0; i <= ASC_MAX_TID; i++) {
5520                 len = asc_prt_line(cp, leftlen, " %d", i);
5521                 ASC_PRT_NEXT();
5522         }
5523         len = asc_prt_line(cp, leftlen, "\n");
5524         ASC_PRT_NEXT();
5525
5526         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
5527         ASC_PRT_NEXT();
5528         for (i = 0; i <= ASC_MAX_TID; i++) {
5529                 len = asc_prt_line(cp, leftlen, " %c",
5530                                    (ep->
5531                                     disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5532                                    'N');
5533                 ASC_PRT_NEXT();
5534         }
5535         len = asc_prt_line(cp, leftlen, "\n");
5536         ASC_PRT_NEXT();
5537
5538         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
5539         ASC_PRT_NEXT();
5540         for (i = 0; i <= ASC_MAX_TID; i++) {
5541                 len = asc_prt_line(cp, leftlen, " %c",
5542                                    (ep->
5543                                     use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5544                                    'N');
5545                 ASC_PRT_NEXT();
5546         }
5547         len = asc_prt_line(cp, leftlen, "\n");
5548         ASC_PRT_NEXT();
5549
5550         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
5551         ASC_PRT_NEXT();
5552         for (i = 0; i <= ASC_MAX_TID; i++) {
5553                 len = asc_prt_line(cp, leftlen, " %c",
5554                                    (ep->
5555                                     start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5556                                    'N');
5557                 ASC_PRT_NEXT();
5558         }
5559         len = asc_prt_line(cp, leftlen, "\n");
5560         ASC_PRT_NEXT();
5561
5562         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5563         ASC_PRT_NEXT();
5564         for (i = 0; i <= ASC_MAX_TID; i++) {
5565                 len = asc_prt_line(cp, leftlen, " %c",
5566                                    (ep->
5567                                     init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
5568                                    'N');
5569                 ASC_PRT_NEXT();
5570         }
5571         len = asc_prt_line(cp, leftlen, "\n");
5572         ASC_PRT_NEXT();
5573
5574 #ifdef CONFIG_ISA
5575         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5576                 len = asc_prt_line(cp, leftlen,
5577                                    " Host ISA DMA speed:   %d MB/S\n",
5578                                    isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
5579                 ASC_PRT_NEXT();
5580         }
5581 #endif /* CONFIG_ISA */
5582
5583         return totlen;
5584 }
5585
5586 /*
5587  * asc_prt_adv_board_eeprom()
5588  *
5589  * Print board EEPROM configuration.
5590  *
5591  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5592  * cf. asc_prt_line().
5593  *
5594  * Return the number of characters copied into 'cp'. No more than
5595  * 'cplen' characters will be copied to 'cp'.
5596  */
5597 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
5598 {
5599         asc_board_t *boardp;
5600         ADV_DVC_VAR *adv_dvc_varp;
5601         int leftlen;
5602         int totlen;
5603         int len;
5604         int i;
5605         char *termstr;
5606         uchar serialstr[13];
5607         ADVEEP_3550_CONFIG *ep_3550 = NULL;
5608         ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
5609         ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
5610         ushort word;
5611         ushort *wordp;
5612         ushort sdtr_speed = 0;
5613
5614         boardp = ASC_BOARDP(shost);
5615         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5616         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5617                 ep_3550 = &boardp->eep_config.adv_3550_eep;
5618         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5619                 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
5620         } else {
5621                 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
5622         }
5623
5624         leftlen = cplen;
5625         totlen = len = 0;
5626
5627         len = asc_prt_line(cp, leftlen,
5628                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
5629                            shost->host_no);
5630         ASC_PRT_NEXT();
5631
5632         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5633                 wordp = &ep_3550->serial_number_word1;
5634         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5635                 wordp = &ep_38C0800->serial_number_word1;
5636         } else {
5637                 wordp = &ep_38C1600->serial_number_word1;
5638         }
5639
5640         if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
5641                 len =
5642                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
5643                                  serialstr);
5644                 ASC_PRT_NEXT();
5645         } else {
5646                 len = asc_prt_line(cp, leftlen,
5647                                    " Serial Number Signature Not Present.\n");
5648                 ASC_PRT_NEXT();
5649         }
5650
5651         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5652                 len = asc_prt_line(cp, leftlen,
5653                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5654                                    ep_3550->adapter_scsi_id,
5655                                    ep_3550->max_host_qng, ep_3550->max_dvc_qng);
5656                 ASC_PRT_NEXT();
5657         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5658                 len = asc_prt_line(cp, leftlen,
5659                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5660                                    ep_38C0800->adapter_scsi_id,
5661                                    ep_38C0800->max_host_qng,
5662                                    ep_38C0800->max_dvc_qng);
5663                 ASC_PRT_NEXT();
5664         } else {
5665                 len = asc_prt_line(cp, leftlen,
5666                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
5667                                    ep_38C1600->adapter_scsi_id,
5668                                    ep_38C1600->max_host_qng,
5669                                    ep_38C1600->max_dvc_qng);
5670                 ASC_PRT_NEXT();
5671         }
5672         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5673                 word = ep_3550->termination;
5674         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5675                 word = ep_38C0800->termination_lvd;
5676         } else {
5677                 word = ep_38C1600->termination_lvd;
5678         }
5679         switch (word) {
5680         case 1:
5681                 termstr = "Low Off/High Off";
5682                 break;
5683         case 2:
5684                 termstr = "Low Off/High On";
5685                 break;
5686         case 3:
5687                 termstr = "Low On/High On";
5688                 break;
5689         default:
5690         case 0:
5691                 termstr = "Automatic";
5692                 break;
5693         }
5694
5695         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5696                 len = asc_prt_line(cp, leftlen,
5697                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
5698                                    ep_3550->termination, termstr,
5699                                    ep_3550->bios_ctrl);
5700                 ASC_PRT_NEXT();
5701         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5702                 len = asc_prt_line(cp, leftlen,
5703                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
5704                                    ep_38C0800->termination_lvd, termstr,
5705                                    ep_38C0800->bios_ctrl);
5706                 ASC_PRT_NEXT();
5707         } else {
5708                 len = asc_prt_line(cp, leftlen,
5709                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
5710                                    ep_38C1600->termination_lvd, termstr,
5711                                    ep_38C1600->bios_ctrl);
5712                 ASC_PRT_NEXT();
5713         }
5714
5715         len = asc_prt_line(cp, leftlen, " Target ID:           ");
5716         ASC_PRT_NEXT();
5717         for (i = 0; i <= ADV_MAX_TID; i++) {
5718                 len = asc_prt_line(cp, leftlen, " %X", i);
5719                 ASC_PRT_NEXT();
5720         }
5721         len = asc_prt_line(cp, leftlen, "\n");
5722         ASC_PRT_NEXT();
5723
5724         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5725                 word = ep_3550->disc_enable;
5726         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5727                 word = ep_38C0800->disc_enable;
5728         } else {
5729                 word = ep_38C1600->disc_enable;
5730         }
5731         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
5732         ASC_PRT_NEXT();
5733         for (i = 0; i <= ADV_MAX_TID; i++) {
5734                 len = asc_prt_line(cp, leftlen, " %c",
5735                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5736                 ASC_PRT_NEXT();
5737         }
5738         len = asc_prt_line(cp, leftlen, "\n");
5739         ASC_PRT_NEXT();
5740
5741         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5742                 word = ep_3550->tagqng_able;
5743         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5744                 word = ep_38C0800->tagqng_able;
5745         } else {
5746                 word = ep_38C1600->tagqng_able;
5747         }
5748         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
5749         ASC_PRT_NEXT();
5750         for (i = 0; i <= ADV_MAX_TID; i++) {
5751                 len = asc_prt_line(cp, leftlen, " %c",
5752                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5753                 ASC_PRT_NEXT();
5754         }
5755         len = asc_prt_line(cp, leftlen, "\n");
5756         ASC_PRT_NEXT();
5757
5758         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5759                 word = ep_3550->start_motor;
5760         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5761                 word = ep_38C0800->start_motor;
5762         } else {
5763                 word = ep_38C1600->start_motor;
5764         }
5765         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
5766         ASC_PRT_NEXT();
5767         for (i = 0; i <= ADV_MAX_TID; i++) {
5768                 len = asc_prt_line(cp, leftlen, " %c",
5769                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5770                 ASC_PRT_NEXT();
5771         }
5772         len = asc_prt_line(cp, leftlen, "\n");
5773         ASC_PRT_NEXT();
5774
5775         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5776                 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
5777                 ASC_PRT_NEXT();
5778                 for (i = 0; i <= ADV_MAX_TID; i++) {
5779                         len = asc_prt_line(cp, leftlen, " %c",
5780                                            (ep_3550->
5781                                             sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
5782                                            'Y' : 'N');
5783                         ASC_PRT_NEXT();
5784                 }
5785                 len = asc_prt_line(cp, leftlen, "\n");
5786                 ASC_PRT_NEXT();
5787         }
5788
5789         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5790                 len = asc_prt_line(cp, leftlen, " Ultra Transfer:      ");
5791                 ASC_PRT_NEXT();
5792                 for (i = 0; i <= ADV_MAX_TID; i++) {
5793                         len = asc_prt_line(cp, leftlen, " %c",
5794                                            (ep_3550->
5795                                             ultra_able & ADV_TID_TO_TIDMASK(i))
5796                                            ? 'Y' : 'N');
5797                         ASC_PRT_NEXT();
5798                 }
5799                 len = asc_prt_line(cp, leftlen, "\n");
5800                 ASC_PRT_NEXT();
5801         }
5802
5803         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
5804                 word = ep_3550->wdtr_able;
5805         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5806                 word = ep_38C0800->wdtr_able;
5807         } else {
5808                 word = ep_38C1600->wdtr_able;
5809         }
5810         len = asc_prt_line(cp, leftlen, " Wide Transfer:       ");
5811         ASC_PRT_NEXT();
5812         for (i = 0; i <= ADV_MAX_TID; i++) {
5813                 len = asc_prt_line(cp, leftlen, " %c",
5814                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
5815                 ASC_PRT_NEXT();
5816         }
5817         len = asc_prt_line(cp, leftlen, "\n");
5818         ASC_PRT_NEXT();
5819
5820         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
5821             adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
5822                 len = asc_prt_line(cp, leftlen,
5823                                    " Synchronous Transfer Speed (Mhz):\n  ");
5824                 ASC_PRT_NEXT();
5825                 for (i = 0; i <= ADV_MAX_TID; i++) {
5826                         char *speed_str;
5827
5828                         if (i == 0) {
5829                                 sdtr_speed = adv_dvc_varp->sdtr_speed1;
5830                         } else if (i == 4) {
5831                                 sdtr_speed = adv_dvc_varp->sdtr_speed2;
5832                         } else if (i == 8) {
5833                                 sdtr_speed = adv_dvc_varp->sdtr_speed3;
5834                         } else if (i == 12) {
5835                                 sdtr_speed = adv_dvc_varp->sdtr_speed4;
5836                         }
5837                         switch (sdtr_speed & ADV_MAX_TID) {
5838                         case 0:
5839                                 speed_str = "Off";
5840                                 break;
5841                         case 1:
5842                                 speed_str = "  5";
5843                                 break;
5844                         case 2:
5845                                 speed_str = " 10";
5846                                 break;
5847                         case 3:
5848                                 speed_str = " 20";
5849                                 break;
5850                         case 4:
5851                                 speed_str = " 40";
5852                                 break;
5853                         case 5:
5854                                 speed_str = " 80";
5855                                 break;
5856                         default:
5857                                 speed_str = "Unk";
5858                                 break;
5859                         }
5860                         len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
5861                         ASC_PRT_NEXT();
5862                         if (i == 7) {
5863                                 len = asc_prt_line(cp, leftlen, "\n  ");
5864                                 ASC_PRT_NEXT();
5865                         }
5866                         sdtr_speed >>= 4;
5867                 }
5868                 len = asc_prt_line(cp, leftlen, "\n");
5869                 ASC_PRT_NEXT();
5870         }
5871
5872         return totlen;
5873 }
5874
5875 /*
5876  * asc_prt_driver_conf()
5877  *
5878  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5879  * cf. asc_prt_line().
5880  *
5881  * Return the number of characters copied into 'cp'. No more than
5882  * 'cplen' characters will be copied to 'cp'.
5883  */
5884 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
5885 {
5886         asc_board_t *boardp;
5887         int leftlen;
5888         int totlen;
5889         int len;
5890         int chip_scsi_id;
5891
5892         boardp = ASC_BOARDP(shost);
5893
5894         leftlen = cplen;
5895         totlen = len = 0;
5896
5897         len = asc_prt_line(cp, leftlen,
5898                            "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
5899                            shost->host_no);
5900         ASC_PRT_NEXT();
5901
5902         len = asc_prt_line(cp, leftlen,
5903                            " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
5904                            shost->host_busy, shost->last_reset, shost->max_id,
5905                            shost->max_lun, shost->max_channel);
5906         ASC_PRT_NEXT();
5907
5908         len = asc_prt_line(cp, leftlen,
5909                            " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
5910                            shost->unique_id, shost->can_queue, shost->this_id,
5911                            shost->sg_tablesize, shost->cmd_per_lun);
5912         ASC_PRT_NEXT();
5913
5914         len = asc_prt_line(cp, leftlen,
5915                            " unchecked_isa_dma %d, use_clustering %d\n",
5916                            shost->unchecked_isa_dma, shost->use_clustering);
5917         ASC_PRT_NEXT();
5918
5919         len = asc_prt_line(cp, leftlen,
5920                            " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
5921                            boardp->flags, boardp->last_reset, jiffies,
5922                            boardp->asc_n_io_port);
5923         ASC_PRT_NEXT();
5924
5925         len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
5926         ASC_PRT_NEXT();
5927
5928         if (ASC_NARROW_BOARD(boardp)) {
5929                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
5930         } else {
5931                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
5932         }
5933
5934         return totlen;
5935 }
5936
5937 /*
5938  * asc_prt_asc_board_info()
5939  *
5940  * Print dynamic board configuration information.
5941  *
5942  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
5943  * cf. asc_prt_line().
5944  *
5945  * Return the number of characters copied into 'cp'. No more than
5946  * 'cplen' characters will be copied to 'cp'.
5947  */
5948 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
5949 {
5950         asc_board_t *boardp;
5951         int chip_scsi_id;
5952         int leftlen;
5953         int totlen;
5954         int len;
5955         ASC_DVC_VAR *v;
5956         ASC_DVC_CFG *c;
5957         int i;
5958         int renegotiate = 0;
5959
5960         boardp = ASC_BOARDP(shost);
5961         v = &boardp->dvc_var.asc_dvc_var;
5962         c = &boardp->dvc_cfg.asc_dvc_cfg;
5963         chip_scsi_id = c->chip_scsi_id;
5964
5965         leftlen = cplen;
5966         totlen = len = 0;
5967
5968         len = asc_prt_line(cp, leftlen,
5969                            "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
5970                            shost->host_no);
5971         ASC_PRT_NEXT();
5972
5973         len = asc_prt_line(cp, leftlen,
5974                            " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
5975                            c->chip_version, c->lib_version, c->lib_serial_no,
5976                            c->mcode_date);
5977         ASC_PRT_NEXT();
5978
5979         len = asc_prt_line(cp, leftlen,
5980                            " mcode_version 0x%x, err_code %u\n",
5981                            c->mcode_version, v->err_code);
5982         ASC_PRT_NEXT();
5983
5984         /* Current number of commands waiting for the host. */
5985         len = asc_prt_line(cp, leftlen,
5986                            " Total Command Pending: %d\n", v->cur_total_qng);
5987         ASC_PRT_NEXT();
5988
5989         len = asc_prt_line(cp, leftlen, " Command Queuing:");
5990         ASC_PRT_NEXT();
5991         for (i = 0; i <= ASC_MAX_TID; i++) {
5992                 if ((chip_scsi_id == i) ||
5993                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
5994                         continue;
5995                 }
5996                 len = asc_prt_line(cp, leftlen, " %X:%c",
5997                                    i,
5998                                    (v->
5999                                     use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6000                                    'Y' : 'N');
6001                 ASC_PRT_NEXT();
6002         }
6003         len = asc_prt_line(cp, leftlen, "\n");
6004         ASC_PRT_NEXT();
6005
6006         /* Current number of commands waiting for a device. */
6007         len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6008         ASC_PRT_NEXT();
6009         for (i = 0; i <= ASC_MAX_TID; i++) {
6010                 if ((chip_scsi_id == i) ||
6011                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6012                         continue;
6013                 }
6014                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6015                 ASC_PRT_NEXT();
6016         }
6017         len = asc_prt_line(cp, leftlen, "\n");
6018         ASC_PRT_NEXT();
6019
6020         /* Current limit on number of commands that can be sent to a device. */
6021         len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6022         ASC_PRT_NEXT();
6023         for (i = 0; i <= ASC_MAX_TID; i++) {
6024                 if ((chip_scsi_id == i) ||
6025                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6026                         continue;
6027                 }
6028                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6029                 ASC_PRT_NEXT();
6030         }
6031         len = asc_prt_line(cp, leftlen, "\n");
6032         ASC_PRT_NEXT();
6033
6034         /* Indicate whether the device has returned queue full status. */
6035         len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6036         ASC_PRT_NEXT();
6037         for (i = 0; i <= ASC_MAX_TID; i++) {
6038                 if ((chip_scsi_id == i) ||
6039                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6040                         continue;
6041                 }
6042                 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6043                         len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6044                                            i, boardp->queue_full_cnt[i]);
6045                 } else {
6046                         len = asc_prt_line(cp, leftlen, " %X:N", i);
6047                 }
6048                 ASC_PRT_NEXT();
6049         }
6050         len = asc_prt_line(cp, leftlen, "\n");
6051         ASC_PRT_NEXT();
6052
6053         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6054         ASC_PRT_NEXT();
6055         for (i = 0; i <= ASC_MAX_TID; i++) {
6056                 if ((chip_scsi_id == i) ||
6057                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6058                         continue;
6059                 }
6060                 len = asc_prt_line(cp, leftlen, " %X:%c",
6061                                    i,
6062                                    (v->
6063                                     sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6064                                    'N');
6065                 ASC_PRT_NEXT();
6066         }
6067         len = asc_prt_line(cp, leftlen, "\n");
6068         ASC_PRT_NEXT();
6069
6070         for (i = 0; i <= ASC_MAX_TID; i++) {
6071                 uchar syn_period_ix;
6072
6073                 if ((chip_scsi_id == i) ||
6074                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6075                     ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6076                         continue;
6077                 }
6078
6079                 len = asc_prt_line(cp, leftlen, "  %X:", i);
6080                 ASC_PRT_NEXT();
6081
6082                 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6083                         len = asc_prt_line(cp, leftlen, " Asynchronous");
6084                         ASC_PRT_NEXT();
6085                 } else {
6086                         syn_period_ix =
6087                             (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6088                                                            1);
6089
6090                         len = asc_prt_line(cp, leftlen,
6091                                            " Transfer Period Factor: %d (%d.%d Mhz),",
6092                                            v->sdtr_period_tbl[syn_period_ix],
6093                                            250 /
6094                                            v->sdtr_period_tbl[syn_period_ix],
6095                                            ASC_TENTHS(250,
6096                                                       v->
6097                                                       sdtr_period_tbl
6098                                                       [syn_period_ix]));
6099                         ASC_PRT_NEXT();
6100
6101                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6102                                            boardp->
6103                                            sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6104                         ASC_PRT_NEXT();
6105                 }
6106
6107                 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6108                         len = asc_prt_line(cp, leftlen, "*\n");
6109                         renegotiate = 1;
6110                 } else {
6111                         len = asc_prt_line(cp, leftlen, "\n");
6112                 }
6113                 ASC_PRT_NEXT();
6114         }
6115
6116         if (renegotiate) {
6117                 len = asc_prt_line(cp, leftlen,
6118                                    " * = Re-negotiation pending before next command.\n");
6119                 ASC_PRT_NEXT();
6120         }
6121
6122         return totlen;
6123 }
6124
6125 /*
6126  * asc_prt_adv_board_info()
6127  *
6128  * Print dynamic board configuration information.
6129  *
6130  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6131  * cf. asc_prt_line().
6132  *
6133  * Return the number of characters copied into 'cp'. No more than
6134  * 'cplen' characters will be copied to 'cp'.
6135  */
6136 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6137 {
6138         asc_board_t *boardp;
6139         int leftlen;
6140         int totlen;
6141         int len;
6142         int i;
6143         ADV_DVC_VAR *v;
6144         ADV_DVC_CFG *c;
6145         AdvPortAddr iop_base;
6146         ushort chip_scsi_id;
6147         ushort lramword;
6148         uchar lrambyte;
6149         ushort tagqng_able;
6150         ushort sdtr_able, wdtr_able;
6151         ushort wdtr_done, sdtr_done;
6152         ushort period = 0;
6153         int renegotiate = 0;
6154
6155         boardp = ASC_BOARDP(shost);
6156         v = &boardp->dvc_var.adv_dvc_var;
6157         c = &boardp->dvc_cfg.adv_dvc_cfg;
6158         iop_base = v->iop_base;
6159         chip_scsi_id = v->chip_scsi_id;
6160
6161         leftlen = cplen;
6162         totlen = len = 0;
6163
6164         len = asc_prt_line(cp, leftlen,
6165                            "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6166                            shost->host_no);
6167         ASC_PRT_NEXT();
6168
6169         len = asc_prt_line(cp, leftlen,
6170                            " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6171                            v->iop_base,
6172                            AdvReadWordRegister(iop_base,
6173                                                IOPW_SCSI_CFG1) & CABLE_DETECT,
6174                            v->err_code);
6175         ASC_PRT_NEXT();
6176
6177         len = asc_prt_line(cp, leftlen,
6178                            " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6179                            c->chip_version, c->lib_version, c->mcode_date,
6180                            c->mcode_version);
6181         ASC_PRT_NEXT();
6182
6183         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6184         len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6185         ASC_PRT_NEXT();
6186         for (i = 0; i <= ADV_MAX_TID; i++) {
6187                 if ((chip_scsi_id == i) ||
6188                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6189                         continue;
6190                 }
6191
6192                 len = asc_prt_line(cp, leftlen, " %X:%c",
6193                                    i,
6194                                    (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6195                                    'N');
6196                 ASC_PRT_NEXT();
6197         }
6198         len = asc_prt_line(cp, leftlen, "\n");
6199         ASC_PRT_NEXT();
6200
6201         len = asc_prt_line(cp, leftlen, " Queue Limit:");
6202         ASC_PRT_NEXT();
6203         for (i = 0; i <= ADV_MAX_TID; i++) {
6204                 if ((chip_scsi_id == i) ||
6205                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6206                         continue;
6207                 }
6208
6209                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
6210                                 lrambyte);
6211
6212                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6213                 ASC_PRT_NEXT();
6214         }
6215         len = asc_prt_line(cp, leftlen, "\n");
6216         ASC_PRT_NEXT();
6217
6218         len = asc_prt_line(cp, leftlen, " Command Pending:");
6219         ASC_PRT_NEXT();
6220         for (i = 0; i <= ADV_MAX_TID; i++) {
6221                 if ((chip_scsi_id == i) ||
6222                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6223                         continue;
6224                 }
6225
6226                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
6227                                 lrambyte);
6228
6229                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
6230                 ASC_PRT_NEXT();
6231         }
6232         len = asc_prt_line(cp, leftlen, "\n");
6233         ASC_PRT_NEXT();
6234
6235         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6236         len = asc_prt_line(cp, leftlen, " Wide Enabled:");
6237         ASC_PRT_NEXT();
6238         for (i = 0; i <= ADV_MAX_TID; i++) {
6239                 if ((chip_scsi_id == i) ||
6240                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6241                         continue;
6242                 }
6243
6244                 len = asc_prt_line(cp, leftlen, " %X:%c",
6245                                    i,
6246                                    (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6247                                    'N');
6248                 ASC_PRT_NEXT();
6249         }
6250         len = asc_prt_line(cp, leftlen, "\n");
6251         ASC_PRT_NEXT();
6252
6253         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
6254         len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
6255         ASC_PRT_NEXT();
6256         for (i = 0; i <= ADV_MAX_TID; i++) {
6257                 if ((chip_scsi_id == i) ||
6258                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6259                         continue;
6260                 }
6261
6262                 AdvReadWordLram(iop_base,
6263                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
6264                                 lramword);
6265
6266                 len = asc_prt_line(cp, leftlen, " %X:%d",
6267                                    i, (lramword & 0x8000) ? 16 : 8);
6268                 ASC_PRT_NEXT();
6269
6270                 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
6271                     (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6272                         len = asc_prt_line(cp, leftlen, "*");
6273                         ASC_PRT_NEXT();
6274                         renegotiate = 1;
6275                 }
6276         }
6277         len = asc_prt_line(cp, leftlen, "\n");
6278         ASC_PRT_NEXT();
6279
6280         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6281         len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
6282         ASC_PRT_NEXT();
6283         for (i = 0; i <= ADV_MAX_TID; i++) {
6284                 if ((chip_scsi_id == i) ||
6285                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6286                         continue;
6287                 }
6288
6289                 len = asc_prt_line(cp, leftlen, " %X:%c",
6290                                    i,
6291                                    (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6292                                    'N');
6293                 ASC_PRT_NEXT();
6294         }
6295         len = asc_prt_line(cp, leftlen, "\n");
6296         ASC_PRT_NEXT();
6297
6298         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
6299         for (i = 0; i <= ADV_MAX_TID; i++) {
6300
6301                 AdvReadWordLram(iop_base,
6302                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
6303                                 lramword);
6304                 lramword &= ~0x8000;
6305
6306                 if ((chip_scsi_id == i) ||
6307                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6308                     ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
6309                         continue;
6310                 }
6311
6312                 len = asc_prt_line(cp, leftlen, "  %X:", i);
6313                 ASC_PRT_NEXT();
6314
6315                 if ((lramword & 0x1F) == 0) {   /* Check for REQ/ACK Offset 0. */
6316                         len = asc_prt_line(cp, leftlen, " Asynchronous");
6317                         ASC_PRT_NEXT();
6318                 } else {
6319                         len =
6320                             asc_prt_line(cp, leftlen,
6321                                          " Transfer Period Factor: ");
6322                         ASC_PRT_NEXT();
6323
6324                         if ((lramword & 0x1F00) == 0x1100) {    /* 80 Mhz */
6325                                 len =
6326                                     asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
6327                                 ASC_PRT_NEXT();
6328                         } else if ((lramword & 0x1F00) == 0x1000) {     /* 40 Mhz */
6329                                 len =
6330                                     asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
6331                                 ASC_PRT_NEXT();
6332                         } else {        /* 20 Mhz or below. */
6333
6334                                 period = (((lramword >> 8) * 25) + 50) / 4;
6335
6336                                 if (period == 0) {      /* Should never happen. */
6337                                         len =
6338                                             asc_prt_line(cp, leftlen,
6339                                                          "%d (? Mhz), ");
6340                                         ASC_PRT_NEXT();
6341                                 } else {
6342                                         len = asc_prt_line(cp, leftlen,
6343                                                            "%d (%d.%d Mhz),",
6344                                                            period, 250 / period,
6345                                                            ASC_TENTHS(250,
6346                                                                       period));
6347                                         ASC_PRT_NEXT();
6348                                 }
6349                         }
6350
6351                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6352                                            lramword & 0x1F);
6353                         ASC_PRT_NEXT();
6354                 }
6355
6356                 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6357                         len = asc_prt_line(cp, leftlen, "*\n");
6358                         renegotiate = 1;
6359                 } else {
6360                         len = asc_prt_line(cp, leftlen, "\n");
6361                 }
6362                 ASC_PRT_NEXT();
6363         }
6364
6365         if (renegotiate) {
6366                 len = asc_prt_line(cp, leftlen,
6367                                    " * = Re-negotiation pending before next command.\n");
6368                 ASC_PRT_NEXT();
6369         }
6370
6371         return totlen;
6372 }
6373
6374 /*
6375  * asc_proc_copy()
6376  *
6377  * Copy proc information to a read buffer taking into account the current
6378  * read offset in the file and the remaining space in the read buffer.
6379  */
6380 static int
6381 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
6382               char *cp, int cplen)
6383 {
6384         int cnt = 0;
6385
6386         ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
6387                  (unsigned)offset, (unsigned)advoffset, cplen);
6388         if (offset <= advoffset) {
6389                 /* Read offset below current offset, copy everything. */
6390                 cnt = min(cplen, leftlen);
6391                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
6392                          (ulong)curbuf, (ulong)cp, cnt);
6393                 memcpy(curbuf, cp, cnt);
6394         } else if (offset < advoffset + cplen) {
6395                 /* Read offset within current range, partial copy. */
6396                 cnt = (advoffset + cplen) - offset;
6397                 cp = (cp + cplen) - cnt;
6398                 cnt = min(cnt, leftlen);
6399                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
6400                          (ulong)curbuf, (ulong)cp, cnt);
6401                 memcpy(curbuf, cp, cnt);
6402         }
6403         return cnt;
6404 }
6405
6406 /*
6407  * asc_prt_line()
6408  *
6409  * If 'cp' is NULL print to the console, otherwise print to a buffer.
6410  *
6411  * Return 0 if printing to the console, otherwise return the number of
6412  * bytes written to the buffer.
6413  *
6414  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
6415  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
6416  */
6417 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
6418 {
6419         va_list args;
6420         int ret;
6421         char s[ASC_PRTLINE_SIZE];
6422
6423         va_start(args, fmt);
6424         ret = vsprintf(s, fmt, args);
6425         ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
6426         if (buf == NULL) {
6427                 (void)printk(s);
6428                 ret = 0;
6429         } else {
6430                 ret = min(buflen, ret);
6431                 memcpy(buf, s, ret);
6432         }
6433         va_end(args);
6434         return ret;
6435 }
6436 #endif /* CONFIG_PROC_FS */
6437
6438 /*
6439  * --- Functions Required by the Asc Library
6440  */
6441
6442 /*
6443  * Delay for 'n' milliseconds. Don't use the 'jiffies'
6444  * global variable which is incremented once every 5 ms
6445  * from a timer interrupt, because this function may be
6446  * called when interrupts are disabled.
6447  */
6448 static void DvcSleepMilliSecond(ADV_DCNT n)
6449 {
6450         ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
6451         mdelay(n);
6452 }
6453
6454 /*
6455  * Currently and inline noop but leave as a placeholder.
6456  * Leave DvcEnterCritical() as a noop placeholder.
6457  */
6458 static inline ulong DvcEnterCritical(void)
6459 {
6460         return 0;
6461 }
6462
6463 /*
6464  * Critical sections are all protected by the board spinlock.
6465  * Leave DvcLeaveCritical() as a noop placeholder.
6466  */
6467 static inline void DvcLeaveCritical(ulong flags)
6468 {
6469         return;
6470 }
6471
6472 /*
6473  * void
6474  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
6475  *
6476  * Calling/Exit State:
6477  *    none
6478  *
6479  * Description:
6480  *     Output an ASC_SCSI_Q structure to the chip
6481  */
6482 static void
6483 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
6484 {
6485         int i;
6486
6487         ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
6488         AscSetChipLramAddr(iop_base, s_addr);
6489         for (i = 0; i < 2 * words; i += 2) {
6490                 if (i == 4 || i == 20) {
6491                         continue;
6492                 }
6493                 outpw(iop_base + IOP_RAM_DATA,
6494                       ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
6495         }
6496 }
6497
6498 /*
6499  * void
6500  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
6501  *
6502  * Calling/Exit State:
6503  *    none
6504  *
6505  * Description:
6506  *     Input an ASC_QDONE_INFO structure from the chip
6507  */
6508 static void
6509 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
6510 {
6511         int i;
6512         ushort word;
6513
6514         AscSetChipLramAddr(iop_base, s_addr);
6515         for (i = 0; i < 2 * words; i += 2) {
6516                 if (i == 10) {
6517                         continue;
6518                 }
6519                 word = inpw(iop_base + IOP_RAM_DATA);
6520                 inbuf[i] = word & 0xff;
6521                 inbuf[i + 1] = (word >> 8) & 0xff;
6522         }
6523         ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
6524 }
6525
6526 /*
6527  * Return the BIOS address of the adapter at the specified
6528  * I/O port and with the specified bus type.
6529  */
6530 static unsigned short __devinit
6531 AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
6532 {
6533         unsigned short cfg_lsw;
6534         unsigned short bios_addr;
6535
6536         /*
6537          * The PCI BIOS is re-located by the motherboard BIOS. Because
6538          * of this the driver can not determine where a PCI BIOS is
6539          * loaded and executes.
6540          */
6541         if (bus_type & ASC_IS_PCI)
6542                 return 0;
6543
6544 #ifdef CONFIG_ISA
6545         if ((bus_type & ASC_IS_EISA) != 0) {
6546                 cfg_lsw = AscGetEisaChipCfg(iop_base);
6547                 cfg_lsw &= 0x000F;
6548                 bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
6549                 return bios_addr;
6550         }
6551 #endif /* CONFIG_ISA */
6552
6553         cfg_lsw = AscGetChipCfgLsw(iop_base);
6554
6555         /*
6556          *  ISA PnP uses the top bit as the 32K BIOS flag
6557          */
6558         if (bus_type == ASC_IS_ISAPNP)
6559                 cfg_lsw &= 0x7FFF;
6560         bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
6561         return bios_addr;
6562 }
6563
6564 /*
6565  * --- Functions Required by the Adv Library
6566  */
6567
6568 /*
6569  * DvcGetPhyAddr()
6570  *
6571  * Return the physical address of 'vaddr' and set '*lenp' to the
6572  * number of physically contiguous bytes that follow 'vaddr'.
6573  * 'flag' indicates the type of structure whose physical address
6574  * is being translated.
6575  *
6576  * Note: Because Linux currently doesn't page the kernel and all
6577  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
6578  */
6579 ADV_PADDR
6580 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
6581               uchar *vaddr, ADV_SDCNT *lenp, int flag)
6582 {
6583         ADV_PADDR paddr;
6584
6585         paddr = virt_to_bus(vaddr);
6586
6587         ASC_DBG4(4,
6588                  "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
6589                  (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
6590                  (ulong)paddr);
6591
6592         return paddr;
6593 }
6594
6595 /*
6596  * --- Tracing and Debugging Functions
6597  */
6598
6599 #ifdef ADVANSYS_STATS
6600 #ifdef CONFIG_PROC_FS
6601 /*
6602  * asc_prt_board_stats()
6603  *
6604  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6605  * cf. asc_prt_line().
6606  *
6607  * Return the number of characters copied into 'cp'. No more than
6608  * 'cplen' characters will be copied to 'cp'.
6609  */
6610 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
6611 {
6612         int leftlen;
6613         int totlen;
6614         int len;
6615         struct asc_stats *s;
6616         asc_board_t *boardp;
6617
6618         leftlen = cplen;
6619         totlen = len = 0;
6620
6621         boardp = ASC_BOARDP(shost);
6622         s = &boardp->asc_stats;
6623
6624         len = asc_prt_line(cp, leftlen,
6625                            "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
6626                            shost->host_no);
6627         ASC_PRT_NEXT();
6628
6629         len = asc_prt_line(cp, leftlen,
6630                            " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
6631                            s->queuecommand, s->reset, s->biosparam,
6632                            s->interrupt);
6633         ASC_PRT_NEXT();
6634
6635         len = asc_prt_line(cp, leftlen,
6636                            " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
6637                            s->callback, s->done, s->build_error,
6638                            s->adv_build_noreq, s->adv_build_nosg);
6639         ASC_PRT_NEXT();
6640
6641         len = asc_prt_line(cp, leftlen,
6642                            " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
6643                            s->exe_noerror, s->exe_busy, s->exe_error,
6644                            s->exe_unknown);
6645         ASC_PRT_NEXT();
6646
6647         /*
6648          * Display data transfer statistics.
6649          */
6650         if (s->cont_cnt > 0) {
6651                 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
6652                 ASC_PRT_NEXT();
6653
6654                 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
6655                                    s->cont_xfer / 2,
6656                                    ASC_TENTHS(s->cont_xfer, 2));
6657                 ASC_PRT_NEXT();
6658
6659                 /* Contiguous transfer average size */
6660                 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
6661                                    (s->cont_xfer / 2) / s->cont_cnt,
6662                                    ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
6663                 ASC_PRT_NEXT();
6664         }
6665
6666         if (s->sg_cnt > 0) {
6667
6668                 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
6669                                    s->sg_cnt, s->sg_elem);
6670                 ASC_PRT_NEXT();
6671
6672                 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
6673                                    s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
6674                 ASC_PRT_NEXT();
6675
6676                 /* Scatter gather transfer statistics */
6677                 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
6678                                    s->sg_elem / s->sg_cnt,
6679                                    ASC_TENTHS(s->sg_elem, s->sg_cnt));
6680                 ASC_PRT_NEXT();
6681
6682                 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
6683                                    (s->sg_xfer / 2) / s->sg_elem,
6684                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
6685                 ASC_PRT_NEXT();
6686
6687                 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
6688                                    (s->sg_xfer / 2) / s->sg_cnt,
6689                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
6690                 ASC_PRT_NEXT();
6691         }
6692
6693         /*
6694          * Display request queuing statistics.
6695          */
6696         len = asc_prt_line(cp, leftlen,
6697                            " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
6698                            HZ);
6699         ASC_PRT_NEXT();
6700
6701         return totlen;
6702 }
6703
6704 /*
6705  * asc_prt_target_stats()
6706  *
6707  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6708  * cf. asc_prt_line().
6709  *
6710  * This is separated from asc_prt_board_stats because a full set
6711  * of targets will overflow ASC_PRTBUF_SIZE.
6712  *
6713  * Return the number of characters copied into 'cp'. No more than
6714  * 'cplen' characters will be copied to 'cp'.
6715  */
6716 static int
6717 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
6718 {
6719         int leftlen;
6720         int totlen;
6721         int len;
6722         struct asc_stats *s;
6723         ushort chip_scsi_id;
6724         asc_board_t *boardp;
6725         asc_queue_t *active;
6726         asc_queue_t *waiting;
6727
6728         leftlen = cplen;
6729         totlen = len = 0;
6730
6731         boardp = ASC_BOARDP(shost);
6732         s = &boardp->asc_stats;
6733
6734         active = &ASC_BOARDP(shost)->active;
6735         waiting = &ASC_BOARDP(shost)->waiting;
6736
6737         if (ASC_NARROW_BOARD(boardp)) {
6738                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6739         } else {
6740                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6741         }
6742
6743         if ((chip_scsi_id == tgt_id) ||
6744             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
6745                 return 0;
6746         }
6747
6748         do {
6749                 if (active->q_tot_cnt[tgt_id] > 0
6750                     || waiting->q_tot_cnt[tgt_id] > 0) {
6751                         len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
6752                         ASC_PRT_NEXT();
6753
6754                         len = asc_prt_line(cp, leftlen,
6755                                            "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
6756                                            active->q_cur_cnt[tgt_id],
6757                                            active->q_max_cnt[tgt_id],
6758                                            active->q_tot_cnt[tgt_id],
6759                                            active->q_min_tim[tgt_id],
6760                                            active->q_max_tim[tgt_id],
6761                                            (active->q_tot_cnt[tgt_id] ==
6762                                             0) ? 0 : (active->
6763                                                       q_tot_tim[tgt_id] /
6764                                                       active->
6765                                                       q_tot_cnt[tgt_id]),
6766                                            (active->q_tot_cnt[tgt_id] ==
6767                                             0) ? 0 : ASC_TENTHS(active->
6768                                                                 q_tot_tim
6769                                                                 [tgt_id],
6770                                                                 active->
6771                                                                 q_tot_cnt
6772                                                                 [tgt_id]));
6773                         ASC_PRT_NEXT();
6774
6775                         len = asc_prt_line(cp, leftlen,
6776                                            "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
6777                                            waiting->q_cur_cnt[tgt_id],
6778                                            waiting->q_max_cnt[tgt_id],
6779                                            waiting->q_tot_cnt[tgt_id],
6780                                            waiting->q_min_tim[tgt_id],
6781                                            waiting->q_max_tim[tgt_id],
6782                                            (waiting->q_tot_cnt[tgt_id] ==
6783                                             0) ? 0 : (waiting->
6784                                                       q_tot_tim[tgt_id] /
6785                                                       waiting->
6786                                                       q_tot_cnt[tgt_id]),
6787                                            (waiting->q_tot_cnt[tgt_id] ==
6788                                             0) ? 0 : ASC_TENTHS(waiting->
6789                                                                 q_tot_tim
6790                                                                 [tgt_id],
6791                                                                 waiting->
6792                                                                 q_tot_cnt
6793                                                                 [tgt_id]));
6794                         ASC_PRT_NEXT();
6795                 }
6796         } while (0);
6797
6798         return totlen;
6799 }
6800 #endif /* CONFIG_PROC_FS */
6801 #endif /* ADVANSYS_STATS */
6802
6803 #ifdef ADVANSYS_DEBUG
6804 /*
6805  * asc_prt_scsi_host()
6806  */
6807 static void asc_prt_scsi_host(struct Scsi_Host *s)
6808 {
6809         asc_board_t *boardp;
6810
6811         boardp = ASC_BOARDP(s);
6812
6813         printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
6814         printk(" host_busy %u, host_no %d, last_reset %d,\n",
6815                s->host_busy, s->host_no, (unsigned)s->last_reset);
6816
6817         printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
6818                (ulong)s->base, (ulong)s->io_port, s->irq);
6819
6820         printk(" dma_channel %d, this_id %d, can_queue %d,\n",
6821                s->dma_channel, s->this_id, s->can_queue);
6822
6823         printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
6824                s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
6825
6826         if (ASC_NARROW_BOARD(boardp)) {
6827                 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
6828                 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
6829         } else {
6830                 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
6831                 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
6832         }
6833 }
6834
6835 /*
6836  * asc_prt_scsi_cmnd()
6837  */
6838 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
6839 {
6840         printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
6841
6842         printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
6843                (ulong)s->device->host, (ulong)s->device, s->device->id,
6844                s->device->lun, s->device->channel);
6845
6846         asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
6847
6848         printk("sc_data_direction %u, resid %d\n",
6849                s->sc_data_direction, s->resid);
6850
6851         printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
6852
6853         printk(" serial_number 0x%x, retries %d, allowed %d\n",
6854                (unsigned)s->serial_number, s->retries, s->allowed);
6855
6856         printk(" timeout_per_command %d\n", s->timeout_per_command);
6857
6858         printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
6859                 s->scsi_done, s->done, s->host_scribble, s->result);
6860
6861         printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
6862 }
6863
6864 /*
6865  * asc_prt_asc_dvc_var()
6866  */
6867 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
6868 {
6869         printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
6870
6871         printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
6872                "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
6873
6874         printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
6875                 (unsigned)h->init_sdtr);
6876
6877         printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
6878                "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
6879                (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
6880                (unsigned)h->chip_no);
6881
6882         printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
6883                "%u,\n", (unsigned)h->queue_full_or_busy,
6884                (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
6885
6886         printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
6887                "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
6888                (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
6889                (unsigned)h->in_critical_cnt);
6890
6891         printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
6892                "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
6893                (unsigned)h->init_state, (unsigned)h->no_scam,
6894                (unsigned)h->pci_fix_asyn_xfer);
6895
6896         printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
6897 }
6898
6899 /*
6900  * asc_prt_asc_dvc_cfg()
6901  */
6902 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
6903 {
6904         printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
6905
6906         printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
6907                h->can_tagged_qng, h->cmd_qng_enabled);
6908         printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
6909                h->disc_enable, h->sdtr_enable);
6910
6911         printk
6912             (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
6913              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
6914              h->chip_version);
6915
6916         printk
6917             (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
6918              to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
6919              h->mcode_date);
6920
6921         printk(" mcode_version %d, overrun_buf 0x%lx\n",
6922                h->mcode_version, (ulong)h->overrun_buf);
6923 }
6924
6925 /*
6926  * asc_prt_asc_scsi_q()
6927  */
6928 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
6929 {
6930         ASC_SG_HEAD *sgp;
6931         int i;
6932
6933         printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
6934
6935         printk
6936             (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
6937              q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
6938              q->q2.tag_code);
6939
6940         printk
6941             (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
6942              (ulong)le32_to_cpu(q->q1.data_addr),
6943              (ulong)le32_to_cpu(q->q1.data_cnt),
6944              (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
6945
6946         printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
6947                (ulong)q->cdbptr, q->q2.cdb_len,
6948                (ulong)q->sg_head, q->q1.sg_queue_cnt);
6949
6950         if (q->sg_head) {
6951                 sgp = q->sg_head;
6952                 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
6953                 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
6954                        sgp->queue_cnt);
6955                 for (i = 0; i < sgp->entry_cnt; i++) {
6956                         printk(" [%u]: addr 0x%lx, bytes %lu\n",
6957                                i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
6958                                (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
6959                 }
6960
6961         }
6962 }
6963
6964 /*
6965  * asc_prt_asc_qdone_info()
6966  */
6967 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
6968 {
6969         printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
6970         printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
6971                (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
6972                q->d2.tag_code);
6973         printk
6974             (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
6975              q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
6976 }
6977
6978 /*
6979  * asc_prt_adv_dvc_var()
6980  *
6981  * Display an ADV_DVC_VAR structure.
6982  */
6983 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
6984 {
6985         printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
6986
6987         printk("  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
6988                (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
6989
6990         printk("  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
6991                (ulong)h->isr_callback, (unsigned)h->sdtr_able,
6992                (unsigned)h->wdtr_able);
6993
6994         printk("  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
6995                (unsigned)h->start_motor,
6996                (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
6997
6998         printk("  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
6999                (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7000                (ulong)h->carr_freelist);
7001
7002         printk("  icq_sp 0x%lx, irq_sp 0x%lx\n",
7003                (ulong)h->icq_sp, (ulong)h->irq_sp);
7004
7005         printk("  no_scam 0x%x, tagqng_able 0x%x\n",
7006                (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7007
7008         printk("  chip_scsi_id 0x%x, cfg 0x%lx\n",
7009                (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7010 }
7011
7012 /*
7013  * asc_prt_adv_dvc_cfg()
7014  *
7015  * Display an ADV_DVC_CFG structure.
7016  */
7017 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7018 {
7019         printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7020
7021         printk("  disc_enable 0x%x, termination 0x%x\n",
7022                h->disc_enable, h->termination);
7023
7024         printk("  chip_version 0x%x, mcode_date 0x%x\n",
7025                h->chip_version, h->mcode_date);
7026
7027         printk("  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7028                h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7029
7030         printk("  control_flag 0x%x\n", h->control_flag);
7031 }
7032
7033 /*
7034  * asc_prt_adv_scsi_req_q()
7035  *
7036  * Display an ADV_SCSI_REQ_Q structure.
7037  */
7038 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7039 {
7040         int sg_blk_cnt;
7041         struct asc_sg_block *sg_ptr;
7042
7043         printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7044
7045         printk("  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7046                q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7047
7048         printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7049                q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7050
7051         printk("  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7052                (ulong)le32_to_cpu(q->data_cnt),
7053                (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7054
7055         printk
7056             ("  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7057              q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7058
7059         printk("  sg_working_ix 0x%x, target_cmd %u\n",
7060                q->sg_working_ix, q->target_cmd);
7061
7062         printk("  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7063                (ulong)le32_to_cpu(q->scsiq_rptr),
7064                (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7065
7066         /* Display the request's ADV_SG_BLOCK structures. */
7067         if (q->sg_list_ptr != NULL) {
7068                 sg_blk_cnt = 0;
7069                 while (1) {
7070                         /*
7071                          * 'sg_ptr' is a physical address. Convert it to a virtual
7072                          * address by indexing 'sg_blk_cnt' into the virtual address
7073                          * array 'sg_list_ptr'.
7074                          *
7075                          * XXX - Assumes all SG physical blocks are virtually contiguous.
7076                          */
7077                         sg_ptr =
7078                             &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7079                         asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7080                         if (sg_ptr->sg_ptr == 0) {
7081                                 break;
7082                         }
7083                         sg_blk_cnt++;
7084                 }
7085         }
7086 }
7087
7088 /*
7089  * asc_prt_adv_sgblock()
7090  *
7091  * Display an ADV_SG_BLOCK structure.
7092  */
7093 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7094 {
7095         int i;
7096
7097         printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7098                (ulong)b, sgblockno);
7099         printk("  sg_cnt %u, sg_ptr 0x%lx\n",
7100                b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7101         ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7102         if (b->sg_ptr != 0) {
7103                 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7104         }
7105         for (i = 0; i < b->sg_cnt; i++) {
7106                 printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7107                        i, (ulong)b->sg_list[i].sg_addr,
7108                        (ulong)b->sg_list[i].sg_count);
7109         }
7110 }
7111
7112 /*
7113  * asc_prt_hex()
7114  *
7115  * Print hexadecimal output in 4 byte groupings 32 bytes
7116  * or 8 double-words per line.
7117  */
7118 static void asc_prt_hex(char *f, uchar *s, int l)
7119 {
7120         int i;
7121         int j;
7122         int k;
7123         int m;
7124
7125         printk("%s: (%d bytes)\n", f, l);
7126
7127         for (i = 0; i < l; i += 32) {
7128
7129                 /* Display a maximum of 8 double-words per line. */
7130                 if ((k = (l - i) / 4) >= 8) {
7131                         k = 8;
7132                         m = 0;
7133                 } else {
7134                         m = (l - i) % 4;
7135                 }
7136
7137                 for (j = 0; j < k; j++) {
7138                         printk(" %2.2X%2.2X%2.2X%2.2X",
7139                                (unsigned)s[i + (j * 4)],
7140                                (unsigned)s[i + (j * 4) + 1],
7141                                (unsigned)s[i + (j * 4) + 2],
7142                                (unsigned)s[i + (j * 4) + 3]);
7143                 }
7144
7145                 switch (m) {
7146                 case 0:
7147                 default:
7148                         break;
7149                 case 1:
7150                         printk(" %2.2X", (unsigned)s[i + (j * 4)]);
7151                         break;
7152                 case 2:
7153                         printk(" %2.2X%2.2X",
7154                                (unsigned)s[i + (j * 4)],
7155                                (unsigned)s[i + (j * 4) + 1]);
7156                         break;
7157                 case 3:
7158                         printk(" %2.2X%2.2X%2.2X",
7159                                (unsigned)s[i + (j * 4) + 1],
7160                                (unsigned)s[i + (j * 4) + 2],
7161                                (unsigned)s[i + (j * 4) + 3]);
7162                         break;
7163                 }
7164
7165                 printk("\n");
7166         }
7167 }
7168 #endif /* ADVANSYS_DEBUG */
7169
7170 /*
7171  * --- Asc Library Functions
7172  */
7173
7174 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
7175 {
7176         PortAddr eisa_cfg_iop;
7177
7178         eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7179             (PortAddr) (ASC_EISA_CFG_IOP_MASK);
7180         return (inpw(eisa_cfg_iop));
7181 }
7182
7183 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
7184 {
7185         ushort cfg_lsw;
7186
7187         if (AscGetChipScsiID(iop_base) == new_host_id) {
7188                 return (new_host_id);
7189         }
7190         cfg_lsw = AscGetChipCfgLsw(iop_base);
7191         cfg_lsw &= 0xF8FF;
7192         cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
7193         AscSetChipCfgLsw(iop_base, cfg_lsw);
7194         return (AscGetChipScsiID(iop_base));
7195 }
7196
7197 static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
7198 {
7199         unsigned char sc;
7200
7201         AscSetBank(iop_base, 1);
7202         sc = inp(iop_base + IOP_REG_SC);
7203         AscSetBank(iop_base, 0);
7204         return sc;
7205 }
7206
7207 static unsigned char __devinit
7208 AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
7209 {
7210         if (bus_type & ASC_IS_EISA) {
7211                 PortAddr eisa_iop;
7212                 unsigned char revision;
7213                 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
7214                     (PortAddr) ASC_EISA_REV_IOP_MASK;
7215                 revision = inp(eisa_iop);
7216                 return ASC_CHIP_MIN_VER_EISA - 1 + revision;
7217         }
7218         return AscGetChipVerNo(iop_base);
7219 }
7220
7221 static ASC_DCNT
7222 AscLoadMicroCode(PortAddr iop_base,
7223                  ushort s_addr, uchar *mcode_buf, ushort mcode_size)
7224 {
7225         ASC_DCNT chksum;
7226         ushort mcode_word_size;
7227         ushort mcode_chksum;
7228
7229         /* Write the microcode buffer starting at LRAM address 0. */
7230         mcode_word_size = (ushort)(mcode_size >> 1);
7231         AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
7232         AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
7233
7234         chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
7235         ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
7236         mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
7237                                                  (ushort)ASC_CODE_SEC_BEG,
7238                                                  (ushort)((mcode_size -
7239                                                            s_addr - (ushort)
7240                                                            ASC_CODE_SEC_BEG) /
7241                                                           2));
7242         ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
7243                  (ulong)mcode_chksum);
7244         AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
7245         AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
7246         return (chksum);
7247 }
7248
7249 static int AscFindSignature(PortAddr iop_base)
7250 {
7251         ushort sig_word;
7252
7253         ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
7254                  iop_base, AscGetChipSignatureByte(iop_base));
7255         if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
7256                 ASC_DBG2(1,
7257                          "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
7258                          iop_base, AscGetChipSignatureWord(iop_base));
7259                 sig_word = AscGetChipSignatureWord(iop_base);
7260                 if ((sig_word == (ushort)ASC_1000_ID0W) ||
7261                     (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
7262                         return (1);
7263                 }
7264         }
7265         return (0);
7266 }
7267
7268 static void __devinit AscToggleIRQAct(PortAddr iop_base)
7269 {
7270         AscSetChipStatus(iop_base, CIW_IRQ_ACT);
7271         AscSetChipStatus(iop_base, 0);
7272         return;
7273 }
7274
7275 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
7276 {
7277         ushort cfg_lsw;
7278         uchar chip_irq;
7279
7280         if ((bus_type & ASC_IS_EISA) != 0) {
7281                 cfg_lsw = AscGetEisaChipCfg(iop_base);
7282                 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
7283                 if ((chip_irq == 13) || (chip_irq > 15)) {
7284                         return (0);
7285                 }
7286                 return (chip_irq);
7287         }
7288         if ((bus_type & ASC_IS_VL) != 0) {
7289                 cfg_lsw = AscGetChipCfgLsw(iop_base);
7290                 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
7291                 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
7292                         return (0);
7293                 }
7294                 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
7295         }
7296         cfg_lsw = AscGetChipCfgLsw(iop_base);
7297         chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
7298         if (chip_irq == 3)
7299                 chip_irq += (uchar)2;
7300         return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
7301 }
7302
7303 static uchar __devinit
7304 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
7305 {
7306         ushort cfg_lsw;
7307
7308         if ((bus_type & ASC_IS_VL) != 0) {
7309                 if (irq_no != 0) {
7310                         if ((irq_no < ASC_MIN_IRQ_NO)
7311                             || (irq_no > ASC_MAX_IRQ_NO)) {
7312                                 irq_no = 0;
7313                         } else {
7314                                 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
7315                         }
7316                 }
7317                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
7318                 cfg_lsw |= (ushort)0x0010;
7319                 AscSetChipCfgLsw(iop_base, cfg_lsw);
7320                 AscToggleIRQAct(iop_base);
7321                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
7322                 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
7323                 AscSetChipCfgLsw(iop_base, cfg_lsw);
7324                 AscToggleIRQAct(iop_base);
7325                 return (AscGetChipIRQ(iop_base, bus_type));
7326         }
7327         if ((bus_type & (ASC_IS_ISA)) != 0) {
7328                 if (irq_no == 15)
7329                         irq_no -= (uchar)2;
7330                 irq_no -= (uchar)ASC_MIN_IRQ_NO;
7331                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
7332                 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
7333                 AscSetChipCfgLsw(iop_base, cfg_lsw);
7334                 return (AscGetChipIRQ(iop_base, bus_type));
7335         }
7336         return (0);
7337 }
7338
7339 #ifdef CONFIG_ISA
7340 static void __devinit AscEnableIsaDma(uchar dma_channel)
7341 {
7342         if (dma_channel < 4) {
7343                 outp(0x000B, (ushort)(0xC0 | dma_channel));
7344                 outp(0x000A, dma_channel);
7345         } else if (dma_channel < 8) {
7346                 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
7347                 outp(0x00D4, (ushort)(dma_channel - 4));
7348         }
7349         return;
7350 }
7351 #endif /* CONFIG_ISA */
7352
7353 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
7354 {
7355         EXT_MSG ext_msg;
7356         EXT_MSG out_msg;
7357         ushort halt_q_addr;
7358         int sdtr_accept;
7359         ushort int_halt_code;
7360         ASC_SCSI_BIT_ID_TYPE scsi_busy;
7361         ASC_SCSI_BIT_ID_TYPE target_id;
7362         PortAddr iop_base;
7363         uchar tag_code;
7364         uchar q_status;
7365         uchar halt_qp;
7366         uchar sdtr_data;
7367         uchar target_ix;
7368         uchar q_cntl, tid_no;
7369         uchar cur_dvc_qng;
7370         uchar asyn_sdtr;
7371         uchar scsi_status;
7372         asc_board_t *boardp;
7373
7374         ASC_ASSERT(asc_dvc->drv_ptr != NULL);
7375         boardp = asc_dvc->drv_ptr;
7376
7377         iop_base = asc_dvc->iop_base;
7378         int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
7379
7380         halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
7381         halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
7382         target_ix = AscReadLramByte(iop_base,
7383                                     (ushort)(halt_q_addr +
7384                                              (ushort)ASC_SCSIQ_B_TARGET_IX));
7385         q_cntl =
7386             AscReadLramByte(iop_base,
7387                             (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
7388         tid_no = ASC_TIX_TO_TID(target_ix);
7389         target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
7390         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
7391                 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
7392         } else {
7393                 asyn_sdtr = 0;
7394         }
7395         if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
7396                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
7397                         AscSetChipSDTR(iop_base, 0, tid_no);
7398                         boardp->sdtr_data[tid_no] = 0;
7399                 }
7400                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7401                 return (0);
7402         } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
7403                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
7404                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
7405                         boardp->sdtr_data[tid_no] = asyn_sdtr;
7406                 }
7407                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7408                 return (0);
7409         } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
7410
7411                 AscMemWordCopyPtrFromLram(iop_base,
7412                                           ASCV_MSGIN_BEG,
7413                                           (uchar *)&ext_msg,
7414                                           sizeof(EXT_MSG) >> 1);
7415
7416                 if (ext_msg.msg_type == EXTENDED_MESSAGE &&
7417                     ext_msg.msg_req == EXTENDED_SDTR &&
7418                     ext_msg.msg_len == MS_SDTR_LEN) {
7419                         sdtr_accept = TRUE;
7420                         if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
7421
7422                                 sdtr_accept = FALSE;
7423                                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
7424                         }
7425                         if ((ext_msg.xfer_period <
7426                              asc_dvc->sdtr_period_tbl[asc_dvc->
7427                                                       host_init_sdtr_index])
7428                             || (ext_msg.xfer_period >
7429                                 asc_dvc->sdtr_period_tbl[asc_dvc->
7430                                                          max_sdtr_index])) {
7431                                 sdtr_accept = FALSE;
7432                                 ext_msg.xfer_period =
7433                                     asc_dvc->sdtr_period_tbl[asc_dvc->
7434                                                              host_init_sdtr_index];
7435                         }
7436                         if (sdtr_accept) {
7437                                 sdtr_data =
7438                                     AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
7439                                                    ext_msg.req_ack_offset);
7440                                 if ((sdtr_data == 0xFF)) {
7441
7442                                         q_cntl |= QC_MSG_OUT;
7443                                         asc_dvc->init_sdtr &= ~target_id;
7444                                         asc_dvc->sdtr_done &= ~target_id;
7445                                         AscSetChipSDTR(iop_base, asyn_sdtr,
7446                                                        tid_no);
7447                                         boardp->sdtr_data[tid_no] = asyn_sdtr;
7448                                 }
7449                         }
7450                         if (ext_msg.req_ack_offset == 0) {
7451
7452                                 q_cntl &= ~QC_MSG_OUT;
7453                                 asc_dvc->init_sdtr &= ~target_id;
7454                                 asc_dvc->sdtr_done &= ~target_id;
7455                                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
7456                         } else {
7457                                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
7458
7459                                         q_cntl &= ~QC_MSG_OUT;
7460                                         asc_dvc->sdtr_done |= target_id;
7461                                         asc_dvc->init_sdtr |= target_id;
7462                                         asc_dvc->pci_fix_asyn_xfer &=
7463                                             ~target_id;
7464                                         sdtr_data =
7465                                             AscCalSDTRData(asc_dvc,
7466                                                            ext_msg.xfer_period,
7467                                                            ext_msg.
7468                                                            req_ack_offset);
7469                                         AscSetChipSDTR(iop_base, sdtr_data,
7470                                                        tid_no);
7471                                         boardp->sdtr_data[tid_no] = sdtr_data;
7472                                 } else {
7473
7474                                         q_cntl |= QC_MSG_OUT;
7475                                         AscMsgOutSDTR(asc_dvc,
7476                                                       ext_msg.xfer_period,
7477                                                       ext_msg.req_ack_offset);
7478                                         asc_dvc->pci_fix_asyn_xfer &=
7479                                             ~target_id;
7480                                         sdtr_data =
7481                                             AscCalSDTRData(asc_dvc,
7482                                                            ext_msg.xfer_period,
7483                                                            ext_msg.
7484                                                            req_ack_offset);
7485                                         AscSetChipSDTR(iop_base, sdtr_data,
7486                                                        tid_no);
7487                                         boardp->sdtr_data[tid_no] = sdtr_data;
7488                                         asc_dvc->sdtr_done |= target_id;
7489                                         asc_dvc->init_sdtr |= target_id;
7490                                 }
7491                         }
7492
7493                         AscWriteLramByte(iop_base,
7494                                          (ushort)(halt_q_addr +
7495                                                   (ushort)ASC_SCSIQ_B_CNTL),
7496                                          q_cntl);
7497                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7498                         return (0);
7499                 } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
7500                            ext_msg.msg_req == EXTENDED_WDTR &&
7501                            ext_msg.msg_len == MS_WDTR_LEN) {
7502
7503                         ext_msg.wdtr_width = 0;
7504                         AscMemWordCopyPtrToLram(iop_base,
7505                                                 ASCV_MSGOUT_BEG,
7506                                                 (uchar *)&ext_msg,
7507                                                 sizeof(EXT_MSG) >> 1);
7508                         q_cntl |= QC_MSG_OUT;
7509                         AscWriteLramByte(iop_base,
7510                                          (ushort)(halt_q_addr +
7511                                                   (ushort)ASC_SCSIQ_B_CNTL),
7512                                          q_cntl);
7513                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7514                         return (0);
7515                 } else {
7516
7517                         ext_msg.msg_type = MESSAGE_REJECT;
7518                         AscMemWordCopyPtrToLram(iop_base,
7519                                                 ASCV_MSGOUT_BEG,
7520                                                 (uchar *)&ext_msg,
7521                                                 sizeof(EXT_MSG) >> 1);
7522                         q_cntl |= QC_MSG_OUT;
7523                         AscWriteLramByte(iop_base,
7524                                          (ushort)(halt_q_addr +
7525                                                   (ushort)ASC_SCSIQ_B_CNTL),
7526                                          q_cntl);
7527                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7528                         return (0);
7529                 }
7530         } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
7531
7532                 q_cntl |= QC_REQ_SENSE;
7533
7534                 if ((asc_dvc->init_sdtr & target_id) != 0) {
7535
7536                         asc_dvc->sdtr_done &= ~target_id;
7537
7538                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
7539                         q_cntl |= QC_MSG_OUT;
7540                         AscMsgOutSDTR(asc_dvc,
7541                                       asc_dvc->
7542                                       sdtr_period_tbl[(sdtr_data >> 4) &
7543                                                       (uchar)(asc_dvc->
7544                                                               max_sdtr_index -
7545                                                               1)],
7546                                       (uchar)(sdtr_data & (uchar)
7547                                               ASC_SYN_MAX_OFFSET));
7548                 }
7549
7550                 AscWriteLramByte(iop_base,
7551                                  (ushort)(halt_q_addr +
7552                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
7553
7554                 tag_code = AscReadLramByte(iop_base,
7555                                            (ushort)(halt_q_addr + (ushort)
7556                                                     ASC_SCSIQ_B_TAG_CODE));
7557                 tag_code &= 0xDC;
7558                 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
7559                     && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
7560                     ) {
7561
7562                         tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
7563                                      | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
7564
7565                 }
7566                 AscWriteLramByte(iop_base,
7567                                  (ushort)(halt_q_addr +
7568                                           (ushort)ASC_SCSIQ_B_TAG_CODE),
7569                                  tag_code);
7570
7571                 q_status = AscReadLramByte(iop_base,
7572                                            (ushort)(halt_q_addr + (ushort)
7573                                                     ASC_SCSIQ_B_STATUS));
7574                 q_status |= (QS_READY | QS_BUSY);
7575                 AscWriteLramByte(iop_base,
7576                                  (ushort)(halt_q_addr +
7577                                           (ushort)ASC_SCSIQ_B_STATUS),
7578                                  q_status);
7579
7580                 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
7581                 scsi_busy &= ~target_id;
7582                 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
7583
7584                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7585                 return (0);
7586         } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
7587
7588                 AscMemWordCopyPtrFromLram(iop_base,
7589                                           ASCV_MSGOUT_BEG,
7590                                           (uchar *)&out_msg,
7591                                           sizeof(EXT_MSG) >> 1);
7592
7593                 if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
7594                     (out_msg.msg_len == MS_SDTR_LEN) &&
7595                     (out_msg.msg_req == EXTENDED_SDTR)) {
7596
7597                         asc_dvc->init_sdtr &= ~target_id;
7598                         asc_dvc->sdtr_done &= ~target_id;
7599                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
7600                         boardp->sdtr_data[tid_no] = asyn_sdtr;
7601                 }
7602                 q_cntl &= ~QC_MSG_OUT;
7603                 AscWriteLramByte(iop_base,
7604                                  (ushort)(halt_q_addr +
7605                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
7606                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7607                 return (0);
7608         } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
7609
7610                 scsi_status = AscReadLramByte(iop_base,
7611                                               (ushort)((ushort)halt_q_addr +
7612                                                        (ushort)
7613                                                        ASC_SCSIQ_SCSI_STATUS));
7614                 cur_dvc_qng =
7615                     AscReadLramByte(iop_base,
7616                                     (ushort)((ushort)ASC_QADR_BEG +
7617                                              (ushort)target_ix));
7618                 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
7619
7620                         scsi_busy = AscReadLramByte(iop_base,
7621                                                     (ushort)ASCV_SCSIBUSY_B);
7622                         scsi_busy |= target_id;
7623                         AscWriteLramByte(iop_base,
7624                                          (ushort)ASCV_SCSIBUSY_B, scsi_busy);
7625                         asc_dvc->queue_full_or_busy |= target_id;
7626
7627                         if (scsi_status == SAM_STAT_TASK_SET_FULL) {
7628                                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
7629                                         cur_dvc_qng -= 1;
7630                                         asc_dvc->max_dvc_qng[tid_no] =
7631                                             cur_dvc_qng;
7632
7633                                         AscWriteLramByte(iop_base,
7634                                                          (ushort)((ushort)
7635                                                                   ASCV_MAX_DVC_QNG_BEG
7636                                                                   + (ushort)
7637                                                                   tid_no),
7638                                                          cur_dvc_qng);
7639
7640                                         /*
7641                                          * Set the device queue depth to the number of
7642                                          * active requests when the QUEUE FULL condition
7643                                          * was encountered.
7644                                          */
7645                                         boardp->queue_full |= target_id;
7646                                         boardp->queue_full_cnt[tid_no] =
7647                                             cur_dvc_qng;
7648                                 }
7649                         }
7650                 }
7651                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7652                 return (0);
7653         }
7654 #if CC_VERY_LONG_SG_LIST
7655         else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
7656                 uchar q_no;
7657                 ushort q_addr;
7658                 uchar sg_wk_q_no;
7659                 uchar first_sg_wk_q_no;
7660                 ASC_SCSI_Q *scsiq;      /* Ptr to driver request. */
7661                 ASC_SG_HEAD *sg_head;   /* Ptr to driver SG request. */
7662                 ASC_SG_LIST_Q scsi_sg_q;        /* Structure written to queue. */
7663                 ushort sg_list_dwords;
7664                 ushort sg_entry_cnt;
7665                 uchar next_qp;
7666                 int i;
7667
7668                 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
7669                 if (q_no == ASC_QLINK_END) {
7670                         return (0);
7671                 }
7672
7673                 q_addr = ASC_QNO_TO_QADDR(q_no);
7674
7675                 /*
7676                  * Convert the request's SRB pointer to a host ASC_SCSI_REQ
7677                  * structure pointer using a macro provided by the driver.
7678                  * The ASC_SCSI_REQ pointer provides a pointer to the
7679                  * host ASC_SG_HEAD structure.
7680                  */
7681                 /* Read request's SRB pointer. */
7682                 scsiq = (ASC_SCSI_Q *)
7683                     ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
7684                                                                     (ushort)
7685                                                                     (q_addr +
7686                                                                      ASC_SCSIQ_D_SRBPTR))));
7687
7688                 /*
7689                  * Get request's first and working SG queue.
7690                  */
7691                 sg_wk_q_no = AscReadLramByte(iop_base,
7692                                              (ushort)(q_addr +
7693                                                       ASC_SCSIQ_B_SG_WK_QP));
7694
7695                 first_sg_wk_q_no = AscReadLramByte(iop_base,
7696                                                    (ushort)(q_addr +
7697                                                             ASC_SCSIQ_B_FIRST_SG_WK_QP));
7698
7699                 /*
7700                  * Reset request's working SG queue back to the
7701                  * first SG queue.
7702                  */
7703                 AscWriteLramByte(iop_base,
7704                                  (ushort)(q_addr +
7705                                           (ushort)ASC_SCSIQ_B_SG_WK_QP),
7706                                  first_sg_wk_q_no);
7707
7708                 sg_head = scsiq->sg_head;
7709
7710                 /*
7711                  * Set sg_entry_cnt to the number of SG elements
7712                  * that will be completed on this interrupt.
7713                  *
7714                  * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
7715                  * SG elements. The data_cnt and data_addr fields which
7716                  * add 1 to the SG element capacity are not used when
7717                  * restarting SG handling after a halt.
7718                  */
7719                 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
7720                         sg_entry_cnt = ASC_MAX_SG_LIST - 1;
7721
7722                         /*
7723                          * Keep track of remaining number of SG elements that will
7724                          * need to be handled on the next interrupt.
7725                          */
7726                         scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
7727                 } else {
7728                         sg_entry_cnt = scsiq->remain_sg_entry_cnt;
7729                         scsiq->remain_sg_entry_cnt = 0;
7730                 }
7731
7732                 /*
7733                  * Copy SG elements into the list of allocated SG queues.
7734                  *
7735                  * Last index completed is saved in scsiq->next_sg_index.
7736                  */
7737                 next_qp = first_sg_wk_q_no;
7738                 q_addr = ASC_QNO_TO_QADDR(next_qp);
7739                 scsi_sg_q.sg_head_qp = q_no;
7740                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
7741                 for (i = 0; i < sg_head->queue_cnt; i++) {
7742                         scsi_sg_q.seq_no = i + 1;
7743                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
7744                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
7745                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
7746                                 /*
7747                                  * After very first SG queue RISC FW uses next
7748                                  * SG queue first element then checks sg_list_cnt
7749                                  * against zero and then decrements, so set
7750                                  * sg_list_cnt 1 less than number of SG elements
7751                                  * in each SG queue.
7752                                  */
7753                                 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
7754                                 scsi_sg_q.sg_cur_list_cnt =
7755                                     ASC_SG_LIST_PER_Q - 1;
7756                         } else {
7757                                 /*
7758                                  * This is the last SG queue in the list of
7759                                  * allocated SG queues. If there are more
7760                                  * SG elements than will fit in the allocated
7761                                  * queues, then set the QCSG_SG_XFER_MORE flag.
7762                                  */
7763                                 if (scsiq->remain_sg_entry_cnt != 0) {
7764                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
7765                                 } else {
7766                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
7767                                 }
7768                                 /* equals sg_entry_cnt * 2 */
7769                                 sg_list_dwords = sg_entry_cnt << 1;
7770                                 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
7771                                 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
7772                                 sg_entry_cnt = 0;
7773                         }
7774
7775                         scsi_sg_q.q_no = next_qp;
7776                         AscMemWordCopyPtrToLram(iop_base,
7777                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
7778                                                 (uchar *)&scsi_sg_q,
7779                                                 sizeof(ASC_SG_LIST_Q) >> 1);
7780
7781                         AscMemDWordCopyPtrToLram(iop_base,
7782                                                  q_addr + ASC_SGQ_LIST_BEG,
7783                                                  (uchar *)&sg_head->
7784                                                  sg_list[scsiq->next_sg_index],
7785                                                  sg_list_dwords);
7786
7787                         scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
7788
7789                         /*
7790                          * If the just completed SG queue contained the
7791                          * last SG element, then no more SG queues need
7792                          * to be written.
7793                          */
7794                         if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
7795                                 break;
7796                         }
7797
7798                         next_qp = AscReadLramByte(iop_base,
7799                                                   (ushort)(q_addr +
7800                                                            ASC_SCSIQ_B_FWD));
7801                         q_addr = ASC_QNO_TO_QADDR(next_qp);
7802                 }
7803
7804                 /*
7805                  * Clear the halt condition so the RISC will be restarted
7806                  * after the return.
7807                  */
7808                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
7809                 return (0);
7810         }
7811 #endif /* CC_VERY_LONG_SG_LIST */
7812         return (0);
7813 }
7814
7815 static uchar
7816 _AscCopyLramScsiDoneQ(PortAddr iop_base,
7817                       ushort q_addr,
7818                       ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
7819 {
7820         ushort _val;
7821         uchar sg_queue_cnt;
7822
7823         DvcGetQinfo(iop_base,
7824                     q_addr + ASC_SCSIQ_DONE_INFO_BEG,
7825                     (uchar *)scsiq,
7826                     (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
7827
7828         _val = AscReadLramWord(iop_base,
7829                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
7830         scsiq->q_status = (uchar)_val;
7831         scsiq->q_no = (uchar)(_val >> 8);
7832         _val = AscReadLramWord(iop_base,
7833                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
7834         scsiq->cntl = (uchar)_val;
7835         sg_queue_cnt = (uchar)(_val >> 8);
7836         _val = AscReadLramWord(iop_base,
7837                                (ushort)(q_addr +
7838                                         (ushort)ASC_SCSIQ_B_SENSE_LEN));
7839         scsiq->sense_len = (uchar)_val;
7840         scsiq->extra_bytes = (uchar)(_val >> 8);
7841
7842         /*
7843          * Read high word of remain bytes from alternate location.
7844          */
7845         scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
7846                                                           (ushort)(q_addr +
7847                                                                    (ushort)
7848                                                                    ASC_SCSIQ_W_ALT_DC1)))
7849                                << 16);
7850         /*
7851          * Read low word of remain bytes from original location.
7852          */
7853         scsiq->remain_bytes += AscReadLramWord(iop_base,
7854                                                (ushort)(q_addr + (ushort)
7855                                                         ASC_SCSIQ_DW_REMAIN_XFER_CNT));
7856
7857         scsiq->remain_bytes &= max_dma_count;
7858         return (sg_queue_cnt);
7859 }
7860
7861 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
7862 {
7863         uchar next_qp;
7864         uchar n_q_used;
7865         uchar sg_list_qp;
7866         uchar sg_queue_cnt;
7867         uchar q_cnt;
7868         uchar done_q_tail;
7869         uchar tid_no;
7870         ASC_SCSI_BIT_ID_TYPE scsi_busy;
7871         ASC_SCSI_BIT_ID_TYPE target_id;
7872         PortAddr iop_base;
7873         ushort q_addr;
7874         ushort sg_q_addr;
7875         uchar cur_target_qng;
7876         ASC_QDONE_INFO scsiq_buf;
7877         ASC_QDONE_INFO *scsiq;
7878         int false_overrun;
7879
7880         iop_base = asc_dvc->iop_base;
7881         n_q_used = 1;
7882         scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
7883         done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
7884         q_addr = ASC_QNO_TO_QADDR(done_q_tail);
7885         next_qp = AscReadLramByte(iop_base,
7886                                   (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
7887         if (next_qp != ASC_QLINK_END) {
7888                 AscPutVarDoneQTail(iop_base, next_qp);
7889                 q_addr = ASC_QNO_TO_QADDR(next_qp);
7890                 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
7891                                                      asc_dvc->max_dma_count);
7892                 AscWriteLramByte(iop_base,
7893                                  (ushort)(q_addr +
7894                                           (ushort)ASC_SCSIQ_B_STATUS),
7895                                  (uchar)(scsiq->
7896                                          q_status & (uchar)~(QS_READY |
7897                                                              QS_ABORTED)));
7898                 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
7899                 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
7900                 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
7901                         sg_q_addr = q_addr;
7902                         sg_list_qp = next_qp;
7903                         for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
7904                                 sg_list_qp = AscReadLramByte(iop_base,
7905                                                              (ushort)(sg_q_addr
7906                                                                       + (ushort)
7907                                                                       ASC_SCSIQ_B_FWD));
7908                                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
7909                                 if (sg_list_qp == ASC_QLINK_END) {
7910                                         AscSetLibErrorCode(asc_dvc,
7911                                                            ASCQ_ERR_SG_Q_LINKS);
7912                                         scsiq->d3.done_stat = QD_WITH_ERROR;
7913                                         scsiq->d3.host_stat =
7914                                             QHSTA_D_QDONE_SG_LIST_CORRUPTED;
7915                                         goto FATAL_ERR_QDONE;
7916                                 }
7917                                 AscWriteLramByte(iop_base,
7918                                                  (ushort)(sg_q_addr + (ushort)
7919                                                           ASC_SCSIQ_B_STATUS),
7920                                                  QS_FREE);
7921                         }
7922                         n_q_used = sg_queue_cnt + 1;
7923                         AscPutVarDoneQTail(iop_base, sg_list_qp);
7924                 }
7925                 if (asc_dvc->queue_full_or_busy & target_id) {
7926                         cur_target_qng = AscReadLramByte(iop_base,
7927                                                          (ushort)((ushort)
7928                                                                   ASC_QADR_BEG
7929                                                                   + (ushort)
7930                                                                   scsiq->d2.
7931                                                                   target_ix));
7932                         if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
7933                                 scsi_busy = AscReadLramByte(iop_base, (ushort)
7934                                                             ASCV_SCSIBUSY_B);
7935                                 scsi_busy &= ~target_id;
7936                                 AscWriteLramByte(iop_base,
7937                                                  (ushort)ASCV_SCSIBUSY_B,
7938                                                  scsi_busy);
7939                                 asc_dvc->queue_full_or_busy &= ~target_id;
7940                         }
7941                 }
7942                 if (asc_dvc->cur_total_qng >= n_q_used) {
7943                         asc_dvc->cur_total_qng -= n_q_used;
7944                         if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
7945                                 asc_dvc->cur_dvc_qng[tid_no]--;
7946                         }
7947                 } else {
7948                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
7949                         scsiq->d3.done_stat = QD_WITH_ERROR;
7950                         goto FATAL_ERR_QDONE;
7951                 }
7952                 if ((scsiq->d2.srb_ptr == 0UL) ||
7953                     ((scsiq->q_status & QS_ABORTED) != 0)) {
7954                         return (0x11);
7955                 } else if (scsiq->q_status == QS_DONE) {
7956                         false_overrun = FALSE;
7957                         if (scsiq->extra_bytes != 0) {
7958                                 scsiq->remain_bytes +=
7959                                     (ADV_DCNT)scsiq->extra_bytes;
7960                         }
7961                         if (scsiq->d3.done_stat == QD_WITH_ERROR) {
7962                                 if (scsiq->d3.host_stat ==
7963                                     QHSTA_M_DATA_OVER_RUN) {
7964                                         if ((scsiq->
7965                                              cntl & (QC_DATA_IN | QC_DATA_OUT))
7966                                             == 0) {
7967                                                 scsiq->d3.done_stat =
7968                                                     QD_NO_ERROR;
7969                                                 scsiq->d3.host_stat =
7970                                                     QHSTA_NO_ERROR;
7971                                         } else if (false_overrun) {
7972                                                 scsiq->d3.done_stat =
7973                                                     QD_NO_ERROR;
7974                                                 scsiq->d3.host_stat =
7975                                                     QHSTA_NO_ERROR;
7976                                         }
7977                                 } else if (scsiq->d3.host_stat ==
7978                                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
7979                                         AscStopChip(iop_base);
7980                                         AscSetChipControl(iop_base,
7981                                                           (uchar)(CC_SCSI_RESET
7982                                                                   | CC_HALT));
7983                                         DvcDelayNanoSecond(asc_dvc, 60000);
7984                                         AscSetChipControl(iop_base, CC_HALT);
7985                                         AscSetChipStatus(iop_base,
7986                                                          CIW_CLR_SCSI_RESET_INT);
7987                                         AscSetChipStatus(iop_base, 0);
7988                                         AscSetChipControl(iop_base, 0);
7989                                 }
7990                         }
7991                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
7992                                 asc_isr_callback(asc_dvc, scsiq);
7993                         } else {
7994                                 if ((AscReadLramByte(iop_base,
7995                                                      (ushort)(q_addr + (ushort)
7996                                                               ASC_SCSIQ_CDB_BEG))
7997                                      == START_STOP)) {
7998                                         asc_dvc->unit_not_ready &= ~target_id;
7999                                         if (scsiq->d3.done_stat != QD_NO_ERROR) {
8000                                                 asc_dvc->start_motor &=
8001                                                     ~target_id;
8002                                         }
8003                                 }
8004                         }
8005                         return (1);
8006                 } else {
8007                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8008  FATAL_ERR_QDONE:
8009                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8010                                 asc_isr_callback(asc_dvc, scsiq);
8011                         }
8012                         return (0x80);
8013                 }
8014         }
8015         return (0);
8016 }
8017
8018 static int AscISR(ASC_DVC_VAR *asc_dvc)
8019 {
8020         ASC_CS_TYPE chipstat;
8021         PortAddr iop_base;
8022         ushort saved_ram_addr;
8023         uchar ctrl_reg;
8024         uchar saved_ctrl_reg;
8025         int int_pending;
8026         int status;
8027         uchar host_flag;
8028
8029         iop_base = asc_dvc->iop_base;
8030         int_pending = FALSE;
8031
8032         if (AscIsIntPending(iop_base) == 0) {
8033                 return int_pending;
8034         }
8035
8036         if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
8037                 return (ERR);
8038         }
8039         if (asc_dvc->in_critical_cnt != 0) {
8040                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8041                 return (ERR);
8042         }
8043         if (asc_dvc->is_in_int) {
8044                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8045                 return (ERR);
8046         }
8047         asc_dvc->is_in_int = TRUE;
8048         ctrl_reg = AscGetChipControl(iop_base);
8049         saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8050                                        CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8051         chipstat = AscGetChipStatus(iop_base);
8052         if (chipstat & CSW_SCSI_RESET_LATCH) {
8053                 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8054                         int i = 10;
8055                         int_pending = TRUE;
8056                         asc_dvc->sdtr_done = 0;
8057                         saved_ctrl_reg &= (uchar)(~CC_HALT);
8058                         while ((AscGetChipStatus(iop_base) &
8059                                 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8060                                 DvcSleepMilliSecond(100);
8061                         }
8062                         AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8063                         AscSetChipControl(iop_base, CC_HALT);
8064                         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8065                         AscSetChipStatus(iop_base, 0);
8066                         chipstat = AscGetChipStatus(iop_base);
8067                 }
8068         }
8069         saved_ram_addr = AscGetChipLramAddr(iop_base);
8070         host_flag = AscReadLramByte(iop_base,
8071                                     ASCV_HOST_FLAG_B) &
8072             (uchar)(~ASC_HOST_FLAG_IN_ISR);
8073         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8074                          (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8075         if ((chipstat & CSW_INT_PENDING)
8076             || (int_pending)
8077             ) {
8078                 AscAckInterrupt(iop_base);
8079                 int_pending = TRUE;
8080                 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8081                         if (AscIsrChipHalted(asc_dvc) == ERR) {
8082                                 goto ISR_REPORT_QDONE_FATAL_ERROR;
8083                         } else {
8084                                 saved_ctrl_reg &= (uchar)(~CC_HALT);
8085                         }
8086                 } else {
8087  ISR_REPORT_QDONE_FATAL_ERROR:
8088                         if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8089                                 while (((status =
8090                                          AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8091                                 }
8092                         } else {
8093                                 do {
8094                                         if ((status =
8095                                              AscIsrQDone(asc_dvc)) == 1) {
8096                                                 break;
8097                                         }
8098                                 } while (status == 0x11);
8099                         }
8100                         if ((status & 0x80) != 0)
8101                                 int_pending = ERR;
8102                 }
8103         }
8104         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8105         AscSetChipLramAddr(iop_base, saved_ram_addr);
8106         AscSetChipControl(iop_base, saved_ctrl_reg);
8107         asc_dvc->is_in_int = FALSE;
8108         return (int_pending);
8109 }
8110
8111 /* Microcode buffer is kept after initialization for error recovery. */
8112 static uchar _asc_mcode_buf[] = {
8113         0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8114         0x00, 0x00, 0x00, 0x00,
8115         0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
8116         0x00, 0x00, 0x00, 0x00,
8117         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8118         0x00, 0x00, 0x00, 0x00,
8119         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8120         0x00, 0x00, 0x00, 0x00,
8121         0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
8122         0x00, 0xFF, 0x00, 0x00,
8123         0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
8124         0x00, 0x00, 0x00, 0x00,
8125         0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
8126         0x00, 0x00, 0x00, 0x00,
8127         0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
8128         0x00, 0x00, 0x00, 0x00,
8129         0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
8130         0x03, 0x23, 0x36, 0x40,
8131         0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
8132         0xC2, 0x00, 0x92, 0x80,
8133         0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
8134         0xB6, 0x00, 0x92, 0x80,
8135         0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
8136         0x92, 0x80, 0x80, 0x62,
8137         0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
8138         0xCD, 0x04, 0x4D, 0x00,
8139         0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
8140         0xE6, 0x84, 0xD2, 0xC1,
8141         0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
8142         0xC6, 0x81, 0xC2, 0x88,
8143         0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
8144         0x84, 0x97, 0x07, 0xA6,
8145         0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
8146         0xC2, 0x88, 0xCE, 0x00,
8147         0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
8148         0x80, 0x63, 0x07, 0xA6,
8149         0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
8150         0x34, 0x01, 0x00, 0x33,
8151         0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
8152         0x68, 0x98, 0x4D, 0x04,
8153         0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
8154         0xF8, 0x88, 0xFB, 0x23,
8155         0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
8156         0x00, 0x33, 0x0A, 0x00,
8157         0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
8158         0xC2, 0x88, 0xCD, 0x04,
8159         0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
8160         0x06, 0xAB, 0x82, 0x01,
8161         0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
8162         0x3C, 0x01, 0x00, 0x05,
8163         0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
8164         0x15, 0x23, 0xA1, 0x01,
8165         0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
8166         0x06, 0x61, 0x00, 0xA0,
8167         0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
8168         0xC2, 0x88, 0x06, 0x23,
8169         0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
8170         0x57, 0x60, 0x00, 0xA0,
8171         0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
8172         0x4B, 0x00, 0x06, 0x61,
8173         0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
8174         0x4F, 0x00, 0x84, 0x97,
8175         0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
8176         0x48, 0x04, 0x84, 0x80,
8177         0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
8178         0x81, 0x73, 0x06, 0x29,
8179         0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
8180         0x04, 0x98, 0xF0, 0x80,
8181         0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
8182         0x34, 0x02, 0x03, 0xA6,
8183         0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
8184         0x46, 0x82, 0xFE, 0x95,
8185         0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
8186         0x07, 0xA6, 0x5A, 0x02,
8187         0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
8188         0x48, 0x82, 0x60, 0x96,
8189         0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
8190         0x04, 0x01, 0x0C, 0xDC,
8191         0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
8192         0x6F, 0x00, 0xA5, 0x01,
8193         0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
8194         0x02, 0xA6, 0xAA, 0x02,
8195         0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
8196         0x01, 0xA6, 0xB4, 0x02,
8197         0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
8198         0x80, 0x63, 0x00, 0x43,
8199         0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
8200         0x04, 0x61, 0x84, 0x01,
8201         0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
8202         0x00, 0x00, 0xEA, 0x82,
8203         0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
8204         0x00, 0x33, 0x1F, 0x00,
8205         0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
8206         0xB6, 0x2D, 0x01, 0xA6,
8207         0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
8208         0x10, 0x03, 0x03, 0xA6,
8209         0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
8210         0x7C, 0x95, 0xEE, 0x82,
8211         0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
8212         0x04, 0x01, 0x2D, 0xC8,
8213         0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
8214         0x05, 0x05, 0x86, 0x98,
8215         0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
8216         0x3C, 0x04, 0x06, 0xA6,
8217         0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
8218         0x7C, 0x95, 0x32, 0x83,
8219         0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
8220         0xEB, 0x04, 0x00, 0x33,
8221         0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
8222         0xFF, 0xA2, 0x7A, 0x03,
8223         0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
8224         0x00, 0xA2, 0x9A, 0x03,
8225         0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
8226         0x01, 0xA6, 0x96, 0x03,
8227         0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
8228         0xA4, 0x03, 0x00, 0xA6,
8229         0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
8230         0x07, 0xA6, 0xB2, 0x03,
8231         0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
8232         0xA8, 0x98, 0x80, 0x42,
8233         0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
8234         0xC0, 0x83, 0x00, 0x33,
8235         0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
8236         0xA0, 0x01, 0x12, 0x23,
8237         0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
8238         0x80, 0x67, 0x05, 0x23,
8239         0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
8240         0x06, 0xA6, 0x0A, 0x04,
8241         0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
8242         0xF4, 0x83, 0x20, 0x84,
8243         0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
8244         0x83, 0x03, 0x80, 0x63,
8245         0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
8246         0x38, 0x04, 0x00, 0x33,
8247         0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
8248         0x1D, 0x01, 0x06, 0xCC,
8249         0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
8250         0xA2, 0x0D, 0x80, 0x63,
8251         0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
8252         0x80, 0x63, 0xA3, 0x01,
8253         0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
8254         0x76, 0x04, 0xE0, 0x00,
8255         0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
8256         0x00, 0x33, 0x1E, 0x00,
8257         0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
8258         0x08, 0x23, 0x22, 0xA3,
8259         0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
8260         0xC4, 0x04, 0x42, 0x23,
8261         0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
8262         0xF8, 0x88, 0x04, 0x98,
8263         0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
8264         0x81, 0x62, 0xE8, 0x81,
8265         0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
8266         0x00, 0x33, 0x00, 0x81,
8267         0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
8268         0xF8, 0x88, 0x04, 0x23,
8269         0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
8270         0xF4, 0x04, 0x00, 0x33,
8271         0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
8272         0x04, 0x23, 0xA0, 0x01,
8273         0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
8274         0x00, 0xA3, 0x22, 0x05,
8275         0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
8276         0x46, 0x97, 0xCD, 0x04,
8277         0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
8278         0x82, 0x01, 0x34, 0x85,
8279         0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
8280         0x1D, 0x01, 0x04, 0xD6,
8281         0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
8282         0x49, 0x00, 0x81, 0x01,
8283         0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
8284         0x49, 0x04, 0x80, 0x01,
8285         0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
8286         0x01, 0x23, 0xEA, 0x00,
8287         0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
8288         0x07, 0xA4, 0xF8, 0x05,
8289         0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
8290         0xC2, 0x88, 0x04, 0xA0,
8291         0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
8292         0x00, 0xA2, 0xA4, 0x05,
8293         0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
8294         0x62, 0x97, 0x04, 0x85,
8295         0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
8296         0xF4, 0x85, 0x03, 0xA0,
8297         0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
8298         0xCC, 0x86, 0x07, 0xA0,
8299         0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
8300         0x80, 0x67, 0x80, 0x63,
8301         0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
8302         0xF8, 0x88, 0x07, 0x23,
8303         0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
8304         0x00, 0x63, 0x4A, 0x00,
8305         0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
8306         0x07, 0x41, 0x83, 0x03,
8307         0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
8308         0x1D, 0x01, 0x01, 0xD6,
8309         0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
8310         0x07, 0xA6, 0x7C, 0x05,
8311         0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
8312         0x52, 0x00, 0x06, 0x61,
8313         0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
8314         0x00, 0x63, 0x1D, 0x01,
8315         0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
8316         0x07, 0x41, 0x00, 0x63,
8317         0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
8318         0xDF, 0x00, 0x06, 0xA6,
8319         0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
8320         0x00, 0x40, 0xC0, 0x20,
8321         0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
8322         0x06, 0xA6, 0x94, 0x06,
8323         0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
8324         0x40, 0x0E, 0x80, 0x63,
8325         0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
8326         0x80, 0x63, 0x00, 0x43,
8327         0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
8328         0x80, 0x67, 0x40, 0x0E,
8329         0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
8330         0x07, 0xA6, 0xD6, 0x06,
8331         0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
8332         0x0A, 0x2B, 0x07, 0xA6,
8333         0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
8334         0xF4, 0x06, 0xC0, 0x0E,
8335         0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
8336         0x81, 0x62, 0x04, 0x01,
8337         0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
8338         0x8C, 0x06, 0x00, 0x33,
8339         0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
8340         0x80, 0x63, 0x06, 0xA6,
8341         0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
8342         0x00, 0x00, 0x80, 0x67,
8343         0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
8344         0xBF, 0x23, 0x04, 0x61,
8345         0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
8346         0x00, 0x01, 0xF2, 0x00,
8347         0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
8348         0x80, 0x05, 0x81, 0x05,
8349         0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
8350         0x70, 0x00, 0x81, 0x01,
8351         0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
8352         0x70, 0x00, 0x80, 0x01,
8353         0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
8354         0xF1, 0x00, 0x70, 0x00,
8355         0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
8356         0x71, 0x04, 0x70, 0x00,
8357         0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
8358         0xA3, 0x01, 0xA2, 0x01,
8359         0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
8360         0xC4, 0x07, 0x00, 0x33,
8361         0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
8362         0x48, 0x00, 0xB0, 0x01,
8363         0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
8364         0x00, 0xA2, 0xE4, 0x07,
8365         0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
8366         0x05, 0x05, 0x00, 0x63,
8367         0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
8368         0x76, 0x08, 0x80, 0x02,
8369         0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
8370         0x00, 0x02, 0x00, 0xA0,
8371         0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
8372         0x00, 0x63, 0xF3, 0x04,
8373         0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
8374         0x00, 0xA2, 0x44, 0x08,
8375         0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
8376         0x24, 0x08, 0x04, 0x98,
8377         0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
8378         0x5A, 0x88, 0x02, 0x01,
8379         0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
8380         0x00, 0xA3, 0x64, 0x08,
8381         0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
8382         0x06, 0xA6, 0x76, 0x08,
8383         0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
8384         0x00, 0x63, 0x38, 0x2B,
8385         0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
8386         0x05, 0x05, 0xB2, 0x09,
8387         0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
8388         0x80, 0x32, 0x80, 0x36,
8389         0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
8390         0x40, 0x36, 0x40, 0x3A,
8391         0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
8392         0x5D, 0x00, 0xFE, 0xC3,
8393         0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
8394         0xFF, 0xFD, 0x80, 0x73,
8395         0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
8396         0xA1, 0x23, 0xA1, 0x01,
8397         0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
8398         0x80, 0x00, 0x03, 0xC2,
8399         0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
8400         0xA0, 0x01, 0xE6, 0x84,
8401 };
8402
8403 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
8404 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
8405
8406 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
8407 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
8408         INQUIRY,
8409         REQUEST_SENSE,
8410         READ_CAPACITY,
8411         READ_TOC,
8412         MODE_SELECT,
8413         MODE_SENSE,
8414         MODE_SELECT_10,
8415         MODE_SENSE_10,
8416         0xFF,
8417         0xFF,
8418         0xFF,
8419         0xFF,
8420         0xFF,
8421         0xFF,
8422         0xFF,
8423         0xFF
8424 };
8425
8426 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
8427 {
8428         PortAddr iop_base;
8429         ulong last_int_level;
8430         int sta;
8431         int n_q_required;
8432         int disable_syn_offset_one_fix;
8433         int i;
8434         ASC_PADDR addr;
8435         ushort sg_entry_cnt = 0;
8436         ushort sg_entry_cnt_minus_one = 0;
8437         uchar target_ix;
8438         uchar tid_no;
8439         uchar sdtr_data;
8440         uchar extra_bytes;
8441         uchar scsi_cmd;
8442         uchar disable_cmd;
8443         ASC_SG_HEAD *sg_head;
8444         ASC_DCNT data_cnt;
8445
8446         iop_base = asc_dvc->iop_base;
8447         sg_head = scsiq->sg_head;
8448         if (asc_dvc->err_code != 0)
8449                 return (ERR);
8450         if (scsiq == (ASC_SCSI_Q *)0L) {
8451                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
8452                 return (ERR);
8453         }
8454         scsiq->q1.q_no = 0;
8455         if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
8456                 scsiq->q1.extra_bytes = 0;
8457         }
8458         sta = 0;
8459         target_ix = scsiq->q2.target_ix;
8460         tid_no = ASC_TIX_TO_TID(target_ix);
8461         n_q_required = 1;
8462         if (scsiq->cdbptr[0] == REQUEST_SENSE) {
8463                 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
8464                         asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
8465                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8466                         AscMsgOutSDTR(asc_dvc,
8467                                       asc_dvc->
8468                                       sdtr_period_tbl[(sdtr_data >> 4) &
8469                                                       (uchar)(asc_dvc->
8470                                                               max_sdtr_index -
8471                                                               1)],
8472                                       (uchar)(sdtr_data & (uchar)
8473                                               ASC_SYN_MAX_OFFSET));
8474                         scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
8475                 }
8476         }
8477         last_int_level = DvcEnterCritical();
8478         if (asc_dvc->in_critical_cnt != 0) {
8479                 DvcLeaveCritical(last_int_level);
8480                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
8481                 return (ERR);
8482         }
8483         asc_dvc->in_critical_cnt++;
8484         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8485                 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
8486                         asc_dvc->in_critical_cnt--;
8487                         DvcLeaveCritical(last_int_level);
8488                         return (ERR);
8489                 }
8490 #if !CC_VERY_LONG_SG_LIST
8491                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
8492                         asc_dvc->in_critical_cnt--;
8493                         DvcLeaveCritical(last_int_level);
8494                         return (ERR);
8495                 }
8496 #endif /* !CC_VERY_LONG_SG_LIST */
8497                 if (sg_entry_cnt == 1) {
8498                         scsiq->q1.data_addr =
8499                             (ADV_PADDR)sg_head->sg_list[0].addr;
8500                         scsiq->q1.data_cnt =
8501                             (ADV_DCNT)sg_head->sg_list[0].bytes;
8502                         scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
8503                 }
8504                 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
8505         }
8506         scsi_cmd = scsiq->cdbptr[0];
8507         disable_syn_offset_one_fix = FALSE;
8508         if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
8509             !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
8510                 if (scsiq->q1.cntl & QC_SG_HEAD) {
8511                         data_cnt = 0;
8512                         for (i = 0; i < sg_entry_cnt; i++) {
8513                                 data_cnt +=
8514                                     (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
8515                                                           bytes);
8516                         }
8517                 } else {
8518                         data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
8519                 }
8520                 if (data_cnt != 0UL) {
8521                         if (data_cnt < 512UL) {
8522                                 disable_syn_offset_one_fix = TRUE;
8523                         } else {
8524                                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
8525                                      i++) {
8526                                         disable_cmd =
8527                                             _syn_offset_one_disable_cmd[i];
8528                                         if (disable_cmd == 0xFF) {
8529                                                 break;
8530                                         }
8531                                         if (scsi_cmd == disable_cmd) {
8532                                                 disable_syn_offset_one_fix =
8533                                                     TRUE;
8534                                                 break;
8535                                         }
8536                                 }
8537                         }
8538                 }
8539         }
8540         if (disable_syn_offset_one_fix) {
8541                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
8542                 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
8543                                        ASC_TAG_FLAG_DISABLE_DISCONNECT);
8544         } else {
8545                 scsiq->q2.tag_code &= 0x27;
8546         }
8547         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
8548                 if (asc_dvc->bug_fix_cntl) {
8549                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8550                                 if ((scsi_cmd == READ_6) ||
8551                                     (scsi_cmd == READ_10)) {
8552                                         addr =
8553                                             (ADV_PADDR)le32_to_cpu(sg_head->
8554                                                                    sg_list
8555                                                                    [sg_entry_cnt_minus_one].
8556                                                                    addr) +
8557                                             (ADV_DCNT)le32_to_cpu(sg_head->
8558                                                                   sg_list
8559                                                                   [sg_entry_cnt_minus_one].
8560                                                                   bytes);
8561                                         extra_bytes =
8562                                             (uchar)((ushort)addr & 0x0003);
8563                                         if ((extra_bytes != 0)
8564                                             &&
8565                                             ((scsiq->q2.
8566                                               tag_code &
8567                                               ASC_TAG_FLAG_EXTRA_BYTES)
8568                                              == 0)) {
8569                                                 scsiq->q2.tag_code |=
8570                                                     ASC_TAG_FLAG_EXTRA_BYTES;
8571                                                 scsiq->q1.extra_bytes =
8572                                                     extra_bytes;
8573                                                 data_cnt =
8574                                                     le32_to_cpu(sg_head->
8575                                                                 sg_list
8576                                                                 [sg_entry_cnt_minus_one].
8577                                                                 bytes);
8578                                                 data_cnt -=
8579                                                     (ASC_DCNT) extra_bytes;
8580                                                 sg_head->
8581                                                     sg_list
8582                                                     [sg_entry_cnt_minus_one].
8583                                                     bytes =
8584                                                     cpu_to_le32(data_cnt);
8585                                         }
8586                                 }
8587                         }
8588                 }
8589                 sg_head->entry_to_copy = sg_head->entry_cnt;
8590 #if CC_VERY_LONG_SG_LIST
8591                 /*
8592                  * Set the sg_entry_cnt to the maximum possible. The rest of
8593                  * the SG elements will be copied when the RISC completes the
8594                  * SG elements that fit and halts.
8595                  */
8596                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
8597                         sg_entry_cnt = ASC_MAX_SG_LIST;
8598                 }
8599 #endif /* CC_VERY_LONG_SG_LIST */
8600                 n_q_required = AscSgListToQueue(sg_entry_cnt);
8601                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
8602                      (uint) n_q_required)
8603                     || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8604                         if ((sta =
8605                              AscSendScsiQueue(asc_dvc, scsiq,
8606                                               n_q_required)) == 1) {
8607                                 asc_dvc->in_critical_cnt--;
8608                                 DvcLeaveCritical(last_int_level);
8609                                 return (sta);
8610                         }
8611                 }
8612         } else {
8613                 if (asc_dvc->bug_fix_cntl) {
8614                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
8615                                 if ((scsi_cmd == READ_6) ||
8616                                     (scsi_cmd == READ_10)) {
8617                                         addr =
8618                                             le32_to_cpu(scsiq->q1.data_addr) +
8619                                             le32_to_cpu(scsiq->q1.data_cnt);
8620                                         extra_bytes =
8621                                             (uchar)((ushort)addr & 0x0003);
8622                                         if ((extra_bytes != 0)
8623                                             &&
8624                                             ((scsiq->q2.
8625                                               tag_code &
8626                                               ASC_TAG_FLAG_EXTRA_BYTES)
8627                                              == 0)) {
8628                                                 data_cnt =
8629                                                     le32_to_cpu(scsiq->q1.
8630                                                                 data_cnt);
8631                                                 if (((ushort)data_cnt & 0x01FF)
8632                                                     == 0) {
8633                                                         scsiq->q2.tag_code |=
8634                                                             ASC_TAG_FLAG_EXTRA_BYTES;
8635                                                         data_cnt -= (ASC_DCNT)
8636                                                             extra_bytes;
8637                                                         scsiq->q1.data_cnt =
8638                                                             cpu_to_le32
8639                                                             (data_cnt);
8640                                                         scsiq->q1.extra_bytes =
8641                                                             extra_bytes;
8642                                                 }
8643                                         }
8644                                 }
8645                         }
8646                 }
8647                 n_q_required = 1;
8648                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
8649                     ((scsiq->q1.cntl & QC_URGENT) != 0)) {
8650                         if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
8651                                                     n_q_required)) == 1) {
8652                                 asc_dvc->in_critical_cnt--;
8653                                 DvcLeaveCritical(last_int_level);
8654                                 return (sta);
8655                         }
8656                 }
8657         }
8658         asc_dvc->in_critical_cnt--;
8659         DvcLeaveCritical(last_int_level);
8660         return (sta);
8661 }
8662
8663 static int
8664 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
8665 {
8666         PortAddr iop_base;
8667         uchar free_q_head;
8668         uchar next_qp;
8669         uchar tid_no;
8670         uchar target_ix;
8671         int sta;
8672
8673         iop_base = asc_dvc->iop_base;
8674         target_ix = scsiq->q2.target_ix;
8675         tid_no = ASC_TIX_TO_TID(target_ix);
8676         sta = 0;
8677         free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
8678         if (n_q_required > 1) {
8679                 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
8680                                                          free_q_head, (uchar)
8681                                                          (n_q_required)))
8682                     != (uchar)ASC_QLINK_END) {
8683                         asc_dvc->last_q_shortage = 0;
8684                         scsiq->sg_head->queue_cnt = n_q_required - 1;
8685                         scsiq->q1.q_no = free_q_head;
8686                         if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
8687                                                           free_q_head)) == 1) {
8688                                 AscPutVarFreeQHead(iop_base, next_qp);
8689                                 asc_dvc->cur_total_qng += (uchar)(n_q_required);
8690                                 asc_dvc->cur_dvc_qng[tid_no]++;
8691                         }
8692                         return (sta);
8693                 }
8694         } else if (n_q_required == 1) {
8695                 if ((next_qp = AscAllocFreeQueue(iop_base,
8696                                                  free_q_head)) !=
8697                     ASC_QLINK_END) {
8698                         scsiq->q1.q_no = free_q_head;
8699                         if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
8700                                                     free_q_head)) == 1) {
8701                                 AscPutVarFreeQHead(iop_base, next_qp);
8702                                 asc_dvc->cur_total_qng++;
8703                                 asc_dvc->cur_dvc_qng[tid_no]++;
8704                         }
8705                         return (sta);
8706                 }
8707         }
8708         return (sta);
8709 }
8710
8711 static int AscSgListToQueue(int sg_list)
8712 {
8713         int n_sg_list_qs;
8714
8715         n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
8716         if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
8717                 n_sg_list_qs++;
8718         return (n_sg_list_qs + 1);
8719 }
8720
8721 static uint
8722 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
8723 {
8724         uint cur_used_qs;
8725         uint cur_free_qs;
8726         ASC_SCSI_BIT_ID_TYPE target_id;
8727         uchar tid_no;
8728
8729         target_id = ASC_TIX_TO_TARGET_ID(target_ix);
8730         tid_no = ASC_TIX_TO_TID(target_ix);
8731         if ((asc_dvc->unit_not_ready & target_id) ||
8732             (asc_dvc->queue_full_or_busy & target_id)) {
8733                 return (0);
8734         }
8735         if (n_qs == 1) {
8736                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
8737                     (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
8738         } else {
8739                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
8740                     (uint) ASC_MIN_FREE_Q;
8741         }
8742         if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
8743                 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
8744                 if (asc_dvc->cur_dvc_qng[tid_no] >=
8745                     asc_dvc->max_dvc_qng[tid_no]) {
8746                         return (0);
8747                 }
8748                 return (cur_free_qs);
8749         }
8750         if (n_qs > 1) {
8751                 if ((n_qs > asc_dvc->last_q_shortage)
8752                     && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
8753                         asc_dvc->last_q_shortage = n_qs;
8754                 }
8755         }
8756         return (0);
8757 }
8758
8759 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
8760 {
8761         ushort q_addr;
8762         uchar tid_no;
8763         uchar sdtr_data;
8764         uchar syn_period_ix;
8765         uchar syn_offset;
8766         PortAddr iop_base;
8767
8768         iop_base = asc_dvc->iop_base;
8769         if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
8770             ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
8771                 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
8772                 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8773                 syn_period_ix =
8774                     (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
8775                 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
8776                 AscMsgOutSDTR(asc_dvc,
8777                               asc_dvc->sdtr_period_tbl[syn_period_ix],
8778                               syn_offset);
8779                 scsiq->q1.cntl |= QC_MSG_OUT;
8780         }
8781         q_addr = ASC_QNO_TO_QADDR(q_no);
8782         if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
8783                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
8784         }
8785         scsiq->q1.status = QS_FREE;
8786         AscMemWordCopyPtrToLram(iop_base,
8787                                 q_addr + ASC_SCSIQ_CDB_BEG,
8788                                 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
8789
8790         DvcPutScsiQ(iop_base,
8791                     q_addr + ASC_SCSIQ_CPY_BEG,
8792                     (uchar *)&scsiq->q1.cntl,
8793                     ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
8794         AscWriteLramWord(iop_base,
8795                          (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
8796                          (ushort)(((ushort)scsiq->q1.
8797                                    q_no << 8) | (ushort)QS_READY));
8798         return (1);
8799 }
8800
8801 static int
8802 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
8803 {
8804         int sta;
8805         int i;
8806         ASC_SG_HEAD *sg_head;
8807         ASC_SG_LIST_Q scsi_sg_q;
8808         ASC_DCNT saved_data_addr;
8809         ASC_DCNT saved_data_cnt;
8810         PortAddr iop_base;
8811         ushort sg_list_dwords;
8812         ushort sg_index;
8813         ushort sg_entry_cnt;
8814         ushort q_addr;
8815         uchar next_qp;
8816
8817         iop_base = asc_dvc->iop_base;
8818         sg_head = scsiq->sg_head;
8819         saved_data_addr = scsiq->q1.data_addr;
8820         saved_data_cnt = scsiq->q1.data_cnt;
8821         scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
8822         scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
8823 #if CC_VERY_LONG_SG_LIST
8824         /*
8825          * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
8826          * then not all SG elements will fit in the allocated queues.
8827          * The rest of the SG elements will be copied when the RISC
8828          * completes the SG elements that fit and halts.
8829          */
8830         if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
8831                 /*
8832                  * Set sg_entry_cnt to be the number of SG elements that
8833                  * will fit in the allocated SG queues. It is minus 1, because
8834                  * the first SG element is handled above. ASC_MAX_SG_LIST is
8835                  * already inflated by 1 to account for this. For example it
8836                  * may be 50 which is 1 + 7 queues * 7 SG elements.
8837                  */
8838                 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8839
8840                 /*
8841                  * Keep track of remaining number of SG elements that will
8842                  * need to be handled from a_isr.c.
8843                  */
8844                 scsiq->remain_sg_entry_cnt =
8845                     sg_head->entry_cnt - ASC_MAX_SG_LIST;
8846         } else {
8847 #endif /* CC_VERY_LONG_SG_LIST */
8848                 /*
8849                  * Set sg_entry_cnt to be the number of SG elements that
8850                  * will fit in the allocated SG queues. It is minus 1, because
8851                  * the first SG element is handled above.
8852                  */
8853                 sg_entry_cnt = sg_head->entry_cnt - 1;
8854 #if CC_VERY_LONG_SG_LIST
8855         }
8856 #endif /* CC_VERY_LONG_SG_LIST */
8857         if (sg_entry_cnt != 0) {
8858                 scsiq->q1.cntl |= QC_SG_HEAD;
8859                 q_addr = ASC_QNO_TO_QADDR(q_no);
8860                 sg_index = 1;
8861                 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
8862                 scsi_sg_q.sg_head_qp = q_no;
8863                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8864                 for (i = 0; i < sg_head->queue_cnt; i++) {
8865                         scsi_sg_q.seq_no = i + 1;
8866                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8867                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8868                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8869                                 if (i == 0) {
8870                                         scsi_sg_q.sg_list_cnt =
8871                                             ASC_SG_LIST_PER_Q;
8872                                         scsi_sg_q.sg_cur_list_cnt =
8873                                             ASC_SG_LIST_PER_Q;
8874                                 } else {
8875                                         scsi_sg_q.sg_list_cnt =
8876                                             ASC_SG_LIST_PER_Q - 1;
8877                                         scsi_sg_q.sg_cur_list_cnt =
8878                                             ASC_SG_LIST_PER_Q - 1;
8879                                 }
8880                         } else {
8881 #if CC_VERY_LONG_SG_LIST
8882                                 /*
8883                                  * This is the last SG queue in the list of
8884                                  * allocated SG queues. If there are more
8885                                  * SG elements than will fit in the allocated
8886                                  * queues, then set the QCSG_SG_XFER_MORE flag.
8887                                  */
8888                                 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
8889                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8890                                 } else {
8891 #endif /* CC_VERY_LONG_SG_LIST */
8892                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8893 #if CC_VERY_LONG_SG_LIST
8894                                 }
8895 #endif /* CC_VERY_LONG_SG_LIST */
8896                                 sg_list_dwords = sg_entry_cnt << 1;
8897                                 if (i == 0) {
8898                                         scsi_sg_q.sg_list_cnt = sg_entry_cnt;
8899                                         scsi_sg_q.sg_cur_list_cnt =
8900                                             sg_entry_cnt;
8901                                 } else {
8902                                         scsi_sg_q.sg_list_cnt =
8903                                             sg_entry_cnt - 1;
8904                                         scsi_sg_q.sg_cur_list_cnt =
8905                                             sg_entry_cnt - 1;
8906                                 }
8907                                 sg_entry_cnt = 0;
8908                         }
8909                         next_qp = AscReadLramByte(iop_base,
8910                                                   (ushort)(q_addr +
8911                                                            ASC_SCSIQ_B_FWD));
8912                         scsi_sg_q.q_no = next_qp;
8913                         q_addr = ASC_QNO_TO_QADDR(next_qp);
8914                         AscMemWordCopyPtrToLram(iop_base,
8915                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8916                                                 (uchar *)&scsi_sg_q,
8917                                                 sizeof(ASC_SG_LIST_Q) >> 1);
8918                         AscMemDWordCopyPtrToLram(iop_base,
8919                                                  q_addr + ASC_SGQ_LIST_BEG,
8920                                                  (uchar *)&sg_head->
8921                                                  sg_list[sg_index],
8922                                                  sg_list_dwords);
8923                         sg_index += ASC_SG_LIST_PER_Q;
8924                         scsiq->next_sg_index = sg_index;
8925                 }
8926         } else {
8927                 scsiq->q1.cntl &= ~QC_SG_HEAD;
8928         }
8929         sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
8930         scsiq->q1.data_addr = saved_data_addr;
8931         scsiq->q1.data_cnt = saved_data_cnt;
8932         return (sta);
8933 }
8934
8935 static int
8936 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
8937 {
8938         int sta = FALSE;
8939
8940         if (AscHostReqRiscHalt(iop_base)) {
8941                 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8942                 AscStartChip(iop_base);
8943                 return (sta);
8944         }
8945         return (sta);
8946 }
8947
8948 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8949 {
8950         ASC_SCSI_BIT_ID_TYPE org_id;
8951         int i;
8952         int sta = TRUE;
8953
8954         AscSetBank(iop_base, 1);
8955         org_id = AscReadChipDvcID(iop_base);
8956         for (i = 0; i <= ASC_MAX_TID; i++) {
8957                 if (org_id == (0x01 << i))
8958                         break;
8959         }
8960         org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8961         AscWriteChipDvcID(iop_base, id);
8962         if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8963                 AscSetBank(iop_base, 0);
8964                 AscSetChipSyn(iop_base, sdtr_data);
8965                 if (AscGetChipSyn(iop_base) != sdtr_data) {
8966                         sta = FALSE;
8967                 }
8968         } else {
8969                 sta = FALSE;
8970         }
8971         AscSetBank(iop_base, 1);
8972         AscWriteChipDvcID(iop_base, org_id);
8973         AscSetBank(iop_base, 0);
8974         return (sta);
8975 }
8976
8977 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
8978 {
8979         uchar i;
8980         ushort s_addr;
8981         PortAddr iop_base;
8982         ushort warn_code;
8983
8984         iop_base = asc_dvc->iop_base;
8985         warn_code = 0;
8986         AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
8987                           (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
8988                                     64) >> 1)
8989             );
8990         i = ASC_MIN_ACTIVE_QNO;
8991         s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
8992         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
8993                          (uchar)(i + 1));
8994         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
8995                          (uchar)(asc_dvc->max_total_qng));
8996         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
8997                          (uchar)i);
8998         i++;
8999         s_addr += ASC_QBLK_SIZE;
9000         for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9001                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9002                                  (uchar)(i + 1));
9003                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9004                                  (uchar)(i - 1));
9005                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9006                                  (uchar)i);
9007         }
9008         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9009                          (uchar)ASC_QLINK_END);
9010         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9011                          (uchar)(asc_dvc->max_total_qng - 1));
9012         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9013                          (uchar)asc_dvc->max_total_qng);
9014         i++;
9015         s_addr += ASC_QBLK_SIZE;
9016         for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9017              i++, s_addr += ASC_QBLK_SIZE) {
9018                 AscWriteLramByte(iop_base,
9019                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9020                 AscWriteLramByte(iop_base,
9021                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9022                 AscWriteLramByte(iop_base,
9023                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9024         }
9025         return (warn_code);
9026 }
9027
9028 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
9029 {
9030         PortAddr iop_base;
9031         int i;
9032         ushort lram_addr;
9033
9034         iop_base = asc_dvc->iop_base;
9035         AscPutRiscVarFreeQHead(iop_base, 1);
9036         AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9037         AscPutVarFreeQHead(iop_base, 1);
9038         AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9039         AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9040                          (uchar)((int)asc_dvc->max_total_qng + 1));
9041         AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9042                          (uchar)((int)asc_dvc->max_total_qng + 2));
9043         AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9044                          asc_dvc->max_total_qng);
9045         AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9046         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9047         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9048         AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9049         AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9050         AscPutQDoneInProgress(iop_base, 0);
9051         lram_addr = ASC_QADR_BEG;
9052         for (i = 0; i < 32; i++, lram_addr += 2) {
9053                 AscWriteLramWord(iop_base, lram_addr, 0);
9054         }
9055         return (0);
9056 }
9057
9058 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
9059 {
9060         if (asc_dvc->err_code == 0) {
9061                 asc_dvc->err_code = err_code;
9062                 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9063                                  err_code);
9064         }
9065         return (err_code);
9066 }
9067
9068 static uchar
9069 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
9070 {
9071         EXT_MSG sdtr_buf;
9072         uchar sdtr_period_index;
9073         PortAddr iop_base;
9074
9075         iop_base = asc_dvc->iop_base;
9076         sdtr_buf.msg_type = EXTENDED_MESSAGE;
9077         sdtr_buf.msg_len = MS_SDTR_LEN;
9078         sdtr_buf.msg_req = EXTENDED_SDTR;
9079         sdtr_buf.xfer_period = sdtr_period;
9080         sdtr_offset &= ASC_SYN_MAX_OFFSET;
9081         sdtr_buf.req_ack_offset = sdtr_offset;
9082         if ((sdtr_period_index =
9083              AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9084             asc_dvc->max_sdtr_index) {
9085                 AscMemWordCopyPtrToLram(iop_base,
9086                                         ASCV_MSGOUT_BEG,
9087                                         (uchar *)&sdtr_buf,
9088                                         sizeof(EXT_MSG) >> 1);
9089                 return ((sdtr_period_index << 4) | sdtr_offset);
9090         } else {
9091
9092                 sdtr_buf.req_ack_offset = 0;
9093                 AscMemWordCopyPtrToLram(iop_base,
9094                                         ASCV_MSGOUT_BEG,
9095                                         (uchar *)&sdtr_buf,
9096                                         sizeof(EXT_MSG) >> 1);
9097                 return (0);
9098         }
9099 }
9100
9101 static uchar
9102 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
9103 {
9104         uchar byte;
9105         uchar sdtr_period_ix;
9106
9107         sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
9108         if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
9109             ) {
9110                 return (0xFF);
9111         }
9112         byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
9113         return (byte);
9114 }
9115
9116 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
9117 {
9118         AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9119         AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
9120         return;
9121 }
9122
9123 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
9124 {
9125         uchar *period_table;
9126         int max_index;
9127         int min_index;
9128         int i;
9129
9130         period_table = asc_dvc->sdtr_period_tbl;
9131         max_index = (int)asc_dvc->max_sdtr_index;
9132         min_index = (int)asc_dvc->host_init_sdtr_index;
9133         if ((syn_time <= period_table[max_index])) {
9134                 for (i = min_index; i < (max_index - 1); i++) {
9135                         if (syn_time <= period_table[i]) {
9136                                 return ((uchar)i);
9137                         }
9138                 }
9139                 return ((uchar)max_index);
9140         } else {
9141                 return ((uchar)(max_index + 1));
9142         }
9143 }
9144
9145 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
9146 {
9147         ushort q_addr;
9148         uchar next_qp;
9149         uchar q_status;
9150
9151         q_addr = ASC_QNO_TO_QADDR(free_q_head);
9152         q_status = (uchar)AscReadLramByte(iop_base,
9153                                           (ushort)(q_addr +
9154                                                    ASC_SCSIQ_B_STATUS));
9155         next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
9156         if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
9157                 return (next_qp);
9158         }
9159         return (ASC_QLINK_END);
9160 }
9161
9162 static uchar
9163 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
9164 {
9165         uchar i;
9166
9167         for (i = 0; i < n_free_q; i++) {
9168                 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
9169                     == ASC_QLINK_END) {
9170                         return (ASC_QLINK_END);
9171                 }
9172         }
9173         return (free_q_head);
9174 }
9175
9176 static int AscHostReqRiscHalt(PortAddr iop_base)
9177 {
9178         int count = 0;
9179         int sta = 0;
9180         uchar saved_stop_code;
9181
9182         if (AscIsChipHalted(iop_base))
9183                 return (1);
9184         saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9185         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9186                          ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9187         do {
9188                 if (AscIsChipHalted(iop_base)) {
9189                         sta = 1;
9190                         break;
9191                 }
9192                 DvcSleepMilliSecond(100);
9193         } while (count++ < 20);
9194         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9195         return (sta);
9196 }
9197
9198 static int AscStopQueueExe(PortAddr iop_base)
9199 {
9200         int count = 0;
9201
9202         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
9203                 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9204                                  ASC_STOP_REQ_RISC_STOP);
9205                 do {
9206                         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
9207                             ASC_STOP_ACK_RISC_STOP) {
9208                                 return (1);
9209                         }
9210                         DvcSleepMilliSecond(100);
9211                 } while (count++ < 20);
9212         }
9213         return (0);
9214 }
9215
9216 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
9217 {
9218         udelay(micro_sec);
9219 }
9220
9221 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
9222 {
9223         udelay((nano_sec + 999) / 1000);
9224 }
9225
9226 static int AscStartChip(PortAddr iop_base)
9227 {
9228         AscSetChipControl(iop_base, 0);
9229         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
9230                 return (0);
9231         }
9232         return (1);
9233 }
9234
9235 static int AscStopChip(PortAddr iop_base)
9236 {
9237         uchar cc_val;
9238
9239         cc_val =
9240             AscGetChipControl(iop_base) &
9241             (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
9242         AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
9243         AscSetChipIH(iop_base, INS_HALT);
9244         AscSetChipIH(iop_base, INS_RFLAG_WTM);
9245         if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
9246                 return (0);
9247         }
9248         return (1);
9249 }
9250
9251 static int AscIsChipHalted(PortAddr iop_base)
9252 {
9253         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
9254                 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
9255                         return (1);
9256                 }
9257         }
9258         return (0);
9259 }
9260
9261 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
9262 {
9263         AscSetBank(iop_base, 1);
9264         AscWriteChipIH(iop_base, ins_code);
9265         AscSetBank(iop_base, 0);
9266         return;
9267 }
9268
9269 static void AscAckInterrupt(PortAddr iop_base)
9270 {
9271         uchar host_flag;
9272         uchar risc_flag;
9273         ushort loop;
9274
9275         loop = 0;
9276         do {
9277                 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
9278                 if (loop++ > 0x7FFF) {
9279                         break;
9280                 }
9281         } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
9282         host_flag =
9283             AscReadLramByte(iop_base,
9284                             ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
9285         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9286                          (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
9287         AscSetChipStatus(iop_base, CIW_INT_ACK);
9288         loop = 0;
9289         while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
9290                 AscSetChipStatus(iop_base, CIW_INT_ACK);
9291                 if (loop++ > 3) {
9292                         break;
9293                 }
9294         }
9295         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9296         return;
9297 }
9298
9299 static void AscDisableInterrupt(PortAddr iop_base)
9300 {
9301         ushort cfg;
9302
9303         cfg = AscGetChipCfgLsw(iop_base);
9304         AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
9305         return;
9306 }
9307
9308 static void AscEnableInterrupt(PortAddr iop_base)
9309 {
9310         ushort cfg;
9311
9312         cfg = AscGetChipCfgLsw(iop_base);
9313         AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
9314         return;
9315 }
9316
9317 static void AscSetBank(PortAddr iop_base, uchar bank)
9318 {
9319         uchar val;
9320
9321         val = AscGetChipControl(iop_base) &
9322             (~
9323              (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
9324               CC_CHIP_RESET));
9325         if (bank == 1) {
9326                 val |= CC_BANK_ONE;
9327         } else if (bank == 2) {
9328                 val |= CC_DIAG | CC_BANK_ONE;
9329         } else {
9330                 val &= ~CC_BANK_ONE;
9331         }
9332         AscSetChipControl(iop_base, val);
9333         return;
9334 }
9335
9336 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
9337 {
9338         PortAddr iop_base;
9339         int i = 10;
9340
9341         iop_base = asc_dvc->iop_base;
9342         while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
9343                && (i-- > 0)) {
9344                 DvcSleepMilliSecond(100);
9345         }
9346         AscStopChip(iop_base);
9347         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
9348         DvcDelayNanoSecond(asc_dvc, 60000);
9349         AscSetChipIH(iop_base, INS_RFLAG_WTM);
9350         AscSetChipIH(iop_base, INS_HALT);
9351         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
9352         AscSetChipControl(iop_base, CC_HALT);
9353         DvcSleepMilliSecond(200);
9354         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9355         AscSetChipStatus(iop_base, 0);
9356         return (AscIsChipHalted(iop_base));
9357 }
9358
9359 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
9360 {
9361         if (bus_type & ASC_IS_ISA)
9362                 return (ASC_MAX_ISA_DMA_COUNT);
9363         else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
9364                 return (ASC_MAX_VL_DMA_COUNT);
9365         return (ASC_MAX_PCI_DMA_COUNT);
9366 }
9367
9368 #ifdef CONFIG_ISA
9369 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
9370 {
9371         ushort channel;
9372
9373         channel = AscGetChipCfgLsw(iop_base) & 0x0003;
9374         if (channel == 0x03)
9375                 return (0);
9376         else if (channel == 0x00)
9377                 return (7);
9378         return (channel + 4);
9379 }
9380
9381 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
9382 {
9383         ushort cfg_lsw;
9384         uchar value;
9385
9386         if ((dma_channel >= 5) && (dma_channel <= 7)) {
9387                 if (dma_channel == 7)
9388                         value = 0x00;
9389                 else
9390                         value = dma_channel - 4;
9391                 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
9392                 cfg_lsw |= value;
9393                 AscSetChipCfgLsw(iop_base, cfg_lsw);
9394                 return (AscGetIsaDmaChannel(iop_base));
9395         }
9396         return (0);
9397 }
9398
9399 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
9400 {
9401         speed_value &= 0x07;
9402         AscSetBank(iop_base, 1);
9403         AscWriteChipDmaSpeed(iop_base, speed_value);
9404         AscSetBank(iop_base, 0);
9405         return (AscGetIsaDmaSpeed(iop_base));
9406 }
9407
9408 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
9409 {
9410         uchar speed_value;
9411
9412         AscSetBank(iop_base, 1);
9413         speed_value = AscReadChipDmaSpeed(iop_base);
9414         speed_value &= 0x07;
9415         AscSetBank(iop_base, 0);
9416         return (speed_value);
9417 }
9418 #endif /* CONFIG_ISA */
9419
9420 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
9421 {
9422         unsigned short warn_code = 0;
9423
9424         asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
9425         if (asc_dvc->err_code != 0)
9426                 return (UW_ERR);
9427
9428         if (AscFindSignature(asc_dvc->iop_base)) {
9429                 warn_code |= AscInitAscDvcVar(asc_dvc);
9430                 warn_code |= AscInitFromEEP(asc_dvc);
9431                 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
9432                 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
9433                         asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
9434         } else {
9435                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9436         }
9437         return warn_code;
9438 }
9439
9440 static unsigned short __devinit
9441 AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc)
9442 {
9443         PortAddr iop_base = asc_dvc->iop_base;
9444         unsigned short cfg_msw;
9445         unsigned short warn_code = 0;
9446
9447         asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
9448         if (asc_dvc->err_code != 0)
9449                 return UW_ERR;
9450         if (!AscFindSignature(asc_dvc->iop_base)) {
9451                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9452                 return 0;
9453         }
9454
9455         cfg_msw = AscGetChipCfgMsw(iop_base);
9456         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
9457                 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
9458                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9459                 AscSetChipCfgMsw(iop_base, cfg_msw);
9460         }
9461         if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
9462             asc_dvc->cfg->cmd_qng_enabled) {
9463                 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
9464                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9465         }
9466         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9467                 warn_code |= ASC_WARN_AUTO_CONFIG;
9468         }
9469         if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
9470                 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
9471                     != asc_dvc->irq_no) {
9472                         asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
9473                 }
9474         }
9475 #ifdef CONFIG_PCI
9476         if (asc_dvc->bus_type & ASC_IS_PCI) {
9477                 cfg_msw &= 0xFFC0;
9478                 AscSetChipCfgMsw(iop_base, cfg_msw);
9479                 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
9480                 } else {
9481                         if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
9482                             (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
9483                                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
9484                                 asc_dvc->bug_fix_cntl |=
9485                                     ASC_BUG_FIX_ASYN_USE_SYN;
9486                         }
9487                 }
9488         } else
9489 #endif /* CONFIG_PCI */
9490         if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
9491                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
9492                     == ASC_CHIP_VER_ASYN_BUG) {
9493                         asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
9494                 }
9495         }
9496         if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
9497             asc_dvc->cfg->chip_scsi_id) {
9498                 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
9499         }
9500 #ifdef CONFIG_ISA
9501         if (asc_dvc->bus_type & ASC_IS_ISA) {
9502                 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
9503                 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
9504         }
9505 #endif /* CONFIG_ISA */
9506
9507         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
9508         return warn_code;
9509 }
9510
9511 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
9512 {
9513         ushort warn_code;
9514         PortAddr iop_base;
9515
9516         iop_base = asc_dvc->iop_base;
9517         warn_code = 0;
9518         if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
9519             !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
9520                 AscResetChipAndScsiBus(asc_dvc);
9521                 DvcSleepMilliSecond((ASC_DCNT)
9522                                     ((ushort)asc_dvc->scsi_reset_wait * 1000));
9523         }
9524         asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
9525         if (asc_dvc->err_code != 0)
9526                 return (UW_ERR);
9527         if (!AscFindSignature(asc_dvc->iop_base)) {
9528                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
9529                 return (warn_code);
9530         }
9531         AscDisableInterrupt(iop_base);
9532         warn_code |= AscInitLram(asc_dvc);
9533         if (asc_dvc->err_code != 0)
9534                 return (UW_ERR);
9535         ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
9536                  (ulong)_asc_mcode_chksum);
9537         if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
9538                              _asc_mcode_size) != _asc_mcode_chksum) {
9539                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
9540                 return (warn_code);
9541         }
9542         warn_code |= AscInitMicroCodeVar(asc_dvc);
9543         asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
9544         AscEnableInterrupt(iop_base);
9545         return (warn_code);
9546 }
9547
9548 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
9549 {
9550         int i;
9551         PortAddr iop_base;
9552         ushort warn_code;
9553         uchar chip_version;
9554
9555         iop_base = asc_dvc->iop_base;
9556         warn_code = 0;
9557         asc_dvc->err_code = 0;
9558         if ((asc_dvc->bus_type &
9559              (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
9560                 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
9561         }
9562         AscSetChipControl(iop_base, CC_HALT);
9563         AscSetChipStatus(iop_base, 0);
9564         asc_dvc->bug_fix_cntl = 0;
9565         asc_dvc->pci_fix_asyn_xfer = 0;
9566         asc_dvc->pci_fix_asyn_xfer_always = 0;
9567         /* asc_dvc->init_state initalized in AscInitGetConfig(). */
9568         asc_dvc->sdtr_done = 0;
9569         asc_dvc->cur_total_qng = 0;
9570         asc_dvc->is_in_int = 0;
9571         asc_dvc->in_critical_cnt = 0;
9572         asc_dvc->last_q_shortage = 0;
9573         asc_dvc->use_tagged_qng = 0;
9574         asc_dvc->no_scam = 0;
9575         asc_dvc->unit_not_ready = 0;
9576         asc_dvc->queue_full_or_busy = 0;
9577         asc_dvc->redo_scam = 0;
9578         asc_dvc->res2 = 0;
9579         asc_dvc->host_init_sdtr_index = 0;
9580         asc_dvc->cfg->can_tagged_qng = 0;
9581         asc_dvc->cfg->cmd_qng_enabled = 0;
9582         asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
9583         asc_dvc->init_sdtr = 0;
9584         asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
9585         asc_dvc->scsi_reset_wait = 3;
9586         asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
9587         asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
9588         asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
9589         asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
9590         asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
9591         asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
9592         asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
9593             ASC_LIB_VERSION_MINOR;
9594         chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
9595         asc_dvc->cfg->chip_version = chip_version;
9596         asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
9597         asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
9598         asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
9599         asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
9600         asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
9601         asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
9602         asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
9603         asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
9604         asc_dvc->max_sdtr_index = 7;
9605         if ((asc_dvc->bus_type & ASC_IS_PCI) &&
9606             (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
9607                 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
9608                 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
9609                 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
9610                 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
9611                 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
9612                 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
9613                 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
9614                 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
9615                 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
9616                 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
9617                 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
9618                 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
9619                 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
9620                 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
9621                 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
9622                 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
9623                 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
9624                 asc_dvc->max_sdtr_index = 15;
9625                 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
9626                         AscSetExtraControl(iop_base,
9627                                            (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
9628                 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
9629                         AscSetExtraControl(iop_base,
9630                                            (SEC_ACTIVE_NEGATE |
9631                                             SEC_ENABLE_FILTER));
9632                 }
9633         }
9634         if (asc_dvc->bus_type == ASC_IS_PCI) {
9635                 AscSetExtraControl(iop_base,
9636                                    (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
9637         }
9638
9639         asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
9640 #ifdef CONFIG_ISA
9641         if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
9642                 if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
9643                         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
9644                         asc_dvc->bus_type = ASC_IS_ISAPNP;
9645                 }
9646                 asc_dvc->cfg->isa_dma_channel =
9647                     (uchar)AscGetIsaDmaChannel(iop_base);
9648         }
9649 #endif /* CONFIG_ISA */
9650         for (i = 0; i <= ASC_MAX_TID; i++) {
9651                 asc_dvc->cur_dvc_qng[i] = 0;
9652                 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
9653                 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
9654                 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
9655                 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
9656         }
9657         return (warn_code);
9658 }
9659
9660 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
9661 {
9662         ASCEEP_CONFIG eep_config_buf;
9663         ASCEEP_CONFIG *eep_config;
9664         PortAddr iop_base;
9665         ushort chksum;
9666         ushort warn_code;
9667         ushort cfg_msw, cfg_lsw;
9668         int i;
9669         int write_eep = 0;
9670
9671         iop_base = asc_dvc->iop_base;
9672         warn_code = 0;
9673         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
9674         AscStopQueueExe(iop_base);
9675         if ((AscStopChip(iop_base) == FALSE) ||
9676             (AscGetChipScsiCtrl(iop_base) != 0)) {
9677                 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
9678                 AscResetChipAndScsiBus(asc_dvc);
9679                 DvcSleepMilliSecond((ASC_DCNT)
9680                                     ((ushort)asc_dvc->scsi_reset_wait * 1000));
9681         }
9682         if (AscIsChipHalted(iop_base) == FALSE) {
9683                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
9684                 return (warn_code);
9685         }
9686         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
9687         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
9688                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
9689                 return (warn_code);
9690         }
9691         eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
9692         cfg_msw = AscGetChipCfgMsw(iop_base);
9693         cfg_lsw = AscGetChipCfgLsw(iop_base);
9694         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
9695                 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
9696                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
9697                 AscSetChipCfgMsw(iop_base, cfg_msw);
9698         }
9699         chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
9700         ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
9701         if (chksum == 0) {
9702                 chksum = 0xaa55;
9703         }
9704         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
9705                 warn_code |= ASC_WARN_AUTO_CONFIG;
9706                 if (asc_dvc->cfg->chip_version == 3) {
9707                         if (eep_config->cfg_lsw != cfg_lsw) {
9708                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
9709                                 eep_config->cfg_lsw =
9710                                     AscGetChipCfgLsw(iop_base);
9711                         }
9712                         if (eep_config->cfg_msw != cfg_msw) {
9713                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
9714                                 eep_config->cfg_msw =
9715                                     AscGetChipCfgMsw(iop_base);
9716                         }
9717                 }
9718         }
9719         eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
9720         eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
9721         ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
9722                  eep_config->chksum);
9723         if (chksum != eep_config->chksum) {
9724                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
9725                     ASC_CHIP_VER_PCI_ULTRA_3050) {
9726                         ASC_DBG(1,
9727                                 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
9728                         eep_config->init_sdtr = 0xFF;
9729                         eep_config->disc_enable = 0xFF;
9730                         eep_config->start_motor = 0xFF;
9731                         eep_config->use_cmd_qng = 0;
9732                         eep_config->max_total_qng = 0xF0;
9733                         eep_config->max_tag_qng = 0x20;
9734                         eep_config->cntl = 0xBFFF;
9735                         ASC_EEP_SET_CHIP_ID(eep_config, 7);
9736                         eep_config->no_scam = 0;
9737                         eep_config->adapter_info[0] = 0;
9738                         eep_config->adapter_info[1] = 0;
9739                         eep_config->adapter_info[2] = 0;
9740                         eep_config->adapter_info[3] = 0;
9741                         eep_config->adapter_info[4] = 0;
9742                         /* Indicate EEPROM-less board. */
9743                         eep_config->adapter_info[5] = 0xBB;
9744                 } else {
9745                         ASC_PRINT
9746                             ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
9747                         write_eep = 1;
9748                         warn_code |= ASC_WARN_EEPROM_CHKSUM;
9749                 }
9750         }
9751         asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
9752         asc_dvc->cfg->disc_enable = eep_config->disc_enable;
9753         asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
9754         asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
9755         asc_dvc->start_motor = eep_config->start_motor;
9756         asc_dvc->dvc_cntl = eep_config->cntl;
9757         asc_dvc->no_scam = eep_config->no_scam;
9758         asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
9759         asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
9760         asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
9761         asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
9762         asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
9763         asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
9764         if (!AscTestExternalLram(asc_dvc)) {
9765                 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
9766                      ASC_IS_PCI_ULTRA)) {
9767                         eep_config->max_total_qng =
9768                             ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
9769                         eep_config->max_tag_qng =
9770                             ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
9771                 } else {
9772                         eep_config->cfg_msw |= 0x0800;
9773                         cfg_msw |= 0x0800;
9774                         AscSetChipCfgMsw(iop_base, cfg_msw);
9775                         eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
9776                         eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
9777                 }
9778         } else {
9779         }
9780         if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
9781                 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
9782         }
9783         if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
9784                 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
9785         }
9786         if (eep_config->max_tag_qng > eep_config->max_total_qng) {
9787                 eep_config->max_tag_qng = eep_config->max_total_qng;
9788         }
9789         if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
9790                 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
9791         }
9792         asc_dvc->max_total_qng = eep_config->max_total_qng;
9793         if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
9794             eep_config->use_cmd_qng) {
9795                 eep_config->disc_enable = eep_config->use_cmd_qng;
9796                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
9797         }
9798         if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
9799                 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
9800         }
9801         ASC_EEP_SET_CHIP_ID(eep_config,
9802                             ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
9803         asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
9804         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
9805             !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
9806                 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
9807         }
9808
9809         for (i = 0; i <= ASC_MAX_TID; i++) {
9810                 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
9811                 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
9812                 asc_dvc->cfg->sdtr_period_offset[i] =
9813                     (uchar)(ASC_DEF_SDTR_OFFSET |
9814                             (asc_dvc->host_init_sdtr_index << 4));
9815         }
9816         eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
9817         if (write_eep) {
9818                 if ((i =
9819                      AscSetEEPConfig(iop_base, eep_config,
9820                                      asc_dvc->bus_type)) != 0) {
9821                         ASC_PRINT1
9822                             ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
9823                              i);
9824                 } else {
9825                         ASC_PRINT
9826                             ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
9827                 }
9828         }
9829         return (warn_code);
9830 }
9831
9832 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
9833 {
9834         int i;
9835         ushort warn_code;
9836         PortAddr iop_base;
9837         ASC_PADDR phy_addr;
9838         ASC_DCNT phy_size;
9839
9840         iop_base = asc_dvc->iop_base;
9841         warn_code = 0;
9842         for (i = 0; i <= ASC_MAX_TID; i++) {
9843                 AscPutMCodeInitSDTRAtID(iop_base, i,
9844                                         asc_dvc->cfg->sdtr_period_offset[i]
9845                     );
9846         }
9847
9848         AscInitQLinkVar(asc_dvc);
9849         AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
9850                          asc_dvc->cfg->disc_enable);
9851         AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
9852                          ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
9853
9854         /* Align overrun buffer on an 8 byte boundary. */
9855         phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
9856         phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
9857         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
9858                                  (uchar *)&phy_addr, 1);
9859         phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
9860         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
9861                                  (uchar *)&phy_size, 1);
9862
9863         asc_dvc->cfg->mcode_date =
9864             AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
9865         asc_dvc->cfg->mcode_version =
9866             AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
9867
9868         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
9869         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
9870                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
9871                 return (warn_code);
9872         }
9873         if (AscStartChip(iop_base) != 1) {
9874                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
9875                 return (warn_code);
9876         }
9877
9878         return (warn_code);
9879 }
9880
9881 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
9882 {
9883         PortAddr iop_base;
9884         ushort q_addr;
9885         ushort saved_word;
9886         int sta;
9887
9888         iop_base = asc_dvc->iop_base;
9889         sta = 0;
9890         q_addr = ASC_QNO_TO_QADDR(241);
9891         saved_word = AscReadLramWord(iop_base, q_addr);
9892         AscSetChipLramAddr(iop_base, q_addr);
9893         AscSetChipLramData(iop_base, 0x55AA);
9894         DvcSleepMilliSecond(10);
9895         AscSetChipLramAddr(iop_base, q_addr);
9896         if (AscGetChipLramData(iop_base) == 0x55AA) {
9897                 sta = 1;
9898                 AscWriteLramWord(iop_base, q_addr, saved_word);
9899         }
9900         return (sta);
9901 }
9902
9903 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
9904 {
9905         uchar read_back;
9906         int retry;
9907
9908         retry = 0;
9909         while (TRUE) {
9910                 AscSetChipEEPCmd(iop_base, cmd_reg);
9911                 DvcSleepMilliSecond(1);
9912                 read_back = AscGetChipEEPCmd(iop_base);
9913                 if (read_back == cmd_reg) {
9914                         return (1);
9915                 }
9916                 if (retry++ > ASC_EEP_MAX_RETRY) {
9917                         return (0);
9918                 }
9919         }
9920 }
9921
9922 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
9923 {
9924         ushort read_back;
9925         int retry;
9926
9927         retry = 0;
9928         while (TRUE) {
9929                 AscSetChipEEPData(iop_base, data_reg);
9930                 DvcSleepMilliSecond(1);
9931                 read_back = AscGetChipEEPData(iop_base);
9932                 if (read_back == data_reg) {
9933                         return (1);
9934                 }
9935                 if (retry++ > ASC_EEP_MAX_RETRY) {
9936                         return (0);
9937                 }
9938         }
9939 }
9940
9941 static void __devinit AscWaitEEPRead(void)
9942 {
9943         DvcSleepMilliSecond(1);
9944         return;
9945 }
9946
9947 static void __devinit AscWaitEEPWrite(void)
9948 {
9949         DvcSleepMilliSecond(20);
9950         return;
9951 }
9952
9953 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
9954 {
9955         ushort read_wval;
9956         uchar cmd_reg;
9957
9958         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9959         AscWaitEEPRead();
9960         cmd_reg = addr | ASC_EEP_CMD_READ;
9961         AscWriteEEPCmdReg(iop_base, cmd_reg);
9962         AscWaitEEPRead();
9963         read_wval = AscGetChipEEPData(iop_base);
9964         AscWaitEEPRead();
9965         return (read_wval);
9966 }
9967
9968 static ushort __devinit
9969 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
9970 {
9971         ushort read_wval;
9972
9973         read_wval = AscReadEEPWord(iop_base, addr);
9974         if (read_wval != word_val) {
9975                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
9976                 AscWaitEEPRead();
9977                 AscWriteEEPDataReg(iop_base, word_val);
9978                 AscWaitEEPRead();
9979                 AscWriteEEPCmdReg(iop_base,
9980                                   (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
9981                 AscWaitEEPWrite();
9982                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
9983                 AscWaitEEPRead();
9984                 return (AscReadEEPWord(iop_base, addr));
9985         }
9986         return (read_wval);
9987 }
9988
9989 static ushort __devinit
9990 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
9991 {
9992         ushort wval;
9993         ushort sum;
9994         ushort *wbuf;
9995         int cfg_beg;
9996         int cfg_end;
9997         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
9998         int s_addr;
9999
10000         wbuf = (ushort *)cfg_buf;
10001         sum = 0;
10002         /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10003         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10004                 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10005                 sum += *wbuf;
10006         }
10007         if (bus_type & ASC_IS_VL) {
10008                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10009                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10010         } else {
10011                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10012                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10013         }
10014         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10015                 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
10016                 if (s_addr <= uchar_end_in_config) {
10017                         /*
10018                          * Swap all char fields - must unswap bytes already swapped
10019                          * by AscReadEEPWord().
10020                          */
10021                         *wbuf = le16_to_cpu(wval);
10022                 } else {
10023                         /* Don't swap word field at the end - cntl field. */
10024                         *wbuf = wval;
10025                 }
10026                 sum += wval;    /* Checksum treats all EEPROM data as words. */
10027         }
10028         /*
10029          * Read the checksum word which will be compared against 'sum'
10030          * by the caller. Word field already swapped.
10031          */
10032         *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10033         return (sum);
10034 }
10035
10036 static int __devinit
10037 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10038 {
10039         int n_error;
10040         ushort *wbuf;
10041         ushort word;
10042         ushort sum;
10043         int s_addr;
10044         int cfg_beg;
10045         int cfg_end;
10046         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10047
10048         wbuf = (ushort *)cfg_buf;
10049         n_error = 0;
10050         sum = 0;
10051         /* Write two config words; AscWriteEEPWord() will swap bytes. */
10052         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10053                 sum += *wbuf;
10054                 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10055                         n_error++;
10056                 }
10057         }
10058         if (bus_type & ASC_IS_VL) {
10059                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10060                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10061         } else {
10062                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10063                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10064         }
10065         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10066                 if (s_addr <= uchar_end_in_config) {
10067                         /*
10068                          * This is a char field. Swap char fields before they are
10069                          * swapped again by AscWriteEEPWord().
10070                          */
10071                         word = cpu_to_le16(*wbuf);
10072                         if (word !=
10073                             AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
10074                                 n_error++;
10075                         }
10076                 } else {
10077                         /* Don't swap word field at the end - cntl field. */
10078                         if (*wbuf !=
10079                             AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
10080                                 n_error++;
10081                         }
10082                 }
10083                 sum += *wbuf;   /* Checksum calculated from word values. */
10084         }
10085         /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
10086         *wbuf = sum;
10087         if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
10088                 n_error++;
10089         }
10090
10091         /* Read EEPROM back again. */
10092         wbuf = (ushort *)cfg_buf;
10093         /*
10094          * Read two config words; Byte-swapping done by AscReadEEPWord().
10095          */
10096         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10097                 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
10098                         n_error++;
10099                 }
10100         }
10101         if (bus_type & ASC_IS_VL) {
10102                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10103                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10104         } else {
10105                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
10106                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
10107         }
10108         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
10109                 if (s_addr <= uchar_end_in_config) {
10110                         /*
10111                          * Swap all char fields. Must unswap bytes already swapped
10112                          * by AscReadEEPWord().
10113                          */
10114                         word =
10115                             le16_to_cpu(AscReadEEPWord
10116                                         (iop_base, (uchar)s_addr));
10117                 } else {
10118                         /* Don't swap word field at the end - cntl field. */
10119                         word = AscReadEEPWord(iop_base, (uchar)s_addr);
10120                 }
10121                 if (*wbuf != word) {
10122                         n_error++;
10123                 }
10124         }
10125         /* Read checksum; Byte swapping not needed. */
10126         if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
10127                 n_error++;
10128         }
10129         return (n_error);
10130 }
10131
10132 static int __devinit
10133 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10134 {
10135         int retry;
10136         int n_error;
10137
10138         retry = 0;
10139         while (TRUE) {
10140                 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
10141                                                    bus_type)) == 0) {
10142                         break;
10143                 }
10144                 if (++retry > ASC_EEP_MAX_RETRY) {
10145                         break;
10146                 }
10147         }
10148         return (n_error);
10149 }
10150
10151 static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
10152 {
10153         char type = sdev->type;
10154         ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
10155
10156         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
10157                 if (!(asc_dvc->init_sdtr & tid_bits)) {
10158                         if ((type == TYPE_ROM) &&
10159                             (strncmp(sdev->vendor, "HP ", 3) == 0)) {
10160                                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
10161                         }
10162                         asc_dvc->pci_fix_asyn_xfer |= tid_bits;
10163                         if ((type == TYPE_PROCESSOR) ||
10164                             (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
10165                             (type == TYPE_TAPE)) {
10166                                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
10167                         }
10168
10169                         if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
10170                                 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
10171                                         sdev->id,
10172                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
10173                         }
10174                 }
10175         }
10176 }
10177
10178 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
10179 {
10180         uchar byte_data;
10181         ushort word_data;
10182
10183         if (isodd_word(addr)) {
10184                 AscSetChipLramAddr(iop_base, addr - 1);
10185                 word_data = AscGetChipLramData(iop_base);
10186                 byte_data = (uchar)((word_data >> 8) & 0xFF);
10187         } else {
10188                 AscSetChipLramAddr(iop_base, addr);
10189                 word_data = AscGetChipLramData(iop_base);
10190                 byte_data = (uchar)(word_data & 0xFF);
10191         }
10192         return (byte_data);
10193 }
10194
10195 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
10196 {
10197         ushort word_data;
10198
10199         AscSetChipLramAddr(iop_base, addr);
10200         word_data = AscGetChipLramData(iop_base);
10201         return (word_data);
10202 }
10203
10204 #if CC_VERY_LONG_SG_LIST
10205 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
10206 {
10207         ushort val_low, val_high;
10208         ASC_DCNT dword_data;
10209
10210         AscSetChipLramAddr(iop_base, addr);
10211         val_low = AscGetChipLramData(iop_base);
10212         val_high = AscGetChipLramData(iop_base);
10213         dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
10214         return (dword_data);
10215 }
10216 #endif /* CC_VERY_LONG_SG_LIST */
10217
10218 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
10219 {
10220         AscSetChipLramAddr(iop_base, addr);
10221         AscSetChipLramData(iop_base, word_val);
10222         return;
10223 }
10224
10225 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
10226 {
10227         ushort word_data;
10228
10229         if (isodd_word(addr)) {
10230                 addr--;
10231                 word_data = AscReadLramWord(iop_base, addr);
10232                 word_data &= 0x00FF;
10233                 word_data |= (((ushort)byte_val << 8) & 0xFF00);
10234         } else {
10235                 word_data = AscReadLramWord(iop_base, addr);
10236                 word_data &= 0xFF00;
10237                 word_data |= ((ushort)byte_val & 0x00FF);
10238         }
10239         AscWriteLramWord(iop_base, addr, word_data);
10240         return;
10241 }
10242
10243 /*
10244  * Copy 2 bytes to LRAM.
10245  *
10246  * The source data is assumed to be in little-endian order in memory
10247  * and is maintained in little-endian order when written to LRAM.
10248  */
10249 static void
10250 AscMemWordCopyPtrToLram(PortAddr iop_base,
10251                         ushort s_addr, uchar *s_buffer, int words)
10252 {
10253         int i;
10254
10255         AscSetChipLramAddr(iop_base, s_addr);
10256         for (i = 0; i < 2 * words; i += 2) {
10257                 /*
10258                  * On a little-endian system the second argument below
10259                  * produces a little-endian ushort which is written to
10260                  * LRAM in little-endian order. On a big-endian system
10261                  * the second argument produces a big-endian ushort which
10262                  * is "transparently" byte-swapped by outpw() and written
10263                  * in little-endian order to LRAM.
10264                  */
10265                 outpw(iop_base + IOP_RAM_DATA,
10266                       ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
10267         }
10268         return;
10269 }
10270
10271 /*
10272  * Copy 4 bytes to LRAM.
10273  *
10274  * The source data is assumed to be in little-endian order in memory
10275  * and is maintained in little-endian order when writen to LRAM.
10276  */
10277 static void
10278 AscMemDWordCopyPtrToLram(PortAddr iop_base,
10279                          ushort s_addr, uchar *s_buffer, int dwords)
10280 {
10281         int i;
10282
10283         AscSetChipLramAddr(iop_base, s_addr);
10284         for (i = 0; i < 4 * dwords; i += 4) {
10285                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);   /* LSW */
10286                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);       /* MSW */
10287         }
10288         return;
10289 }
10290
10291 /*
10292  * Copy 2 bytes from LRAM.
10293  *
10294  * The source data is assumed to be in little-endian order in LRAM
10295  * and is maintained in little-endian order when written to memory.
10296  */
10297 static void
10298 AscMemWordCopyPtrFromLram(PortAddr iop_base,
10299                           ushort s_addr, uchar *d_buffer, int words)
10300 {
10301         int i;
10302         ushort word;
10303
10304         AscSetChipLramAddr(iop_base, s_addr);
10305         for (i = 0; i < 2 * words; i += 2) {
10306                 word = inpw(iop_base + IOP_RAM_DATA);
10307                 d_buffer[i] = word & 0xff;
10308                 d_buffer[i + 1] = (word >> 8) & 0xff;
10309         }
10310         return;
10311 }
10312
10313 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
10314 {
10315         ASC_DCNT sum;
10316         int i;
10317
10318         sum = 0L;
10319         for (i = 0; i < words; i++, s_addr += 2) {
10320                 sum += AscReadLramWord(iop_base, s_addr);
10321         }
10322         return (sum);
10323 }
10324
10325 static void
10326 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
10327 {
10328         int i;
10329
10330         AscSetChipLramAddr(iop_base, s_addr);
10331         for (i = 0; i < words; i++) {
10332                 AscSetChipLramData(iop_base, set_wval);
10333         }
10334         return;
10335 }
10336
10337 /*
10338  * --- Adv Library Functions
10339  */
10340
10341 /* a_mcode.h */
10342
10343 /* Microcode buffer is kept after initialization for error recovery. */
10344 static unsigned char _adv_asc3550_buf[] = {
10345         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
10346         0x01, 0x00, 0x48, 0xe4,
10347         0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
10348         0x28, 0x0e, 0x9e, 0xe7,
10349         0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
10350         0x55, 0xf0, 0x01, 0xf6,
10351         0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
10352         0x00, 0xec, 0x85, 0xf0,
10353         0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
10354         0x86, 0xf0, 0xb4, 0x00,
10355         0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
10356         0xaa, 0x18, 0x02, 0x80,
10357         0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
10358         0x00, 0x57, 0x01, 0xea,
10359         0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
10360         0x03, 0xe6, 0xb6, 0x00,
10361         0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
10362         0x02, 0x4a, 0xb9, 0x54,
10363         0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
10364         0x3e, 0x00, 0x80, 0x00,
10365         0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
10366         0x74, 0x01, 0x76, 0x01,
10367         0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
10368         0x4c, 0x1c, 0xbb, 0x55,
10369         0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
10370         0x03, 0xf7, 0x06, 0xf7,
10371         0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
10372         0x30, 0x13, 0x64, 0x15,
10373         0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
10374         0x04, 0xea, 0x5d, 0xf0,
10375         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
10376         0xcc, 0x00, 0x20, 0x01,
10377         0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
10378         0x40, 0x13, 0x30, 0x1c,
10379         0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
10380         0x59, 0xf0, 0xa7, 0xf0,
10381         0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
10382         0xa4, 0x00, 0xb5, 0x00,
10383         0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
10384         0x14, 0x0e, 0x02, 0x10,
10385         0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
10386         0x10, 0x15, 0x14, 0x15,
10387         0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
10388         0x91, 0x44, 0x0a, 0x45,
10389         0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
10390         0x83, 0x59, 0x05, 0xe6,
10391         0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
10392         0x02, 0xfa, 0x03, 0xfa,
10393         0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
10394         0x9e, 0x00, 0xa8, 0x00,
10395         0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
10396         0x7a, 0x01, 0xc0, 0x01,
10397         0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
10398         0x69, 0x08, 0xba, 0x08,
10399         0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
10400         0xf1, 0x10, 0x06, 0x12,
10401         0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
10402         0x8a, 0x15, 0xc6, 0x17,
10403         0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
10404         0x0e, 0x47, 0x48, 0x47,
10405         0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
10406         0x14, 0x56, 0x77, 0x57,
10407         0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
10408         0xf0, 0x29, 0x02, 0xfe,
10409         0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
10410         0xfe, 0x80, 0x01, 0xff,
10411         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
10412         0x00, 0xfe, 0x57, 0x24,
10413         0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
10414         0x00, 0x00, 0xff, 0x08,
10415         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
10416         0xff, 0xff, 0xff, 0x0f,
10417         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
10418         0xfe, 0x04, 0xf7, 0xcf,
10419         0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
10420         0x0b, 0x3c, 0x2a, 0xfe,
10421         0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
10422         0xfe, 0xf0, 0x01, 0xfe,
10423         0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
10424         0x02, 0xfe, 0xd4, 0x0c,
10425         0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
10426         0x1c, 0x05, 0xfe, 0xa6,
10427         0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
10428         0xf0, 0xfe, 0x86, 0x02,
10429         0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
10430         0xfe, 0x46, 0xf0, 0xfe,
10431         0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
10432         0x44, 0x02, 0xfe, 0x44,
10433         0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
10434         0xa0, 0x17, 0x06, 0x18,
10435         0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
10436         0x1e, 0x1c, 0xfe, 0xe9,
10437         0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
10438         0x0a, 0x6b, 0x01, 0x9e,
10439         0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
10440         0x01, 0x82, 0xfe, 0xbd,
10441         0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
10442         0x58, 0x1c, 0x17, 0x06,
10443         0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
10444         0xfe, 0x94, 0x02, 0xfe,
10445         0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
10446         0x01, 0xfe, 0x54, 0x0f,
10447         0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
10448         0x69, 0x10, 0x17, 0x06,
10449         0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
10450         0xf6, 0xc7, 0x01, 0xfe,
10451         0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
10452         0x02, 0x29, 0x0a, 0x40,
10453         0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
10454         0x58, 0x0a, 0x99, 0x01,
10455         0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
10456         0x2a, 0x46, 0xfe, 0x02,
10457         0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
10458         0x01, 0xfe, 0x07, 0x4b,
10459         0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
10460         0xfe, 0x56, 0x03, 0xfe,
10461         0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
10462         0xfe, 0x9f, 0xf0, 0xfe,
10463         0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
10464         0x1c, 0xeb, 0x09, 0x04,
10465         0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
10466         0x01, 0x0e, 0xac, 0x75,
10467         0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
10468         0xfe, 0x82, 0xf0, 0xfe,
10469         0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
10470         0x32, 0x1f, 0xfe, 0xb4,
10471         0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
10472         0x0a, 0xf0, 0xfe, 0x7a,
10473         0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
10474         0x01, 0x33, 0x8f, 0xfe,
10475         0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
10476         0xf7, 0xfe, 0x48, 0x1c,
10477         0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
10478         0x0a, 0xca, 0x01, 0x0e,
10479         0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
10480         0x2c, 0x01, 0x33, 0x8f,
10481         0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
10482         0xfe, 0x3c, 0x04, 0x1f,
10483         0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
10484         0x12, 0x2b, 0xff, 0x02,
10485         0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
10486         0x22, 0x30, 0x2e, 0xd5,
10487         0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
10488         0xfe, 0x4c, 0x54, 0x64,
10489         0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
10490         0xfe, 0x2a, 0x13, 0x2f,
10491         0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
10492         0xd3, 0xfa, 0xef, 0x86,
10493         0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
10494         0x1d, 0xfe, 0x1c, 0x12,
10495         0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
10496         0x70, 0x0c, 0x02, 0x22,
10497         0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
10498         0x01, 0x33, 0x02, 0x29,
10499         0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
10500         0x80, 0xfe, 0x31, 0xe4,
10501         0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
10502         0xfe, 0x70, 0x12, 0x49,
10503         0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
10504         0x80, 0x05, 0xfe, 0x31,
10505         0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
10506         0x28, 0xfe, 0x42, 0x12,
10507         0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
10508         0x11, 0xfe, 0xe3, 0x00,
10509         0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
10510         0x64, 0x05, 0x83, 0x24,
10511         0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
10512         0x09, 0x48, 0x01, 0x08,
10513         0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
10514         0x86, 0x24, 0x06, 0x12,
10515         0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
10516         0x01, 0xa7, 0x14, 0x92,
10517         0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
10518         0x02, 0x22, 0x05, 0xfe,
10519         0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
10520         0x47, 0x01, 0xa7, 0x26,
10521         0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
10522         0x01, 0xfe, 0xaa, 0x14,
10523         0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
10524         0x05, 0x50, 0xb4, 0x0c,
10525         0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
10526         0x13, 0x01, 0xfe, 0x14,
10527         0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
10528         0xff, 0x02, 0x00, 0x57,
10529         0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
10530         0x72, 0x06, 0x49, 0x04,
10531         0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
10532         0x06, 0x11, 0x9a, 0x01,
10533         0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
10534         0x01, 0xa7, 0xec, 0x72,
10535         0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
10536         0xfe, 0x0a, 0xf0, 0xfe,
10537         0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
10538         0x8d, 0x81, 0x02, 0x22,
10539         0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
10540         0x01, 0x08, 0x15, 0x00,
10541         0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
10542         0x00, 0x02, 0xfe, 0x32,
10543         0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
10544         0xfe, 0x1b, 0x00, 0x01,
10545         0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
10546         0x08, 0x15, 0x06, 0x01,
10547         0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
10548         0x9a, 0x81, 0x4b, 0x1d,
10549         0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
10550         0x45, 0xfe, 0x32, 0x12,
10551         0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
10552         0xfe, 0x32, 0x07, 0x8d,
10553         0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
10554         0x06, 0x15, 0x19, 0x02,
10555         0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
10556         0x90, 0x77, 0xfe, 0xca,
10557         0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
10558         0x10, 0xfe, 0x0e, 0x12,
10559         0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
10560         0x83, 0xe7, 0xc4, 0xa1,
10561         0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
10562         0x40, 0x12, 0x58, 0x01,
10563         0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
10564         0x51, 0x83, 0xfb, 0xfe,
10565         0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
10566         0xfe, 0x40, 0x50, 0xfe,
10567         0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
10568         0xfe, 0x2a, 0x12, 0xfe,
10569         0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
10570         0x85, 0x01, 0xa8, 0xfe,
10571         0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
10572         0x18, 0x57, 0xfb, 0xfe,
10573         0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
10574         0x0c, 0x39, 0x18, 0x3a,
10575         0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
10576         0x11, 0x65, 0xfe, 0x48,
10577         0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
10578         0xdd, 0xb8, 0xfe, 0x80,
10579         0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
10580         0xfe, 0x7a, 0x08, 0x8d,
10581         0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
10582         0x10, 0x61, 0x04, 0x06,
10583         0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
10584         0x12, 0xfe, 0x2e, 0x1c,
10585         0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
10586         0x52, 0x12, 0xfe, 0x2c,
10587         0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
10588         0x08, 0xfe, 0x8a, 0x10,
10589         0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
10590         0x24, 0x0a, 0xab, 0xfe,
10591         0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
10592         0x1c, 0x12, 0xb5, 0xfe,
10593         0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
10594         0x1c, 0x06, 0x16, 0x9d,
10595         0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
10596         0x14, 0x92, 0x01, 0x33,
10597         0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
10598         0xfe, 0x74, 0x18, 0x1c,
10599         0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
10600         0x01, 0xe6, 0x1e, 0x27,
10601         0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
10602         0x09, 0x04, 0x6a, 0xfe,
10603         0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
10604         0xfe, 0x83, 0x80, 0xfe,
10605         0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
10606         0x27, 0xfe, 0x40, 0x59,
10607         0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
10608         0x7c, 0xbe, 0x54, 0xbf,
10609         0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
10610         0x79, 0x56, 0x68, 0x57,
10611         0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
10612         0xa2, 0x23, 0x0c, 0x7b,
10613         0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
10614         0x16, 0xd7, 0x79, 0x39,
10615         0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
10616         0xfe, 0x10, 0x58, 0xfe,
10617         0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
10618         0x19, 0x16, 0xd7, 0x09,
10619         0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
10620         0xfe, 0x10, 0x90, 0xfe,
10621         0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
10622         0x11, 0x9b, 0x09, 0x04,
10623         0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
10624         0xfe, 0x0c, 0x58, 0xfe,
10625         0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
10626         0x0b, 0xfe, 0x1a, 0x12,
10627         0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
10628         0x14, 0x7a, 0x01, 0x33,
10629         0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
10630         0xfe, 0xed, 0x19, 0xbf,
10631         0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
10632         0x34, 0xfe, 0x74, 0x10,
10633         0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
10634         0x84, 0x05, 0xcb, 0x1c,
10635         0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
10636         0xf0, 0xfe, 0xc4, 0x0a,
10637         0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
10638         0xce, 0xf0, 0xfe, 0xca,
10639         0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
10640         0x22, 0x00, 0x02, 0x5a,
10641         0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
10642         0xfe, 0xd0, 0xf0, 0xfe,
10643         0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
10644         0x4c, 0xfe, 0x10, 0x10,
10645         0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
10646         0x2a, 0x13, 0xfe, 0x4e,
10647         0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
10648         0x16, 0x32, 0x2a, 0x73,
10649         0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
10650         0x32, 0x8c, 0xfe, 0x48,
10651         0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
10652         0xdb, 0x10, 0x11, 0xfe,
10653         0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
10654         0x22, 0x30, 0x2e, 0xd8,
10655         0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
10656         0x45, 0x0f, 0xfe, 0x42,
10657         0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
10658         0x09, 0x04, 0x0b, 0xfe,
10659         0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
10660         0x00, 0x21, 0xfe, 0xa6,
10661         0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
10662         0xfe, 0xe2, 0x10, 0x01,
10663         0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
10664         0x01, 0x6f, 0x02, 0x29,
10665         0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
10666         0x01, 0x86, 0x3e, 0x0b,
10667         0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
10668         0x3e, 0x0b, 0x0f, 0xfe,
10669         0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
10670         0xe8, 0x59, 0x11, 0x2d,
10671         0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
10672         0x04, 0x0b, 0x84, 0x3e,
10673         0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
10674         0x09, 0x04, 0x1b, 0xfe,
10675         0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
10676         0x1c, 0x1c, 0xfe, 0x9d,
10677         0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
10678         0xfe, 0x15, 0x00, 0xfe,
10679         0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
10680         0x0f, 0xfe, 0x47, 0x00,
10681         0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
10682         0xab, 0x70, 0x05, 0x6b,
10683         0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
10684         0x1c, 0x42, 0x59, 0x01,
10685         0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
10686         0x00, 0x37, 0x97, 0x01,
10687         0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
10688         0x1d, 0xfe, 0xce, 0x45,
10689         0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
10690         0x57, 0x05, 0x51, 0xfe,
10691         0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
10692         0x46, 0x09, 0x04, 0x1d,
10693         0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
10694         0x99, 0x01, 0x0e, 0xfe,
10695         0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
10696         0xfe, 0xee, 0x14, 0xee,
10697         0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
10698         0x13, 0x02, 0x29, 0x1e,
10699         0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
10700         0xce, 0x1e, 0x2d, 0x47,
10701         0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
10702         0x12, 0x4d, 0x01, 0xfe,
10703         0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
10704         0xf0, 0x0d, 0xfe, 0x02,
10705         0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
10706         0xf6, 0xfe, 0x34, 0x01,
10707         0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
10708         0xaf, 0xfe, 0x02, 0xea,
10709         0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
10710         0x05, 0xfe, 0x38, 0x01,
10711         0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
10712         0x0c, 0xfe, 0x62, 0x01,
10713         0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
10714         0x03, 0x23, 0x03, 0x1e,
10715         0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
10716         0x71, 0x13, 0xfe, 0x24,
10717         0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
10718         0xdc, 0xfe, 0x73, 0x57,
10719         0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
10720         0x80, 0x5d, 0x03, 0xfe,
10721         0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
10722         0x75, 0x03, 0x09, 0x04,
10723         0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
10724         0xfe, 0x1e, 0x80, 0xe1,
10725         0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
10726         0x90, 0xa3, 0xfe, 0x3c,
10727         0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
10728         0x16, 0x2f, 0x07, 0x2d,
10729         0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
10730         0xe8, 0x11, 0xfe, 0xe9,
10731         0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
10732         0x1e, 0x1c, 0xfe, 0x14,
10733         0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
10734         0x09, 0x04, 0x4f, 0xfe,
10735         0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
10736         0x40, 0x12, 0x20, 0x63,
10737         0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
10738         0x1c, 0x05, 0xfe, 0xac,
10739         0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
10740         0xfe, 0xb0, 0x00, 0xfe,
10741         0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
10742         0x24, 0x69, 0x12, 0xc9,
10743         0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
10744         0x90, 0x4d, 0xfe, 0x91,
10745         0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
10746         0xfe, 0x90, 0x4d, 0xfe,
10747         0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
10748         0x46, 0x1e, 0x20, 0xed,
10749         0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
10750         0x70, 0xfe, 0x14, 0x1c,
10751         0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
10752         0xfe, 0x07, 0xe6, 0x1d,
10753         0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
10754         0xfa, 0xef, 0xfe, 0x42,
10755         0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
10756         0xfe, 0x36, 0x12, 0xf0,
10757         0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
10758         0x3d, 0x75, 0x07, 0x10,
10759         0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
10760         0x10, 0x07, 0x7e, 0x45,
10761         0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
10762         0xfe, 0x01, 0xec, 0x97,
10763         0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
10764         0x27, 0x01, 0xda, 0xfe,
10765         0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
10766         0xfe, 0x48, 0x12, 0x07,
10767         0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
10768         0xfe, 0x3e, 0x11, 0x07,
10769         0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
10770         0x11, 0x07, 0x19, 0xfe,
10771         0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
10772         0x01, 0x08, 0x8c, 0x43,
10773         0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
10774         0x7e, 0x02, 0x29, 0x2b,
10775         0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
10776         0xfc, 0x10, 0x09, 0x04,
10777         0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
10778         0xc6, 0x10, 0x1e, 0x58,
10779         0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
10780         0x54, 0x18, 0x55, 0x23,
10781         0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
10782         0xa5, 0xc0, 0x38, 0xc1,
10783         0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
10784         0x05, 0xfa, 0x4e, 0xfe,
10785         0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
10786         0x0c, 0x56, 0x18, 0x57,
10787         0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
10788         0x00, 0x56, 0xfe, 0xa1,
10789         0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
10790         0x58, 0xfe, 0x1f, 0x40,
10791         0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
10792         0x31, 0x57, 0xfe, 0x44,
10793         0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
10794         0x8a, 0x50, 0x05, 0x39,
10795         0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
10796         0x12, 0xcd, 0x02, 0x5b,
10797         0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
10798         0x2f, 0x07, 0x9b, 0x21,
10799         0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
10800         0x39, 0x68, 0x3a, 0xfe,
10801         0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
10802         0x51, 0xfe, 0x8e, 0x51,
10803         0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
10804         0x01, 0x08, 0x25, 0x32,
10805         0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
10806         0x3b, 0x02, 0x44, 0x01,
10807         0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
10808         0x01, 0x08, 0x1f, 0xa2,
10809         0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
10810         0x00, 0x28, 0x84, 0x49,
10811         0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
10812         0x78, 0x3d, 0xfe, 0xda,
10813         0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
10814         0x05, 0xc6, 0x28, 0x84,
10815         0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
10816         0x14, 0xfe, 0x03, 0x17,
10817         0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
10818         0xfe, 0xaa, 0x14, 0x02,
10819         0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
10820         0x21, 0x44, 0x01, 0xfe,
10821         0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
10822         0xfe, 0x4a, 0xf4, 0x0b,
10823         0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
10824         0x85, 0x02, 0x5b, 0x05,
10825         0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
10826         0xd8, 0x14, 0x02, 0x5c,
10827         0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
10828         0x01, 0x08, 0x23, 0x72,
10829         0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
10830         0x12, 0x5e, 0x2b, 0x01,
10831         0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
10832         0x1c, 0xfe, 0xff, 0x7f,
10833         0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
10834         0x57, 0x48, 0x8b, 0x1c,
10835         0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
10836         0x00, 0x57, 0x48, 0x8b,
10837         0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
10838         0x03, 0x0a, 0x50, 0x01,
10839         0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
10840         0x54, 0xfe, 0x00, 0xf4,
10841         0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
10842         0x03, 0x7c, 0x63, 0x27,
10843         0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
10844         0xfe, 0x82, 0x4a, 0xfe,
10845         0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
10846         0x42, 0x48, 0x5f, 0x60,
10847         0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
10848         0x1f, 0xfe, 0xa2, 0x14,
10849         0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
10850         0xcc, 0x12, 0x49, 0x04,
10851         0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
10852         0xe8, 0x13, 0x3b, 0x13,
10853         0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
10854         0xa1, 0xff, 0x02, 0x83,
10855         0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
10856         0x13, 0x06, 0xfe, 0x56,
10857         0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
10858         0x64, 0x00, 0x17, 0x93,
10859         0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
10860         0xc8, 0x00, 0x8e, 0xe4,
10861         0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
10862         0x01, 0xba, 0xfe, 0x4e,
10863         0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
10864         0xfe, 0x60, 0x14, 0xfe,
10865         0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
10866         0xfe, 0x22, 0x13, 0x1c,
10867         0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
10868         0xfe, 0x9c, 0x14, 0xb7,
10869         0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
10870         0xfe, 0x9c, 0x14, 0xb7,
10871         0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
10872         0xfe, 0xb4, 0x56, 0xfe,
10873         0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
10874         0xe5, 0x15, 0x0b, 0x01,
10875         0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
10876         0x49, 0x01, 0x08, 0x03,
10877         0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
10878         0x15, 0x06, 0x01, 0x08,
10879         0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
10880         0x4a, 0x01, 0x08, 0x03,
10881         0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
10882         0xfe, 0x49, 0xf4, 0x00,
10883         0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
10884         0x08, 0x2f, 0x07, 0xfe,
10885         0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
10886         0x01, 0x43, 0x1e, 0xcd,
10887         0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
10888         0xed, 0x88, 0x07, 0x10,
10889         0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
10890         0x80, 0x01, 0x0e, 0x88,
10891         0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
10892         0x88, 0x03, 0x0a, 0x42,
10893         0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
10894         0xfe, 0x80, 0x80, 0xf2,
10895         0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
10896         0x01, 0x82, 0x03, 0x17,
10897         0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
10898         0xfe, 0x24, 0x1c, 0xfe,
10899         0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
10900         0x91, 0x1d, 0x66, 0xfe,
10901         0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
10902         0xda, 0x10, 0x17, 0x10,
10903         0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
10904         0x05, 0xfe, 0x66, 0x01,
10905         0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
10906         0xfe, 0x3c, 0x50, 0x66,
10907         0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
10908         0x40, 0x16, 0xfe, 0xb6,
10909         0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
10910         0x10, 0x71, 0xfe, 0x83,
10911         0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
10912         0xfe, 0x62, 0x16, 0xfe,
10913         0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
10914         0xfe, 0x98, 0xe7, 0x00,
10915         0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
10916         0xfe, 0x30, 0xbc, 0xfe,
10917         0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
10918         0xc5, 0x90, 0xfe, 0x9a,
10919         0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
10920         0x42, 0x10, 0xfe, 0x02,
10921         0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
10922         0xfe, 0x1d, 0xf7, 0x4f,
10923         0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
10924         0x47, 0xfe, 0x83, 0x58,
10925         0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
10926         0xfe, 0xdd, 0x00, 0x63,
10927         0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
10928         0x06, 0x37, 0x95, 0xa9,
10929         0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
10930         0x18, 0x1c, 0x1a, 0x5d,
10931         0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
10932         0xe1, 0x10, 0x78, 0x2c,
10933         0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
10934         0x13, 0x3c, 0x8a, 0x0a,
10935         0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
10936         0xe3, 0xfe, 0x00, 0xcc,
10937         0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
10938         0x0e, 0xf2, 0x01, 0x6f,
10939         0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
10940         0xf6, 0xfe, 0xd6, 0xf0,
10941         0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
10942         0x15, 0x00, 0x59, 0x76,
10943         0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
10944         0x11, 0x2d, 0x01, 0x6f,
10945         0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
10946         0xc8, 0xfe, 0x48, 0x55,
10947         0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
10948         0x99, 0x01, 0x0e, 0xf0,
10949         0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
10950         0x75, 0x03, 0x0a, 0x42,
10951         0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
10952         0x0e, 0x73, 0x75, 0x03,
10953         0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
10954         0xfe, 0x3a, 0x45, 0x5b,
10955         0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
10956         0xfe, 0x02, 0xe6, 0x1b,
10957         0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
10958         0xfe, 0x94, 0x00, 0xfe,
10959         0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
10960         0xe6, 0x2c, 0xfe, 0x4e,
10961         0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
10962         0x03, 0x07, 0x7a, 0xfe,
10963         0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
10964         0x07, 0x1b, 0xfe, 0x5a,
10965         0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
10966         0x24, 0x2c, 0xdc, 0x07,
10967         0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
10968         0x9f, 0xad, 0x03, 0x14,
10969         0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
10970         0x03, 0x25, 0xfe, 0xca,
10971         0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
10972         0x00, 0x00,
10973 };
10974
10975 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf);     /* 0x13AD */
10976 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL;     /* Expanded little-endian checksum. */
10977
10978 /* Microcode buffer is kept after initialization for error recovery. */
10979 static unsigned char _adv_asc38C0800_buf[] = {
10980         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
10981         0x01, 0x00, 0x48, 0xe4,
10982         0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
10983         0x1c, 0x0f, 0x00, 0xf6,
10984         0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
10985         0x09, 0xe7, 0x55, 0xf0,
10986         0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
10987         0x18, 0xf4, 0x08, 0x00,
10988         0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
10989         0x86, 0xf0, 0xb1, 0xf0,
10990         0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
10991         0x3c, 0x00, 0xbb, 0x00,
10992         0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
10993         0xba, 0x13, 0x18, 0x40,
10994         0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
10995         0x6e, 0x01, 0x74, 0x01,
10996         0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
10997         0xc0, 0x00, 0x01, 0x01,
10998         0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
10999         0x08, 0x12, 0x02, 0x4a,
11000         0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
11001         0x5d, 0xf0, 0x02, 0xfa,
11002         0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
11003         0x68, 0x01, 0x6a, 0x01,
11004         0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
11005         0x06, 0x13, 0x4c, 0x1c,
11006         0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
11007         0x0f, 0x00, 0x47, 0x00,
11008         0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
11009         0x4e, 0x1c, 0x10, 0x44,
11010         0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
11011         0x05, 0x00, 0x34, 0x00,
11012         0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
11013         0x42, 0x0c, 0x12, 0x0f,
11014         0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
11015         0x00, 0x4e, 0x42, 0x54,
11016         0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11017         0x59, 0xf0, 0xb8, 0xf0,
11018         0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
11019         0x19, 0x00, 0x33, 0x00,
11020         0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
11021         0xe7, 0x00, 0xe2, 0x03,
11022         0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
11023         0x12, 0x13, 0x24, 0x14,
11024         0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
11025         0x36, 0x1c, 0x08, 0x44,
11026         0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
11027         0x3a, 0x55, 0x83, 0x55,
11028         0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
11029         0x0c, 0xf0, 0x04, 0xf8,
11030         0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
11031         0xa8, 0x00, 0xaa, 0x00,
11032         0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
11033         0xc4, 0x01, 0xc6, 0x01,
11034         0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
11035         0x68, 0x08, 0x69, 0x08,
11036         0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
11037         0xed, 0x10, 0xf1, 0x10,
11038         0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
11039         0x1e, 0x13, 0x46, 0x14,
11040         0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
11041         0xca, 0x18, 0xe6, 0x19,
11042         0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
11043         0xf0, 0x2b, 0x02, 0xfe,
11044         0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
11045         0xfe, 0x84, 0x01, 0xff,
11046         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11047         0x00, 0xfe, 0x57, 0x24,
11048         0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
11049         0x00, 0x00, 0xff, 0x08,
11050         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11051         0xff, 0xff, 0xff, 0x11,
11052         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11053         0xfe, 0x04, 0xf7, 0xd6,
11054         0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
11055         0x0a, 0x42, 0x2c, 0xfe,
11056         0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
11057         0xfe, 0xf4, 0x01, 0xfe,
11058         0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
11059         0x02, 0xfe, 0xc8, 0x0d,
11060         0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11061         0x1c, 0x03, 0xfe, 0xa6,
11062         0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
11063         0xf0, 0xfe, 0x8a, 0x02,
11064         0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
11065         0xfe, 0x46, 0xf0, 0xfe,
11066         0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11067         0x48, 0x02, 0xfe, 0x44,
11068         0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
11069         0xaa, 0x18, 0x06, 0x14,
11070         0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
11071         0x1e, 0x1c, 0xfe, 0xe9,
11072         0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
11073         0x09, 0x70, 0x01, 0xa8,
11074         0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
11075         0x01, 0x87, 0xfe, 0xbd,
11076         0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11077         0x58, 0x1c, 0x18, 0x06,
11078         0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
11079         0xfe, 0x98, 0x02, 0xfe,
11080         0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
11081         0x01, 0xfe, 0x48, 0x10,
11082         0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
11083         0x69, 0x10, 0x18, 0x06,
11084         0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
11085         0xf6, 0xce, 0x01, 0xfe,
11086         0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
11087         0x82, 0x16, 0x02, 0x2b,
11088         0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
11089         0xfe, 0x41, 0x58, 0x09,
11090         0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
11091         0x82, 0x16, 0x02, 0x2b,
11092         0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
11093         0xfe, 0x77, 0x57, 0xfe,
11094         0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
11095         0xfe, 0x40, 0x1c, 0x1c,
11096         0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
11097         0x03, 0xfe, 0x11, 0xf0,
11098         0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
11099         0xfe, 0x11, 0x00, 0x02,
11100         0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
11101         0x21, 0x22, 0xa3, 0xb7,
11102         0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
11103         0x12, 0xd1, 0x1c, 0xd9,
11104         0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
11105         0xfe, 0xe4, 0x00, 0x27,
11106         0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
11107         0x06, 0xf0, 0xfe, 0xc8,
11108         0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
11109         0x70, 0x28, 0x17, 0xfe,
11110         0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
11111         0xf9, 0x2c, 0x99, 0x19,
11112         0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
11113         0x74, 0x01, 0xaf, 0x8c,
11114         0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
11115         0x8d, 0x51, 0x64, 0x79,
11116         0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
11117         0xfe, 0x6a, 0x02, 0x02,
11118         0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
11119         0xfe, 0x3c, 0x04, 0x3b,
11120         0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
11121         0x00, 0x10, 0x01, 0x0b,
11122         0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
11123         0xfe, 0x4c, 0x44, 0xfe,
11124         0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
11125         0xda, 0x4f, 0x79, 0x2a,
11126         0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
11127         0xfe, 0x2a, 0x13, 0x32,
11128         0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
11129         0x54, 0x6b, 0xda, 0xfe,
11130         0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
11131         0x08, 0x13, 0x32, 0x07,
11132         0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
11133         0x08, 0x05, 0x06, 0x4d,
11134         0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
11135         0x2d, 0x12, 0xfe, 0xe6,
11136         0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
11137         0x02, 0x2b, 0xfe, 0x42,
11138         0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
11139         0xfe, 0x87, 0x80, 0xfe,
11140         0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
11141         0x07, 0x19, 0xfe, 0x7c,
11142         0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
11143         0x17, 0xfe, 0x90, 0x05,
11144         0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
11145         0xa0, 0x00, 0x28, 0xfe,
11146         0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
11147         0x34, 0xfe, 0x89, 0x48,
11148         0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
11149         0x12, 0xfe, 0xe3, 0x00,
11150         0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11151         0x70, 0x05, 0x88, 0x25,
11152         0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
11153         0x09, 0x48, 0xff, 0x02,
11154         0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
11155         0x08, 0x53, 0x05, 0xcb,
11156         0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
11157         0x05, 0x1b, 0xfe, 0x22,
11158         0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
11159         0x0d, 0x00, 0x01, 0x36,
11160         0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
11161         0x03, 0x5c, 0x28, 0xfe,
11162         0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
11163         0x05, 0x1f, 0xfe, 0x02,
11164         0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
11165         0x01, 0x4b, 0x12, 0xfe,
11166         0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
11167         0x12, 0x03, 0x45, 0x28,
11168         0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
11169         0x43, 0x48, 0xc4, 0xcc,
11170         0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
11171         0x6e, 0x41, 0x01, 0xb2,
11172         0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
11173         0xfe, 0xcc, 0x15, 0x1d,
11174         0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
11175         0x45, 0xc1, 0x0c, 0x45,
11176         0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
11177         0xe2, 0x00, 0x27, 0xdb,
11178         0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
11179         0xfe, 0x06, 0xf0, 0xfe,
11180         0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
11181         0x16, 0x19, 0x01, 0x0b,
11182         0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
11183         0xfe, 0x99, 0xa4, 0x01,
11184         0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
11185         0x12, 0x08, 0x05, 0x1a,
11186         0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
11187         0x0b, 0x16, 0x00, 0x01,
11188         0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
11189         0xe2, 0x6c, 0x58, 0xbe,
11190         0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
11191         0xfe, 0x09, 0x6f, 0xba,
11192         0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
11193         0xfe, 0x54, 0x07, 0x1c,
11194         0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
11195         0x07, 0x02, 0x24, 0x01,
11196         0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
11197         0x2c, 0x90, 0xfe, 0xae,
11198         0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
11199         0x37, 0x22, 0x20, 0x07,
11200         0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
11201         0xfe, 0x06, 0x10, 0xfe,
11202         0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
11203         0x37, 0x01, 0xb3, 0xb8,
11204         0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
11205         0x50, 0xfe, 0x44, 0x51,
11206         0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
11207         0x14, 0x5f, 0xfe, 0x0c,
11208         0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
11209         0x14, 0x3e, 0xfe, 0x4a,
11210         0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11211         0x90, 0x0c, 0x60, 0x14,
11212         0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
11213         0xfe, 0x44, 0x90, 0xfe,
11214         0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
11215         0x0c, 0x5e, 0x14, 0x5f,
11216         0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
11217         0x14, 0x3c, 0x21, 0x0c,
11218         0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
11219         0x27, 0xdd, 0xfe, 0x9e,
11220         0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
11221         0x9a, 0x08, 0xc6, 0xfe,
11222         0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
11223         0x95, 0x86, 0x02, 0x24,
11224         0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
11225         0x06, 0xfe, 0x10, 0x12,
11226         0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
11227         0x1c, 0x02, 0xfe, 0x18,
11228         0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
11229         0x2c, 0x1c, 0xfe, 0xaa,
11230         0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
11231         0xde, 0x09, 0xfe, 0xb7,
11232         0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
11233         0xfe, 0xf1, 0x18, 0xfe,
11234         0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
11235         0x14, 0x59, 0xfe, 0x95,
11236         0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
11237         0xfe, 0xf0, 0x08, 0xb5,
11238         0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
11239         0x0b, 0xb6, 0xfe, 0xbf,
11240         0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
11241         0x12, 0xc2, 0xfe, 0xd2,
11242         0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
11243         0x06, 0x17, 0x85, 0xc5,
11244         0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
11245         0x9d, 0x01, 0x36, 0x10,
11246         0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
11247         0x98, 0x80, 0xfe, 0x19,
11248         0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
11249         0xfe, 0x44, 0x54, 0xbe,
11250         0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
11251         0x02, 0x4a, 0x08, 0x05,
11252         0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
11253         0x9c, 0x3c, 0xfe, 0x6c,
11254         0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
11255         0x3b, 0x40, 0x03, 0x49,
11256         0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
11257         0x8f, 0xfe, 0xe3, 0x54,
11258         0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
11259         0xda, 0x09, 0xfe, 0x8b,
11260         0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
11261         0x0a, 0x3a, 0x49, 0x3b,
11262         0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
11263         0xad, 0xfe, 0x01, 0x59,
11264         0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
11265         0x49, 0x8f, 0xfe, 0xe3,
11266         0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
11267         0x4a, 0x3a, 0x49, 0x3b,
11268         0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
11269         0x02, 0x4a, 0x08, 0x05,
11270         0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
11271         0xb7, 0xfe, 0x03, 0xa1,
11272         0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
11273         0xfe, 0x86, 0x91, 0x6a,
11274         0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
11275         0x61, 0x0c, 0x7f, 0x14,
11276         0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
11277         0x9b, 0x2e, 0x9c, 0x3c,
11278         0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
11279         0xfa, 0x3c, 0x01, 0xef,
11280         0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
11281         0xe4, 0x08, 0x05, 0x1f,
11282         0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
11283         0x03, 0x5e, 0x29, 0x5f,
11284         0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
11285         0xf4, 0x09, 0x08, 0x05,
11286         0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
11287         0x81, 0x50, 0xfe, 0x10,
11288         0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
11289         0x08, 0x09, 0x12, 0xa6,
11290         0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
11291         0x08, 0x09, 0xfe, 0x0c,
11292         0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
11293         0x08, 0x05, 0x0a, 0xfe,
11294         0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
11295         0xf0, 0xe2, 0x15, 0x7e,
11296         0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
11297         0x57, 0x3d, 0xfe, 0xed,
11298         0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
11299         0x00, 0xff, 0x35, 0xfe,
11300         0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
11301         0x1e, 0x19, 0x8a, 0x03,
11302         0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
11303         0xfe, 0xd1, 0xf0, 0xfe,
11304         0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
11305         0x10, 0xfe, 0xce, 0xf0,
11306         0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
11307         0x10, 0xfe, 0x22, 0x00,
11308         0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
11309         0x02, 0x65, 0xfe, 0xd0,
11310         0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
11311         0x0b, 0x10, 0x58, 0xfe,
11312         0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
11313         0x12, 0x00, 0x2c, 0x0f,
11314         0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
11315         0x0c, 0xbc, 0x17, 0x34,
11316         0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
11317         0x0c, 0x1c, 0x34, 0x94,
11318         0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
11319         0x4b, 0xfe, 0xdb, 0x10,
11320         0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
11321         0x89, 0xf0, 0x24, 0x33,
11322         0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
11323         0x33, 0x31, 0xdf, 0xbc,
11324         0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
11325         0x17, 0xfe, 0x2c, 0x0d,
11326         0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
11327         0x12, 0x55, 0xfe, 0x28,
11328         0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
11329         0x44, 0xfe, 0x28, 0x00,
11330         0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
11331         0x0f, 0x64, 0x12, 0x2f,
11332         0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
11333         0x0a, 0xfe, 0xb4, 0x10,
11334         0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
11335         0xfe, 0x34, 0x46, 0xac,
11336         0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
11337         0x37, 0x01, 0xf5, 0x01,
11338         0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
11339         0xfe, 0x2e, 0x03, 0x08,
11340         0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
11341         0x1a, 0xfe, 0x58, 0x12,
11342         0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
11343         0xfe, 0x50, 0x0d, 0xfe,
11344         0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
11345         0xfe, 0xa9, 0x10, 0x10,
11346         0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
11347         0xfe, 0x13, 0x00, 0xfe,
11348         0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
11349         0x24, 0x00, 0x8c, 0xb5,
11350         0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
11351         0xfe, 0x9d, 0x41, 0xfe,
11352         0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
11353         0xb4, 0x15, 0xfe, 0x31,
11354         0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
11355         0xec, 0xd0, 0xfc, 0x44,
11356         0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
11357         0x4b, 0x91, 0xfe, 0x75,
11358         0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
11359         0x0e, 0xfe, 0x44, 0x48,
11360         0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
11361         0xfe, 0x41, 0x58, 0x09,
11362         0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
11363         0x2e, 0x03, 0x09, 0x5d,
11364         0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
11365         0xce, 0x47, 0xfe, 0xad,
11366         0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
11367         0x59, 0x13, 0x9f, 0x13,
11368         0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
11369         0xe0, 0x0e, 0x0f, 0x06,
11370         0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
11371         0x3a, 0x01, 0x56, 0xfe,
11372         0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
11373         0x20, 0x4f, 0xfe, 0x05,
11374         0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
11375         0x48, 0xf4, 0x0d, 0xfe,
11376         0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
11377         0x15, 0x1a, 0x39, 0xa0,
11378         0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
11379         0x0c, 0xfe, 0x60, 0x01,
11380         0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
11381         0x06, 0x13, 0x2f, 0x12,
11382         0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
11383         0x22, 0x9f, 0xb7, 0x13,
11384         0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
11385         0xa0, 0xb4, 0xfe, 0xd9,
11386         0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
11387         0xc3, 0xfe, 0x03, 0xdc,
11388         0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
11389         0xfe, 0x00, 0xcc, 0x04,
11390         0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
11391         0xfe, 0x1c, 0x80, 0x07,
11392         0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
11393         0xfe, 0x0c, 0x90, 0xfe,
11394         0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
11395         0x0a, 0xfe, 0x3c, 0x50,
11396         0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
11397         0x16, 0x08, 0x05, 0x1b,
11398         0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
11399         0xfe, 0x2c, 0x13, 0x01,
11400         0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
11401         0x0c, 0xfe, 0x64, 0x01,
11402         0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
11403         0x80, 0x8d, 0xfe, 0x01,
11404         0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
11405         0x22, 0x20, 0xfb, 0x79,
11406         0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
11407         0x03, 0xfe, 0xae, 0x00,
11408
11409         0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
11410         0xb2, 0x00, 0xfe, 0x09,
11411         0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
11412         0x45, 0x0f, 0x46, 0x52,
11413         0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
11414         0x0f, 0x44, 0x11, 0x0f,
11415         0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
11416         0x25, 0x11, 0x13, 0x20,
11417         0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
11418         0x56, 0xfe, 0xd6, 0xf0,
11419         0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
11420         0x18, 0x1c, 0x04, 0x42,
11421         0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
11422         0xf5, 0x13, 0x04, 0x01,
11423         0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
11424         0x13, 0x32, 0x07, 0x2f,
11425         0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
11426         0x41, 0x48, 0xfe, 0x45,
11427         0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
11428         0x07, 0x11, 0xac, 0x09,
11429         0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
11430         0x82, 0x4e, 0xfe, 0x14,
11431         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
11432         0xfe, 0x01, 0xec, 0xa2,
11433         0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
11434         0x2a, 0x01, 0xe3, 0xfe,
11435         0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
11436         0xfe, 0x48, 0x12, 0x07,
11437         0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
11438         0xfe, 0x32, 0x12, 0x07,
11439         0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
11440         0x1f, 0xfe, 0x12, 0x12,
11441         0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
11442         0x94, 0x4b, 0x04, 0x2d,
11443         0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
11444         0x32, 0x07, 0xa6, 0xfe,
11445         0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
11446         0x5a, 0xfe, 0x72, 0x12,
11447         0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
11448         0xfe, 0x26, 0x13, 0x03,
11449         0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
11450         0x0c, 0x7f, 0x0c, 0x80,
11451         0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
11452         0x3c, 0xfe, 0x04, 0x55,
11453         0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
11454         0x91, 0x10, 0x03, 0x3f,
11455         0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
11456         0x88, 0x9b, 0x2e, 0x9c,
11457         0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
11458         0x56, 0x0c, 0x5e, 0x14,
11459         0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
11460         0x03, 0x60, 0x29, 0x61,
11461         0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
11462         0x50, 0xfe, 0xc6, 0x50,
11463         0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
11464         0x29, 0x3e, 0xfe, 0x40,
11465         0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
11466         0x2d, 0x01, 0x0b, 0x1d,
11467         0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
11468         0x72, 0x01, 0xaf, 0x1e,
11469         0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
11470         0x0a, 0x55, 0x35, 0xfe,
11471         0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
11472         0x02, 0x72, 0xfe, 0x19,
11473         0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
11474         0x1d, 0xe8, 0x33, 0x31,
11475         0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
11476         0x0b, 0x1c, 0x34, 0x1d,
11477         0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
11478         0x33, 0x31, 0xfe, 0xe8,
11479         0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
11480         0x05, 0x1f, 0x35, 0xa9,
11481         0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
11482         0x14, 0x01, 0xaf, 0x8c,
11483         0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
11484         0x03, 0x45, 0x28, 0x35,
11485         0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
11486         0x03, 0x5c, 0xc1, 0x0c,
11487         0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
11488         0x89, 0x01, 0x0b, 0x1c,
11489         0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
11490         0xfe, 0x42, 0x58, 0xf1,
11491         0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
11492         0xf4, 0x06, 0xea, 0x32,
11493         0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
11494         0x01, 0x0b, 0x26, 0x89,
11495         0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
11496         0x26, 0xfe, 0xd4, 0x13,
11497         0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
11498         0x13, 0x1c, 0xfe, 0xd0,
11499         0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
11500         0x0f, 0x71, 0xff, 0x02,
11501         0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
11502         0x00, 0x5c, 0x04, 0x0f,
11503         0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
11504         0xfe, 0x00, 0x5c, 0x04,
11505         0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
11506         0x02, 0x00, 0x57, 0x52,
11507         0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
11508         0x87, 0x04, 0xfe, 0x03,
11509         0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
11510         0xfe, 0x00, 0x7d, 0xfe,
11511         0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
11512         0x14, 0x5f, 0x57, 0x3f,
11513         0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
11514         0x5a, 0x8d, 0x04, 0x01,
11515         0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
11516         0xfe, 0x96, 0x15, 0x33,
11517         0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
11518         0x0a, 0xfe, 0xc1, 0x59,
11519         0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
11520         0x21, 0x69, 0x1a, 0xee,
11521         0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
11522         0x30, 0xfe, 0x78, 0x10,
11523         0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
11524         0x98, 0xfe, 0x30, 0x00,
11525         0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
11526         0x98, 0xfe, 0x64, 0x00,
11527         0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
11528         0x10, 0x69, 0x06, 0xfe,
11529         0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
11530         0x18, 0x59, 0x0f, 0x06,
11531         0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
11532         0x43, 0xf4, 0x9f, 0xfe,
11533         0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
11534         0x9e, 0xfe, 0xf3, 0x10,
11535         0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
11536         0x17, 0xfe, 0x4d, 0xe4,
11537         0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
11538         0x17, 0xfe, 0x4d, 0xe4,
11539         0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
11540         0xf4, 0x00, 0xe9, 0x91,
11541         0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
11542         0x04, 0x16, 0x06, 0x01,
11543         0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
11544         0x0b, 0x26, 0xf3, 0x76,
11545         0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
11546         0x16, 0x19, 0x01, 0x0b,
11547         0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
11548         0x0b, 0x26, 0xb1, 0x76,
11549         0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
11550         0xfe, 0x48, 0x13, 0xb8,
11551         0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
11552         0xec, 0xfe, 0x27, 0x01,
11553         0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
11554         0x07, 0xfe, 0xe3, 0x00,
11555         0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
11556         0x22, 0xd4, 0x07, 0x06,
11557         0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
11558         0x07, 0x11, 0xae, 0x09,
11559         0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
11560         0x0e, 0x8e, 0xfe, 0x80,
11561         0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
11562         0x09, 0x48, 0x01, 0x0e,
11563         0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
11564         0x80, 0xfe, 0x80, 0x4c,
11565         0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
11566         0x09, 0x5d, 0x01, 0x87,
11567         0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
11568         0x19, 0xde, 0xfe, 0x24,
11569         0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
11570         0x17, 0xad, 0x9a, 0x1b,
11571         0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
11572         0x16, 0xfe, 0xda, 0x10,
11573         0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
11574         0x18, 0x58, 0x03, 0xfe,
11575         0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
11576         0xf4, 0x06, 0xfe, 0x3c,
11577         0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
11578         0x97, 0xfe, 0x38, 0x17,
11579         0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
11580         0x10, 0x18, 0x11, 0x75,
11581         0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
11582         0x2e, 0x97, 0xfe, 0x5a,
11583         0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
11584         0xfe, 0x98, 0xe7, 0x00,
11585         0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
11586         0xfe, 0x30, 0xbc, 0xfe,
11587         0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11588         0xcb, 0x97, 0xfe, 0x92,
11589         0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
11590         0x42, 0x10, 0xfe, 0x02,
11591         0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
11592         0x03, 0xa1, 0xfe, 0x1d,
11593         0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
11594         0x9a, 0x5b, 0x41, 0xfe,
11595         0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
11596         0x11, 0x12, 0xfe, 0xdd,
11597         0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
11598         0x17, 0x15, 0x06, 0x39,
11599         0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
11600         0xfe, 0x7e, 0x18, 0x1e,
11601         0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
11602         0x12, 0xfe, 0xe1, 0x10,
11603         0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
11604         0x13, 0x42, 0x92, 0x09,
11605         0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
11606         0xf0, 0xfe, 0x00, 0xcc,
11607         0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
11608         0x0e, 0xfe, 0x80, 0x4c,
11609         0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
11610         0x24, 0x12, 0xfe, 0x14,
11611         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
11612         0xe7, 0x0a, 0x10, 0xfe,
11613         0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
11614         0x08, 0x54, 0x1b, 0x37,
11615         0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
11616         0x90, 0x3a, 0xce, 0x3b,
11617         0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
11618         0x13, 0xa3, 0x04, 0x09,
11619         0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
11620         0x44, 0x17, 0xfe, 0xe8,
11621         0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
11622         0x5d, 0x01, 0xa8, 0x09,
11623         0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
11624         0x1c, 0x19, 0x03, 0xfe,
11625         0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
11626         0x6b, 0xfe, 0x2e, 0x19,
11627         0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
11628         0xfe, 0x0b, 0x00, 0x6b,
11629         0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
11630         0x08, 0x10, 0x03, 0xfe,
11631         0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
11632         0x04, 0x68, 0x54, 0xe7,
11633         0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
11634         0x1a, 0xf4, 0xfe, 0x00,
11635         0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
11636         0x04, 0x07, 0x7e, 0xfe,
11637         0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
11638         0x07, 0x1a, 0xfe, 0x5a,
11639         0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
11640         0x25, 0x6d, 0xe5, 0x07,
11641         0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
11642         0xa9, 0xb8, 0x04, 0x15,
11643         0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
11644         0x40, 0x5c, 0x04, 0x1c,
11645         0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
11646         0xf7, 0xfe, 0x82, 0xf0,
11647         0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
11648 };
11649
11650 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf);       /* 0x14E1 */
11651 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL;  /* Expanded little-endian checksum. */
11652
11653 /* Microcode buffer is kept after initialization for error recovery. */
11654 static unsigned char _adv_asc38C1600_buf[] = {
11655         0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
11656         0x18, 0xe4, 0x01, 0x00,
11657         0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
11658         0x07, 0x17, 0xc0, 0x5f,
11659         0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
11660         0x85, 0xf0, 0x86, 0xf0,
11661         0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
11662         0x98, 0x57, 0x01, 0xe6,
11663         0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
11664         0x38, 0x54, 0x32, 0xf0,
11665         0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
11666         0x00, 0xe6, 0xb1, 0xf0,
11667         0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
11668         0x06, 0x13, 0x0c, 0x1c,
11669         0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
11670         0xb9, 0x54, 0x00, 0x80,
11671         0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
11672         0x03, 0xe6, 0x01, 0xea,
11673         0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
11674         0x04, 0x13, 0xbb, 0x55,
11675         0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
11676         0xbb, 0x00, 0xc0, 0x00,
11677         0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
11678         0x4c, 0x1c, 0x4e, 0x1c,
11679         0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
11680         0x24, 0x01, 0x3c, 0x01,
11681         0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
11682         0x78, 0x01, 0x7c, 0x01,
11683         0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
11684         0x6e, 0x1e, 0x02, 0x48,
11685         0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
11686         0x03, 0xfc, 0x06, 0x00,
11687         0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
11688         0x30, 0x1c, 0x38, 0x1c,
11689         0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
11690         0x5d, 0xf0, 0xa7, 0xf0,
11691         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
11692         0x33, 0x00, 0x34, 0x00,
11693         0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
11694         0x79, 0x01, 0x3c, 0x09,
11695         0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
11696         0x40, 0x16, 0x50, 0x16,
11697         0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
11698         0x05, 0xf0, 0x09, 0xf0,
11699         0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
11700         0x9c, 0x00, 0xa4, 0x00,
11701         0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
11702         0xe9, 0x09, 0x5c, 0x0c,
11703         0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
11704         0x42, 0x1d, 0x08, 0x44,
11705         0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
11706         0x83, 0x55, 0x83, 0x59,
11707         0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
11708         0x4b, 0xf4, 0x04, 0xf8,
11709         0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
11710         0xa8, 0x00, 0xaa, 0x00,
11711         0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
11712         0x7a, 0x01, 0x82, 0x01,
11713         0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
11714         0x68, 0x08, 0x10, 0x0d,
11715         0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
11716         0xf3, 0x10, 0x06, 0x12,
11717         0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
11718         0xf0, 0x35, 0x05, 0xfe,
11719         0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
11720         0xfe, 0x88, 0x01, 0xff,
11721         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11722         0x00, 0xfe, 0x57, 0x24,
11723         0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
11724         0x00, 0x00, 0xff, 0x08,
11725         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11726         0xff, 0xff, 0xff, 0x13,
11727         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11728         0xfe, 0x04, 0xf7, 0xe8,
11729         0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
11730         0x0d, 0x51, 0x37, 0xfe,
11731         0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
11732         0xfe, 0xf8, 0x01, 0xfe,
11733         0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
11734         0x05, 0xfe, 0x08, 0x0f,
11735         0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
11736         0x28, 0x1c, 0x03, 0xfe,
11737         0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
11738         0x48, 0xf0, 0xfe, 0x90,
11739         0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
11740         0x02, 0xfe, 0x46, 0xf0,
11741         0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
11742         0xfe, 0x4e, 0x02, 0xfe,
11743         0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
11744         0x0d, 0xa2, 0x1c, 0x07,
11745         0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
11746         0x1c, 0xf5, 0xfe, 0x1e,
11747         0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
11748         0xde, 0x0a, 0x81, 0x01,
11749         0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
11750         0x81, 0x01, 0x5c, 0xfe,
11751         0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
11752         0xfe, 0x58, 0x1c, 0x1c,
11753         0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
11754         0x2b, 0xfe, 0x9e, 0x02,
11755         0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
11756         0x00, 0x47, 0xb8, 0x01,
11757         0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
11758         0x1a, 0x31, 0xfe, 0x69,
11759         0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
11760         0x1e, 0x1e, 0x20, 0x2c,
11761         0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
11762         0x44, 0x15, 0x56, 0x51,
11763         0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
11764         0x01, 0x18, 0x09, 0x00,
11765         0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
11766         0x18, 0xfe, 0xc8, 0x54,
11767         0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
11768         0xfe, 0x02, 0xe8, 0x30,
11769         0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
11770         0xfe, 0xe4, 0x01, 0xfe,
11771         0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
11772         0x26, 0xf0, 0xfe, 0x66,
11773         0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
11774         0xef, 0x10, 0xfe, 0x9f,
11775         0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
11776         0x70, 0x37, 0xfe, 0x48,
11777         0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
11778         0x21, 0xb9, 0xc7, 0x20,
11779         0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
11780         0xe1, 0x2a, 0xeb, 0xfe,
11781         0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
11782         0x15, 0xfe, 0xe4, 0x00,
11783         0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
11784         0xfe, 0x06, 0xf0, 0xfe,
11785         0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
11786         0x03, 0x81, 0x1e, 0x1b,
11787         0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
11788         0xea, 0xfe, 0x46, 0x1c,
11789         0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
11790         0xfe, 0x48, 0x1c, 0x75,
11791         0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
11792         0xe1, 0x01, 0x18, 0x77,
11793         0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
11794         0x8f, 0xfe, 0x70, 0x02,
11795         0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
11796         0x16, 0xfe, 0x4a, 0x04,
11797         0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
11798         0x02, 0x00, 0x10, 0x01,
11799         0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
11800         0xee, 0xfe, 0x4c, 0x44,
11801         0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
11802         0x7b, 0xec, 0x60, 0x8d,
11803         0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
11804         0x0c, 0x06, 0x28, 0xfe,
11805         0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
11806         0x13, 0x34, 0xfe, 0x4c,
11807         0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
11808         0x13, 0x01, 0x0c, 0x06,
11809         0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
11810         0x28, 0xf9, 0x1f, 0x7f,
11811         0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
11812         0xfe, 0xa4, 0x0e, 0x05,
11813         0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
11814         0x9c, 0x93, 0x3a, 0x0b,
11815         0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
11816         0x7d, 0x1d, 0xfe, 0x46,
11817         0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
11818         0xfe, 0x87, 0x83, 0xfe,
11819         0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
11820         0x13, 0x0f, 0xfe, 0x20,
11821         0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
11822         0x12, 0x01, 0x38, 0x06,
11823         0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
11824         0x05, 0xd0, 0x54, 0x01,
11825         0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
11826         0x50, 0x12, 0x5e, 0xff,
11827         0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
11828         0x00, 0x10, 0x2f, 0xfe,
11829         0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
11830         0x38, 0xfe, 0x4a, 0xf0,
11831         0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
11832         0x21, 0x00, 0xf1, 0x2e,
11833         0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
11834         0x10, 0x2f, 0xfe, 0xd0,
11835         0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
11836         0x1c, 0x00, 0x4d, 0x01,
11837         0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
11838         0x28, 0xfe, 0x24, 0x12,
11839         0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
11840         0x0d, 0x00, 0x01, 0x42,
11841         0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
11842         0x03, 0xb6, 0x1e, 0xfe,
11843         0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
11844         0xfe, 0x72, 0x06, 0x0a,
11845         0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
11846         0x19, 0x16, 0xfe, 0x68,
11847         0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
11848         0x03, 0x9a, 0x1e, 0xfe,
11849         0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
11850         0x48, 0xfe, 0x92, 0x06,
11851         0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
11852         0x58, 0xff, 0x02, 0x00,
11853         0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
11854         0xfe, 0xea, 0x06, 0x01,
11855         0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
11856         0xfe, 0xe0, 0x06, 0x15,
11857         0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
11858         0x01, 0x84, 0xfe, 0xae,
11859         0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
11860         0x1e, 0xfe, 0x1a, 0x12,
11861         0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
11862         0x43, 0x48, 0x62, 0x80,
11863         0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
11864         0x36, 0xfe, 0x02, 0xf6,
11865         0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
11866         0xd0, 0x0d, 0x17, 0xfe,
11867         0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
11868         0x9e, 0x15, 0x82, 0x01,
11869         0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
11870         0x57, 0x10, 0xe6, 0x05,
11871         0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
11872         0xfe, 0x9c, 0x32, 0x5f,
11873         0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
11874         0xfe, 0x0a, 0xf0, 0xfe,
11875         0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
11876         0xaf, 0xa0, 0x05, 0x29,
11877         0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
11878         0x00, 0x01, 0x08, 0x14,
11879         0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
11880         0x14, 0x00, 0x05, 0xfe,
11881         0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
11882         0x12, 0xfe, 0x30, 0x13,
11883         0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
11884         0x01, 0x08, 0x14, 0x00,
11885         0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
11886         0x78, 0x4f, 0x0f, 0xfe,
11887         0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
11888         0x28, 0x48, 0xfe, 0x6c,
11889         0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
11890         0x12, 0x53, 0x63, 0x4e,
11891         0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
11892         0x6c, 0x08, 0xaf, 0xa0,
11893         0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
11894         0x05, 0xed, 0xfe, 0x9c,
11895         0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
11896         0x1e, 0xfe, 0x99, 0x58,
11897         0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
11898         0x22, 0x6b, 0x01, 0x0c,
11899         0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
11900         0x1e, 0x47, 0x2c, 0x7a,
11901         0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
11902         0x01, 0x0c, 0x61, 0x65,
11903         0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
11904         0x16, 0xfe, 0x08, 0x50,
11905         0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
11906         0x01, 0xfe, 0xce, 0x1e,
11907         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
11908         0x01, 0xfe, 0xfe, 0x1e,
11909         0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
11910         0x10, 0x01, 0x0c, 0x06,
11911         0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
11912         0x10, 0x6a, 0x22, 0x6b,
11913         0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
11914         0xfe, 0x9f, 0x83, 0x33,
11915         0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
11916         0x3a, 0x0b, 0xfe, 0xc6,
11917         0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
11918         0x01, 0xfe, 0xce, 0x1e,
11919         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
11920         0x04, 0xfe, 0xc0, 0x93,
11921         0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
11922         0x10, 0x4b, 0x22, 0x4c,
11923         0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
11924         0x4e, 0x11, 0x2f, 0xfe,
11925         0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
11926         0x3c, 0x37, 0x88, 0xf5,
11927         0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
11928         0xd3, 0xfe, 0x42, 0x0a,
11929         0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
11930         0x05, 0x29, 0x01, 0x41,
11931         0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
11932         0xfe, 0x14, 0x12, 0x01,
11933         0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
11934         0x2e, 0x1c, 0x05, 0xfe,
11935         0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
11936         0xfe, 0x2c, 0x1c, 0xfe,
11937         0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
11938         0x92, 0x10, 0xc4, 0xf6,
11939         0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
11940         0xe7, 0x10, 0xfe, 0x2b,
11941         0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
11942         0xac, 0xfe, 0xd2, 0xf0,
11943         0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
11944         0x1b, 0xbf, 0xd4, 0x5b,
11945         0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
11946         0x5e, 0x32, 0x1f, 0x7f,
11947         0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
11948         0x05, 0x70, 0xfe, 0x74,
11949         0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
11950         0x0f, 0x4d, 0x01, 0xfe,
11951         0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
11952         0x0d, 0x2b, 0xfe, 0xe2,
11953         0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
11954         0xfe, 0x88, 0x13, 0x21,
11955         0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
11956         0x83, 0x83, 0xfe, 0xc9,
11957         0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
11958         0x91, 0x04, 0xfe, 0x84,
11959         0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
11960         0xfe, 0xcb, 0x57, 0x0b,
11961         0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
11962         0x6a, 0x3b, 0x6b, 0x10,
11963         0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
11964         0x20, 0x6e, 0xdb, 0x64,
11965         0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
11966         0xfe, 0x04, 0xfa, 0x64,
11967         0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
11968         0x10, 0x98, 0x91, 0x6c,
11969         0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
11970         0x4b, 0x7e, 0x4c, 0x01,
11971         0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
11972         0x58, 0xfe, 0x91, 0x58,
11973         0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
11974         0x1b, 0x40, 0x01, 0x0c,
11975         0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
11976         0xfe, 0x10, 0x90, 0x04,
11977         0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
11978         0x79, 0x0b, 0x0e, 0xfe,
11979         0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
11980         0x01, 0x0c, 0x06, 0x0d,
11981         0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
11982         0x0c, 0x58, 0xfe, 0x8d,
11983         0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
11984         0x83, 0x33, 0x0b, 0x0e,
11985         0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
11986         0x19, 0xfe, 0x19, 0x41,
11987         0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
11988         0x19, 0xfe, 0x44, 0x00,
11989         0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
11990         0x4c, 0xfe, 0x0c, 0x51,
11991         0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
11992         0x76, 0x10, 0xac, 0xfe,
11993         0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
11994         0xe3, 0x23, 0x07, 0xfe,
11995         0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
11996         0xcc, 0x0c, 0x1f, 0x92,
11997         0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
11998         0x0c, 0xfe, 0x3e, 0x10,
11999         0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
12000         0xfe, 0xcb, 0xf0, 0xfe,
12001         0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
12002         0xf4, 0x0c, 0x19, 0x94,
12003         0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
12004         0xfe, 0xcc, 0xf0, 0xef,
12005         0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
12006         0x4e, 0x11, 0x2f, 0xfe,
12007         0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
12008         0x3c, 0x37, 0x88, 0xf5,
12009         0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
12010         0x2f, 0xfe, 0x3e, 0x0d,
12011         0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
12012         0xd2, 0x9f, 0xd3, 0x9f,
12013         0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
12014         0xc5, 0x75, 0xd7, 0x99,
12015         0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
12016         0x9c, 0x2f, 0xfe, 0x8c,
12017         0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
12018         0x42, 0x00, 0x05, 0x70,
12019         0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
12020         0x0d, 0xfe, 0x44, 0x13,
12021         0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
12022         0xfe, 0xda, 0x0e, 0x0a,
12023         0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
12024         0x10, 0x01, 0xfe, 0xf4,
12025         0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
12026         0x15, 0x56, 0x01, 0x85,
12027         0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
12028         0xcc, 0x10, 0x01, 0xa7,
12029         0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
12030         0xfe, 0x99, 0x83, 0xfe,
12031         0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
12032         0x43, 0x00, 0xfe, 0xa2,
12033         0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
12034         0x00, 0x1d, 0x40, 0x15,
12035         0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
12036         0xfe, 0x3a, 0x03, 0x01,
12037         0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
12038         0x76, 0x06, 0x12, 0xfe,
12039         0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
12040         0xfe, 0x9d, 0xf0, 0xfe,
12041         0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
12042         0x0c, 0x61, 0x12, 0x44,
12043         0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
12044         0xfe, 0x2e, 0x10, 0x19,
12045         0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
12046         0xfe, 0x41, 0x00, 0xa2,
12047         0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
12048         0xea, 0x4f, 0xfe, 0x04,
12049         0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
12050         0x35, 0xfe, 0x12, 0x1c,
12051         0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
12052         0xfe, 0xd4, 0x11, 0x05,
12053         0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
12054         0xce, 0x45, 0x31, 0x51,
12055         0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
12056         0x67, 0xfe, 0x98, 0x56,
12057         0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
12058         0x0c, 0x06, 0x28, 0xfe,
12059         0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
12060         0xfe, 0xfa, 0x14, 0xfe,
12061         0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
12062         0xfe, 0xe0, 0x14, 0xfe,
12063         0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
12064         0xfe, 0xad, 0x13, 0x05,
12065         0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
12066         0xe7, 0xfe, 0x08, 0x1c,
12067         0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
12068         0x48, 0x55, 0xa5, 0x3b,
12069         0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
12070         0xf0, 0x1a, 0x03, 0xfe,
12071         0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
12072         0xec, 0xe7, 0x53, 0x00,
12073         0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
12074         0x01, 0xfe, 0x62, 0x1b,
12075         0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
12076         0xea, 0xe7, 0x53, 0x92,
12077         0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
12078         0xfe, 0x38, 0x01, 0x23,
12079         0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
12080         0x01, 0x01, 0xfe, 0x1e,
12081         0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
12082         0x26, 0x02, 0x21, 0x96,
12083         0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
12084         0xc3, 0xfe, 0xe1, 0x10,
12085         0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
12086         0xfe, 0x03, 0xdc, 0xfe,
12087         0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
12088         0x00, 0xcc, 0x02, 0xfe,
12089         0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
12090         0x0f, 0xfe, 0x1c, 0x80,
12091         0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
12092         0x0f, 0xfe, 0x1e, 0x80,
12093         0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
12094         0x1d, 0x80, 0x04, 0xfe,
12095         0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
12096         0x1e, 0xac, 0xfe, 0x14,
12097         0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
12098         0x1f, 0xfe, 0x30, 0xf4,
12099         0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
12100         0x56, 0xfb, 0x01, 0xfe,
12101         0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
12102         0xfe, 0x00, 0x1d, 0x15,
12103         0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
12104         0x22, 0x1b, 0xfe, 0x1e,
12105         0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
12106         0x96, 0x90, 0x04, 0xfe,
12107         0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
12108         0x01, 0x01, 0x0c, 0x06,
12109         0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
12110         0x0e, 0x77, 0xfe, 0x01,
12111         0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
12112         0x21, 0x2c, 0xfe, 0x00,
12113         0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
12114         0x06, 0x58, 0x03, 0xfe,
12115         0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
12116         0x03, 0xfe, 0xb2, 0x00,
12117         0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
12118         0x66, 0x10, 0x55, 0x10,
12119         0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
12120         0x54, 0x2b, 0xfe, 0x88,
12121         0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
12122         0x91, 0x54, 0x2b, 0xfe,
12123         0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
12124         0x00, 0x40, 0x8d, 0x2c,
12125         0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
12126         0x12, 0x1c, 0x75, 0xfe,
12127         0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
12128         0x14, 0xfe, 0x0e, 0x47,
12129         0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
12130         0xa7, 0x90, 0x34, 0x60,
12131         0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
12132         0x09, 0x56, 0xfe, 0x34,
12133         0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
12134         0xfe, 0x45, 0x48, 0x01,
12135         0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
12136         0x09, 0x1a, 0xa5, 0x0a,
12137         0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
12138         0xfe, 0x14, 0x56, 0xfe,
12139         0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
12140         0xec, 0xb8, 0xfe, 0x9e,
12141         0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
12142         0xf4, 0xfe, 0xdd, 0x10,
12143         0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
12144         0x12, 0x09, 0x0d, 0xfe,
12145         0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
12146         0x13, 0x09, 0xfe, 0x23,
12147         0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
12148         0x24, 0xfe, 0x12, 0x12,
12149         0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
12150         0xae, 0x41, 0x02, 0x32,
12151         0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
12152         0x35, 0x32, 0x01, 0x43,
12153         0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
12154         0x13, 0x01, 0x0c, 0x06,
12155         0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
12156         0xe5, 0x55, 0xb0, 0xfe,
12157         0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
12158         0xfe, 0xb6, 0x0e, 0x10,
12159         0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
12160         0x88, 0x20, 0x6e, 0x01,
12161         0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
12162         0x55, 0xfe, 0x04, 0xfa,
12163         0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
12164         0xfe, 0x40, 0x56, 0xfe,
12165         0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
12166         0x44, 0x55, 0xfe, 0xe5,
12167         0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
12168         0x68, 0x22, 0x69, 0x01,
12169         0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
12170         0x6b, 0xfe, 0x2c, 0x50,
12171         0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
12172         0x50, 0x03, 0x68, 0x3b,
12173         0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
12174         0x40, 0x50, 0xfe, 0xc2,
12175         0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
12176         0x16, 0x3d, 0x27, 0x25,
12177         0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
12178         0xa6, 0x23, 0x3f, 0x1b,
12179         0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
12180         0xfe, 0x0a, 0x55, 0x31,
12181         0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
12182         0x51, 0x05, 0x72, 0x01,
12183         0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
12184         0x2a, 0x3c, 0x16, 0xc0,
12185         0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
12186         0xfe, 0x66, 0x15, 0x05,
12187         0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
12188         0x2b, 0x3d, 0x01, 0x08,
12189         0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
12190         0xb6, 0x1e, 0x83, 0x01,
12191         0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
12192         0x07, 0x90, 0x3f, 0x01,
12193         0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
12194         0x01, 0x43, 0x09, 0x82,
12195         0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
12196         0x05, 0x72, 0xfe, 0xc0,
12197         0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
12198         0x32, 0x01, 0x08, 0x17,
12199         0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
12200         0x3d, 0x27, 0x25, 0xbd,
12201         0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
12202         0xe8, 0x14, 0x01, 0xa6,
12203         0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
12204         0x0e, 0x12, 0x01, 0x43,
12205         0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
12206         0x01, 0x08, 0x17, 0x73,
12207         0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
12208         0x27, 0x25, 0xbd, 0x09,
12209         0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
12210         0xb6, 0x14, 0x86, 0xa8,
12211         0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
12212         0x82, 0x4e, 0x05, 0x72,
12213         0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
12214         0xfe, 0xc0, 0x19, 0x05,
12215         0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
12216         0xcc, 0x01, 0x08, 0x26,
12217         0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
12218         0xcc, 0x15, 0x5e, 0x32,
12219         0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
12220         0xad, 0x23, 0xfe, 0xff,
12221         0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
12222         0x00, 0x57, 0x52, 0xad,
12223         0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
12224         0x02, 0x00, 0x57, 0x52,
12225         0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
12226         0x02, 0x13, 0x58, 0xff,
12227         0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
12228         0x5c, 0x0a, 0x55, 0x01,
12229         0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
12230         0xff, 0x03, 0x00, 0x54,
12231         0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
12232         0x7c, 0x3a, 0x0b, 0x0e,
12233         0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
12234         0xfe, 0x1a, 0xf7, 0x00,
12235         0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
12236         0xda, 0x6d, 0x02, 0xfe,
12237         0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
12238         0x02, 0x01, 0xc6, 0xfe,
12239         0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
12240         0x25, 0xbe, 0x01, 0x08,
12241         0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
12242         0x03, 0x9a, 0x1e, 0xfe,
12243         0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
12244         0x48, 0xfe, 0x08, 0x17,
12245         0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
12246         0x17, 0x4d, 0x13, 0x07,
12247         0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
12248         0xff, 0x02, 0x83, 0x55,
12249         0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
12250         0x17, 0x1c, 0x63, 0x13,
12251         0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
12252         0x00, 0xb0, 0xfe, 0x80,
12253         0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
12254         0x53, 0x07, 0xfe, 0x60,
12255         0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
12256         0x00, 0x1c, 0x95, 0x13,
12257         0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
12258         0xfe, 0x43, 0xf4, 0x96,
12259         0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
12260         0xf4, 0x94, 0xf6, 0x8b,
12261         0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
12262         0xda, 0x17, 0x62, 0x49,
12263         0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
12264         0x71, 0x50, 0x26, 0xfe,
12265         0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
12266         0x58, 0x02, 0x50, 0x13,
12267         0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
12268         0x25, 0xbe, 0xfe, 0x03,
12269         0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
12270         0x0a, 0x01, 0x08, 0x16,
12271         0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
12272         0x01, 0x08, 0x16, 0xa9,
12273         0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
12274         0x08, 0x16, 0xa9, 0x27,
12275         0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
12276         0x01, 0x38, 0x06, 0x24,
12277         0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
12278         0x78, 0x03, 0x9a, 0x1e,
12279         0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
12280         0xfe, 0x40, 0x5a, 0x23,
12281         0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
12282         0x80, 0x48, 0xfe, 0xaa,
12283         0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
12284         0xfe, 0xac, 0x1d, 0xfe,
12285         0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
12286         0x43, 0x48, 0x2d, 0x93,
12287         0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
12288         0x36, 0xfe, 0x34, 0xf4,
12289         0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
12290         0x28, 0x10, 0xfe, 0xc0,
12291         0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
12292         0x18, 0x45, 0xfe, 0x1c,
12293         0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
12294         0x19, 0xfe, 0x04, 0xf4,
12295         0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
12296         0x21, 0xfe, 0x7f, 0x01,
12297         0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
12298         0x7e, 0x01, 0xfe, 0xc8,
12299         0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
12300         0x21, 0xfe, 0x81, 0x01,
12301         0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
12302         0x13, 0x0d, 0x02, 0x14,
12303         0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
12304         0xfe, 0x82, 0x19, 0x14,
12305         0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
12306         0x08, 0x02, 0x14, 0x07,
12307         0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
12308         0x01, 0x08, 0x17, 0xc1,
12309         0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
12310         0x08, 0x02, 0x50, 0x02,
12311         0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
12312         0x14, 0x12, 0x01, 0x08,
12313         0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
12314         0x08, 0x17, 0x74, 0xfe,
12315         0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
12316         0x74, 0x5f, 0xcc, 0x01,
12317         0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
12318         0xfe, 0x49, 0xf4, 0x00,
12319         0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
12320         0x02, 0x00, 0x10, 0x2f,
12321         0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
12322         0x16, 0xfe, 0x64, 0x1a,
12323         0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
12324         0x61, 0x07, 0x44, 0x02,
12325         0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
12326         0x13, 0x0a, 0x9d, 0x01,
12327         0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
12328         0xfe, 0x80, 0xe7, 0x1a,
12329         0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
12330         0x0a, 0x5a, 0x01, 0x18,
12331         0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
12332         0x7e, 0x1e, 0xfe, 0x80,
12333         0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
12334         0xfe, 0x80, 0x4c, 0x0a,
12335         0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
12336         0xfe, 0x19, 0xde, 0xfe,
12337         0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
12338         0x2a, 0x1c, 0xfa, 0xb3,
12339         0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
12340         0xf4, 0x1a, 0xfe, 0xfa,
12341         0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
12342         0xfe, 0x18, 0x58, 0x03,
12343         0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
12344         0xfe, 0x30, 0xf4, 0x07,
12345         0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
12346         0xf7, 0x24, 0xb1, 0xfe,
12347         0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
12348         0xfe, 0xba, 0x10, 0x1c,
12349         0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
12350         0x1d, 0xf7, 0x54, 0xb1,
12351         0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
12352         0xaf, 0x19, 0xfe, 0x98,
12353         0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
12354         0x1a, 0x87, 0x8b, 0x0f,
12355         0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
12356         0xfe, 0x32, 0x90, 0x04,
12357         0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
12358         0x7c, 0x12, 0xfe, 0x0f,
12359         0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
12360         0x31, 0x02, 0xc9, 0x2b,
12361         0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
12362         0x6a, 0xfe, 0x19, 0xfe,
12363         0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
12364         0x1b, 0xfe, 0x36, 0x14,
12365         0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
12366         0xfe, 0x80, 0xe7, 0x1a,
12367         0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
12368         0x30, 0xfe, 0x12, 0x45,
12369         0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
12370         0x39, 0xf0, 0x75, 0x26,
12371         0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
12372         0xe3, 0x23, 0x07, 0xfe,
12373         0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
12374         0x56, 0xfe, 0x3c, 0x13,
12375         0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
12376         0x01, 0x18, 0xcb, 0xfe,
12377         0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
12378         0xfe, 0x00, 0xcc, 0xcb,
12379         0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
12380         0xfe, 0x80, 0x4c, 0x01,
12381         0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
12382         0x12, 0xfe, 0x14, 0x56,
12383         0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
12384         0x0d, 0x19, 0xfe, 0x15,
12385         0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
12386         0x83, 0xfe, 0x18, 0x80,
12387         0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
12388         0x90, 0xfe, 0xba, 0x90,
12389         0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
12390         0x21, 0xb9, 0x88, 0x20,
12391         0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
12392         0x18, 0xfe, 0x49, 0x44,
12393         0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
12394         0x1a, 0xa4, 0x0a, 0x67,
12395         0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
12396         0x1d, 0x7b, 0xfe, 0x52,
12397         0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
12398         0x4e, 0xe4, 0xdd, 0x7b,
12399         0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
12400         0xfe, 0x4e, 0xe4, 0xfe,
12401         0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
12402         0xfe, 0x08, 0x10, 0x03,
12403         0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
12404         0x68, 0x54, 0xfe, 0xf1,
12405         0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
12406         0xfe, 0x1a, 0xf4, 0xfe,
12407         0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
12408         0x09, 0x92, 0xfe, 0x5a,
12409         0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
12410         0x5a, 0xf0, 0xfe, 0xc8,
12411         0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
12412         0x1a, 0x10, 0x09, 0x0d,
12413         0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
12414         0x1f, 0x93, 0x01, 0x42,
12415         0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
12416         0xfe, 0x14, 0xf0, 0x08,
12417         0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
12418         0xfe, 0x82, 0xf0, 0xfe,
12419         0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
12420         0x02, 0x0f, 0xfe, 0x18,
12421         0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
12422         0x80, 0x04, 0xfe, 0x82,
12423         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
12424         0x83, 0x33, 0x0b, 0x0e,
12425         0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
12426         0x02, 0x0f, 0xfe, 0x04,
12427         0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
12428         0x80, 0x04, 0xfe, 0x80,
12429         0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
12430         0xfe, 0x99, 0x83, 0xfe,
12431         0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
12432         0x83, 0xfe, 0xce, 0x47,
12433         0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
12434         0x0b, 0x0e, 0x02, 0x0f,
12435         0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
12436         0xfe, 0x08, 0x90, 0x04,
12437         0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
12438         0xfe, 0x8a, 0x93, 0x79,
12439         0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
12440         0x0b, 0x0e, 0x02, 0x0f,
12441         0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
12442         0xfe, 0x3c, 0x90, 0x04,
12443         0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
12444         0x04, 0xfe, 0x83, 0x83,
12445         0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
12446 };
12447
12448 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf);       /* 0x1673 */
12449 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL;  /* Expanded little-endian checksum. */
12450
12451 /*
12452  * EEPROM Configuration.
12453  *
12454  * All drivers should use this structure to set the default EEPROM
12455  * configuration. The BIOS now uses this structure when it is built.
12456  * Additional structure information can be found in a_condor.h where
12457  * the structure is defined.
12458  *
12459  * The *_Field_IsChar structs are needed to correct for endianness.
12460  * These values are read from the board 16 bits at a time directly
12461  * into the structs. Because some fields are char, the values will be
12462  * in the wrong order. The *_Field_IsChar tells when to flip the
12463  * bytes. Data read and written to PCI memory is automatically swapped
12464  * on big-endian platforms so char fields read as words are actually being
12465  * unswapped on big-endian platforms.
12466  */
12467 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
12468         ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
12469         0x0000,                 /* cfg_msw */
12470         0xFFFF,                 /* disc_enable */
12471         0xFFFF,                 /* wdtr_able */
12472         0xFFFF,                 /* sdtr_able */
12473         0xFFFF,                 /* start_motor */
12474         0xFFFF,                 /* tagqng_able */
12475         0xFFFF,                 /* bios_scan */
12476         0,                      /* scam_tolerant */
12477         7,                      /* adapter_scsi_id */
12478         0,                      /* bios_boot_delay */
12479         3,                      /* scsi_reset_delay */
12480         0,                      /* bios_id_lun */
12481         0,                      /* termination */
12482         0,                      /* reserved1 */
12483         0xFFE7,                 /* bios_ctrl */
12484         0xFFFF,                 /* ultra_able */
12485         0,                      /* reserved2 */
12486         ASC_DEF_MAX_HOST_QNG,   /* max_host_qng */
12487         ASC_DEF_MAX_DVC_QNG,    /* max_dvc_qng */
12488         0,                      /* dvc_cntl */
12489         0,                      /* bug_fix */
12490         0,                      /* serial_number_word1 */
12491         0,                      /* serial_number_word2 */
12492         0,                      /* serial_number_word3 */
12493         0,                      /* check_sum */
12494         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12495         ,                       /* oem_name[16] */
12496         0,                      /* dvc_err_code */
12497         0,                      /* adv_err_code */
12498         0,                      /* adv_err_addr */
12499         0,                      /* saved_dvc_err_code */
12500         0,                      /* saved_adv_err_code */
12501         0,                      /* saved_adv_err_addr */
12502         0                       /* num_of_err */
12503 };
12504
12505 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
12506         0,                      /* cfg_lsw */
12507         0,                      /* cfg_msw */
12508         0,                      /* -disc_enable */
12509         0,                      /* wdtr_able */
12510         0,                      /* sdtr_able */
12511         0,                      /* start_motor */
12512         0,                      /* tagqng_able */
12513         0,                      /* bios_scan */
12514         0,                      /* scam_tolerant */
12515         1,                      /* adapter_scsi_id */
12516         1,                      /* bios_boot_delay */
12517         1,                      /* scsi_reset_delay */
12518         1,                      /* bios_id_lun */
12519         1,                      /* termination */
12520         1,                      /* reserved1 */
12521         0,                      /* bios_ctrl */
12522         0,                      /* ultra_able */
12523         0,                      /* reserved2 */
12524         1,                      /* max_host_qng */
12525         1,                      /* max_dvc_qng */
12526         0,                      /* dvc_cntl */
12527         0,                      /* bug_fix */
12528         0,                      /* serial_number_word1 */
12529         0,                      /* serial_number_word2 */
12530         0,                      /* serial_number_word3 */
12531         0,                      /* check_sum */
12532         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12533         ,                       /* oem_name[16] */
12534         0,                      /* dvc_err_code */
12535         0,                      /* adv_err_code */
12536         0,                      /* adv_err_addr */
12537         0,                      /* saved_dvc_err_code */
12538         0,                      /* saved_adv_err_code */
12539         0,                      /* saved_adv_err_addr */
12540         0                       /* num_of_err */
12541 };
12542
12543 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
12544         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12545         0x0000,                 /* 01 cfg_msw */
12546         0xFFFF,                 /* 02 disc_enable */
12547         0xFFFF,                 /* 03 wdtr_able */
12548         0x4444,                 /* 04 sdtr_speed1 */
12549         0xFFFF,                 /* 05 start_motor */
12550         0xFFFF,                 /* 06 tagqng_able */
12551         0xFFFF,                 /* 07 bios_scan */
12552         0,                      /* 08 scam_tolerant */
12553         7,                      /* 09 adapter_scsi_id */
12554         0,                      /*    bios_boot_delay */
12555         3,                      /* 10 scsi_reset_delay */
12556         0,                      /*    bios_id_lun */
12557         0,                      /* 11 termination_se */
12558         0,                      /*    termination_lvd */
12559         0xFFE7,                 /* 12 bios_ctrl */
12560         0x4444,                 /* 13 sdtr_speed2 */
12561         0x4444,                 /* 14 sdtr_speed3 */
12562         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
12563         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
12564         0,                      /* 16 dvc_cntl */
12565         0x4444,                 /* 17 sdtr_speed4 */
12566         0,                      /* 18 serial_number_word1 */
12567         0,                      /* 19 serial_number_word2 */
12568         0,                      /* 20 serial_number_word3 */
12569         0,                      /* 21 check_sum */
12570         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12571         ,                       /* 22-29 oem_name[16] */
12572         0,                      /* 30 dvc_err_code */
12573         0,                      /* 31 adv_err_code */
12574         0,                      /* 32 adv_err_addr */
12575         0,                      /* 33 saved_dvc_err_code */
12576         0,                      /* 34 saved_adv_err_code */
12577         0,                      /* 35 saved_adv_err_addr */
12578         0,                      /* 36 reserved */
12579         0,                      /* 37 reserved */
12580         0,                      /* 38 reserved */
12581         0,                      /* 39 reserved */
12582         0,                      /* 40 reserved */
12583         0,                      /* 41 reserved */
12584         0,                      /* 42 reserved */
12585         0,                      /* 43 reserved */
12586         0,                      /* 44 reserved */
12587         0,                      /* 45 reserved */
12588         0,                      /* 46 reserved */
12589         0,                      /* 47 reserved */
12590         0,                      /* 48 reserved */
12591         0,                      /* 49 reserved */
12592         0,                      /* 50 reserved */
12593         0,                      /* 51 reserved */
12594         0,                      /* 52 reserved */
12595         0,                      /* 53 reserved */
12596         0,                      /* 54 reserved */
12597         0,                      /* 55 reserved */
12598         0,                      /* 56 cisptr_lsw */
12599         0,                      /* 57 cisprt_msw */
12600         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
12601         PCI_DEVICE_ID_38C0800_REV1,     /* 59 subsysid */
12602         0,                      /* 60 reserved */
12603         0,                      /* 61 reserved */
12604         0,                      /* 62 reserved */
12605         0                       /* 63 reserved */
12606 };
12607
12608 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12609         0,                      /* 00 cfg_lsw */
12610         0,                      /* 01 cfg_msw */
12611         0,                      /* 02 disc_enable */
12612         0,                      /* 03 wdtr_able */
12613         0,                      /* 04 sdtr_speed1 */
12614         0,                      /* 05 start_motor */
12615         0,                      /* 06 tagqng_able */
12616         0,                      /* 07 bios_scan */
12617         0,                      /* 08 scam_tolerant */
12618         1,                      /* 09 adapter_scsi_id */
12619         1,                      /*    bios_boot_delay */
12620         1,                      /* 10 scsi_reset_delay */
12621         1,                      /*    bios_id_lun */
12622         1,                      /* 11 termination_se */
12623         1,                      /*    termination_lvd */
12624         0,                      /* 12 bios_ctrl */
12625         0,                      /* 13 sdtr_speed2 */
12626         0,                      /* 14 sdtr_speed3 */
12627         1,                      /* 15 max_host_qng */
12628         1,                      /*    max_dvc_qng */
12629         0,                      /* 16 dvc_cntl */
12630         0,                      /* 17 sdtr_speed4 */
12631         0,                      /* 18 serial_number_word1 */
12632         0,                      /* 19 serial_number_word2 */
12633         0,                      /* 20 serial_number_word3 */
12634         0,                      /* 21 check_sum */
12635         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12636         ,                       /* 22-29 oem_name[16] */
12637         0,                      /* 30 dvc_err_code */
12638         0,                      /* 31 adv_err_code */
12639         0,                      /* 32 adv_err_addr */
12640         0,                      /* 33 saved_dvc_err_code */
12641         0,                      /* 34 saved_adv_err_code */
12642         0,                      /* 35 saved_adv_err_addr */
12643         0,                      /* 36 reserved */
12644         0,                      /* 37 reserved */
12645         0,                      /* 38 reserved */
12646         0,                      /* 39 reserved */
12647         0,                      /* 40 reserved */
12648         0,                      /* 41 reserved */
12649         0,                      /* 42 reserved */
12650         0,                      /* 43 reserved */
12651         0,                      /* 44 reserved */
12652         0,                      /* 45 reserved */
12653         0,                      /* 46 reserved */
12654         0,                      /* 47 reserved */
12655         0,                      /* 48 reserved */
12656         0,                      /* 49 reserved */
12657         0,                      /* 50 reserved */
12658         0,                      /* 51 reserved */
12659         0,                      /* 52 reserved */
12660         0,                      /* 53 reserved */
12661         0,                      /* 54 reserved */
12662         0,                      /* 55 reserved */
12663         0,                      /* 56 cisptr_lsw */
12664         0,                      /* 57 cisprt_msw */
12665         0,                      /* 58 subsysvid */
12666         0,                      /* 59 subsysid */
12667         0,                      /* 60 reserved */
12668         0,                      /* 61 reserved */
12669         0,                      /* 62 reserved */
12670         0                       /* 63 reserved */
12671 };
12672
12673 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12674         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12675         0x0000,                 /* 01 cfg_msw */
12676         0xFFFF,                 /* 02 disc_enable */
12677         0xFFFF,                 /* 03 wdtr_able */
12678         0x5555,                 /* 04 sdtr_speed1 */
12679         0xFFFF,                 /* 05 start_motor */
12680         0xFFFF,                 /* 06 tagqng_able */
12681         0xFFFF,                 /* 07 bios_scan */
12682         0,                      /* 08 scam_tolerant */
12683         7,                      /* 09 adapter_scsi_id */
12684         0,                      /*    bios_boot_delay */
12685         3,                      /* 10 scsi_reset_delay */
12686         0,                      /*    bios_id_lun */
12687         0,                      /* 11 termination_se */
12688         0,                      /*    termination_lvd */
12689         0xFFE7,                 /* 12 bios_ctrl */
12690         0x5555,                 /* 13 sdtr_speed2 */
12691         0x5555,                 /* 14 sdtr_speed3 */
12692         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
12693         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
12694         0,                      /* 16 dvc_cntl */
12695         0x5555,                 /* 17 sdtr_speed4 */
12696         0,                      /* 18 serial_number_word1 */
12697         0,                      /* 19 serial_number_word2 */
12698         0,                      /* 20 serial_number_word3 */
12699         0,                      /* 21 check_sum */
12700         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12701         ,                       /* 22-29 oem_name[16] */
12702         0,                      /* 30 dvc_err_code */
12703         0,                      /* 31 adv_err_code */
12704         0,                      /* 32 adv_err_addr */
12705         0,                      /* 33 saved_dvc_err_code */
12706         0,                      /* 34 saved_adv_err_code */
12707         0,                      /* 35 saved_adv_err_addr */
12708         0,                      /* 36 reserved */
12709         0,                      /* 37 reserved */
12710         0,                      /* 38 reserved */
12711         0,                      /* 39 reserved */
12712         0,                      /* 40 reserved */
12713         0,                      /* 41 reserved */
12714         0,                      /* 42 reserved */
12715         0,                      /* 43 reserved */
12716         0,                      /* 44 reserved */
12717         0,                      /* 45 reserved */
12718         0,                      /* 46 reserved */
12719         0,                      /* 47 reserved */
12720         0,                      /* 48 reserved */
12721         0,                      /* 49 reserved */
12722         0,                      /* 50 reserved */
12723         0,                      /* 51 reserved */
12724         0,                      /* 52 reserved */
12725         0,                      /* 53 reserved */
12726         0,                      /* 54 reserved */
12727         0,                      /* 55 reserved */
12728         0,                      /* 56 cisptr_lsw */
12729         0,                      /* 57 cisprt_msw */
12730         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
12731         PCI_DEVICE_ID_38C1600_REV1,     /* 59 subsysid */
12732         0,                      /* 60 reserved */
12733         0,                      /* 61 reserved */
12734         0,                      /* 62 reserved */
12735         0                       /* 63 reserved */
12736 };
12737
12738 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12739         0,                      /* 00 cfg_lsw */
12740         0,                      /* 01 cfg_msw */
12741         0,                      /* 02 disc_enable */
12742         0,                      /* 03 wdtr_able */
12743         0,                      /* 04 sdtr_speed1 */
12744         0,                      /* 05 start_motor */
12745         0,                      /* 06 tagqng_able */
12746         0,                      /* 07 bios_scan */
12747         0,                      /* 08 scam_tolerant */
12748         1,                      /* 09 adapter_scsi_id */
12749         1,                      /*    bios_boot_delay */
12750         1,                      /* 10 scsi_reset_delay */
12751         1,                      /*    bios_id_lun */
12752         1,                      /* 11 termination_se */
12753         1,                      /*    termination_lvd */
12754         0,                      /* 12 bios_ctrl */
12755         0,                      /* 13 sdtr_speed2 */
12756         0,                      /* 14 sdtr_speed3 */
12757         1,                      /* 15 max_host_qng */
12758         1,                      /*    max_dvc_qng */
12759         0,                      /* 16 dvc_cntl */
12760         0,                      /* 17 sdtr_speed4 */
12761         0,                      /* 18 serial_number_word1 */
12762         0,                      /* 19 serial_number_word2 */
12763         0,                      /* 20 serial_number_word3 */
12764         0,                      /* 21 check_sum */
12765         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12766         ,                       /* 22-29 oem_name[16] */
12767         0,                      /* 30 dvc_err_code */
12768         0,                      /* 31 adv_err_code */
12769         0,                      /* 32 adv_err_addr */
12770         0,                      /* 33 saved_dvc_err_code */
12771         0,                      /* 34 saved_adv_err_code */
12772         0,                      /* 35 saved_adv_err_addr */
12773         0,                      /* 36 reserved */
12774         0,                      /* 37 reserved */
12775         0,                      /* 38 reserved */
12776         0,                      /* 39 reserved */
12777         0,                      /* 40 reserved */
12778         0,                      /* 41 reserved */
12779         0,                      /* 42 reserved */
12780         0,                      /* 43 reserved */
12781         0,                      /* 44 reserved */
12782         0,                      /* 45 reserved */
12783         0,                      /* 46 reserved */
12784         0,                      /* 47 reserved */
12785         0,                      /* 48 reserved */
12786         0,                      /* 49 reserved */
12787         0,                      /* 50 reserved */
12788         0,                      /* 51 reserved */
12789         0,                      /* 52 reserved */
12790         0,                      /* 53 reserved */
12791         0,                      /* 54 reserved */
12792         0,                      /* 55 reserved */
12793         0,                      /* 56 cisptr_lsw */
12794         0,                      /* 57 cisprt_msw */
12795         0,                      /* 58 subsysvid */
12796         0,                      /* 59 subsysid */
12797         0,                      /* 60 reserved */
12798         0,                      /* 61 reserved */
12799         0,                      /* 62 reserved */
12800         0                       /* 63 reserved */
12801 };
12802
12803 /*
12804  * Initialize the ADV_DVC_VAR structure.
12805  *
12806  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12807  *
12808  * For a non-fatal error return a warning code. If there are no warnings
12809  * then 0 is returned.
12810  */
12811 static int __devinit
12812 AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc)
12813 {
12814         unsigned short warn_code = 0;
12815         AdvPortAddr iop_base = asc_dvc->iop_base;
12816         u16 cmd;
12817         int status;
12818
12819         asc_dvc->err_code = 0;
12820
12821         /*
12822          * Save the state of the PCI Configuration Command Register
12823          * "Parity Error Response Control" Bit. If the bit is clear (0),
12824          * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
12825          * DMA parity errors.
12826          */
12827         asc_dvc->cfg->control_flag = 0;
12828         pci_read_config_word(pdev, PCI_COMMAND, &cmd);
12829         if ((cmd & PCI_COMMAND_PARITY) == 0)
12830                 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
12831
12832         asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
12833             ADV_LIB_VERSION_MINOR;
12834         asc_dvc->cfg->chip_version =
12835             AdvGetChipVersion(iop_base, asc_dvc->bus_type);
12836
12837         ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
12838                  (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
12839                  (ushort)ADV_CHIP_ID_BYTE);
12840
12841         ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
12842                  (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
12843                  (ushort)ADV_CHIP_ID_WORD);
12844
12845         /*
12846          * Reset the chip to start and allow register writes.
12847          */
12848         if (AdvFindSignature(iop_base) == 0) {
12849                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12850                 return ADV_ERROR;
12851         } else {
12852                 /*
12853                  * The caller must set 'chip_type' to a valid setting.
12854                  */
12855                 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
12856                     asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
12857                     asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
12858                         asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
12859                         return ADV_ERROR;
12860                 }
12861
12862                 /*
12863                  * Reset Chip.
12864                  */
12865                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
12866                                      ADV_CTRL_REG_CMD_RESET);
12867                 DvcSleepMilliSecond(100);
12868                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
12869                                      ADV_CTRL_REG_CMD_WR_IO_REG);
12870
12871                 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
12872                         status = AdvInitFrom38C1600EEP(asc_dvc);
12873                 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
12874                         status = AdvInitFrom38C0800EEP(asc_dvc);
12875                 } else {
12876                         status = AdvInitFrom3550EEP(asc_dvc);
12877                 }
12878                 warn_code |= status;
12879         }
12880
12881         return warn_code;
12882 }
12883
12884 static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
12885 {
12886         ADV_CARR_T *carrp;
12887         ADV_SDCNT buf_size;
12888         ADV_PADDR carr_paddr;
12889
12890         BUG_ON(!asc_dvc->carrier_buf);
12891
12892         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
12893         asc_dvc->carr_freelist = NULL;
12894         if (carrp == asc_dvc->carrier_buf) {
12895                 buf_size = ADV_CARRIER_BUFSIZE;
12896         } else {
12897                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
12898         }
12899
12900         do {
12901                 /* Get physical address of the carrier 'carrp'. */
12902                 ADV_DCNT contig_len = sizeof(ADV_CARR_T);
12903                 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
12904                                                        (uchar *)carrp,
12905                                                        (ADV_SDCNT *)&contig_len,
12906                                                        ADV_IS_CARRIER_FLAG));
12907
12908                 buf_size -= sizeof(ADV_CARR_T);
12909
12910                 /*
12911                  * If the current carrier is not physically contiguous, then
12912                  * maybe there was a page crossing. Try the next carrier
12913                  * aligned start address.
12914                  */
12915                 if (contig_len < sizeof(ADV_CARR_T)) {
12916                         carrp++;
12917                         continue;
12918                 }
12919
12920                 carrp->carr_pa = carr_paddr;
12921                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
12922
12923                 /*
12924                  * Insert the carrier at the beginning of the freelist.
12925                  */
12926                 carrp->next_vpa =
12927                         cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
12928                 asc_dvc->carr_freelist = carrp;
12929
12930                 carrp++;
12931         } while (buf_size > 0);
12932 }
12933
12934 /*
12935  * Initialize the ASC-3550.
12936  *
12937  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12938  *
12939  * For a non-fatal error return a warning code. If there are no warnings
12940  * then 0 is returned.
12941  *
12942  * Needed after initialization for error recovery.
12943  */
12944 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
12945 {
12946         AdvPortAddr iop_base;
12947         ushort warn_code;
12948         ADV_DCNT sum;
12949         int begin_addr;
12950         int end_addr;
12951         ushort code_sum;
12952         int word;
12953         int j;
12954         int adv_asc3550_expanded_size;
12955         int i;
12956         ushort scsi_cfg1;
12957         uchar tid;
12958         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
12959         ushort wdtr_able = 0, sdtr_able, tagqng_able;
12960         uchar max_cmd[ADV_MAX_TID + 1];
12961
12962         /* If there is already an error, don't continue. */
12963         if (asc_dvc->err_code != 0) {
12964                 return ADV_ERROR;
12965         }
12966
12967         /*
12968          * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
12969          */
12970         if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
12971                 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
12972                 return ADV_ERROR;
12973         }
12974
12975         warn_code = 0;
12976         iop_base = asc_dvc->iop_base;
12977
12978         /*
12979          * Save the RISC memory BIOS region before writing the microcode.
12980          * The BIOS may already be loaded and using its RISC LRAM region
12981          * so its region must be saved and restored.
12982          *
12983          * Note: This code makes the assumption, which is currently true,
12984          * that a chip reset does not clear RISC LRAM.
12985          */
12986         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
12987                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
12988                                 bios_mem[i]);
12989         }
12990
12991         /*
12992          * Save current per TID negotiated values.
12993          */
12994         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
12995                 ushort bios_version, major, minor;
12996
12997                 bios_version =
12998                     bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
12999                 major = (bios_version >> 12) & 0xF;
13000                 minor = (bios_version >> 8) & 0xF;
13001                 if (major < 3 || (major == 3 && minor == 1)) {
13002                         /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
13003                         AdvReadWordLram(iop_base, 0x120, wdtr_able);
13004                 } else {
13005                         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13006                 }
13007         }
13008         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13009         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13010         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13011                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13012                                 max_cmd[tid]);
13013         }
13014
13015         /*
13016          * Load the Microcode
13017          *
13018          * Write the microcode image to RISC memory starting at address 0.
13019          */
13020         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13021         /* Assume the following compressed format of the microcode buffer:
13022          *
13023          *  254 word (508 byte) table indexed by byte code followed
13024          *  by the following byte codes:
13025          *
13026          *    1-Byte Code:
13027          *      00: Emit word 0 in table.
13028          *      01: Emit word 1 in table.
13029          *      .
13030          *      FD: Emit word 253 in table.
13031          *
13032          *    Multi-Byte Code:
13033          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
13034          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
13035          */
13036         word = 0;
13037         for (i = 253 * 2; i < _adv_asc3550_size; i++) {
13038                 if (_adv_asc3550_buf[i] == 0xff) {
13039                         for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
13040                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13041                                                                     _adv_asc3550_buf
13042                                                                     [i +
13043                                                                      3] << 8) |
13044                                                                    _adv_asc3550_buf
13045                                                                    [i + 2]));
13046                                 word++;
13047                         }
13048                         i += 3;
13049                 } else if (_adv_asc3550_buf[i] == 0xfe) {
13050                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
13051                                                             _adv_asc3550_buf[i +
13052                                                                              2]
13053                                                             << 8) |
13054                                                            _adv_asc3550_buf[i +
13055                                                                             1]));
13056                         i += 2;
13057                         word++;
13058                 } else {
13059                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
13060                                                             _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
13061                         word++;
13062                 }
13063         }
13064
13065         /*
13066          * Set 'word' for later use to clear the rest of memory and save
13067          * the expanded mcode size.
13068          */
13069         word *= 2;
13070         adv_asc3550_expanded_size = word;
13071
13072         /*
13073          * Clear the rest of ASC-3550 Internal RAM (8KB).
13074          */
13075         for (; word < ADV_3550_MEMSIZE; word += 2) {
13076                 AdvWriteWordAutoIncLram(iop_base, 0);
13077         }
13078
13079         /*
13080          * Verify the microcode checksum.
13081          */
13082         sum = 0;
13083         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13084
13085         for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
13086                 sum += AdvReadWordAutoIncLram(iop_base);
13087         }
13088
13089         if (sum != _adv_asc3550_chksum) {
13090                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13091                 return ADV_ERROR;
13092         }
13093
13094         /*
13095          * Restore the RISC memory BIOS region.
13096          */
13097         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13098                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13099                                  bios_mem[i]);
13100         }
13101
13102         /*
13103          * Calculate and write the microcode code checksum to the microcode
13104          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13105          */
13106         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13107         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13108         code_sum = 0;
13109         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13110         for (word = begin_addr; word < end_addr; word += 2) {
13111                 code_sum += AdvReadWordAutoIncLram(iop_base);
13112         }
13113         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13114
13115         /*
13116          * Read and save microcode version and date.
13117          */
13118         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13119                         asc_dvc->cfg->mcode_date);
13120         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13121                         asc_dvc->cfg->mcode_version);
13122
13123         /*
13124          * Set the chip type to indicate the ASC3550.
13125          */
13126         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
13127
13128         /*
13129          * If the PCI Configuration Command Register "Parity Error Response
13130          * Control" Bit was clear (0), then set the microcode variable
13131          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13132          * to ignore DMA parity errors.
13133          */
13134         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13135                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13136                 word |= CONTROL_FLAG_IGNORE_PERR;
13137                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13138         }
13139
13140         /*
13141          * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
13142          * threshold of 128 bytes. This register is only accessible to the host.
13143          */
13144         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13145                              START_CTL_EMFU | READ_CMD_MRM);
13146
13147         /*
13148          * Microcode operating variables for WDTR, SDTR, and command tag
13149          * queuing will be set in slave_configure() based on what a
13150          * device reports it is capable of in Inquiry byte 7.
13151          *
13152          * If SCSI Bus Resets have been disabled, then directly set
13153          * SDTR and WDTR from the EEPROM configuration. This will allow
13154          * the BIOS and warm boot to work without a SCSI bus hang on
13155          * the Inquiry caused by host and target mismatched DTR values.
13156          * Without the SCSI Bus Reset, before an Inquiry a device can't
13157          * be assumed to be in Asynchronous, Narrow mode.
13158          */
13159         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13160                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13161                                  asc_dvc->wdtr_able);
13162                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13163                                  asc_dvc->sdtr_able);
13164         }
13165
13166         /*
13167          * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
13168          * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
13169          * bitmask. These values determine the maximum SDTR speed negotiated
13170          * with a device.
13171          *
13172          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13173          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13174          * without determining here whether the device supports SDTR.
13175          *
13176          * 4-bit speed  SDTR speed name
13177          * ===========  ===============
13178          * 0000b (0x0)  SDTR disabled
13179          * 0001b (0x1)  5 Mhz
13180          * 0010b (0x2)  10 Mhz
13181          * 0011b (0x3)  20 Mhz (Ultra)
13182          * 0100b (0x4)  40 Mhz (LVD/Ultra2)
13183          * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
13184          * 0110b (0x6)  Undefined
13185          * .
13186          * 1111b (0xF)  Undefined
13187          */
13188         word = 0;
13189         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13190                 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
13191                         /* Set Ultra speed for TID 'tid'. */
13192                         word |= (0x3 << (4 * (tid % 4)));
13193                 } else {
13194                         /* Set Fast speed for TID 'tid'. */
13195                         word |= (0x2 << (4 * (tid % 4)));
13196                 }
13197                 if (tid == 3) { /* Check if done with sdtr_speed1. */
13198                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
13199                         word = 0;
13200                 } else if (tid == 7) {  /* Check if done with sdtr_speed2. */
13201                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
13202                         word = 0;
13203                 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
13204                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
13205                         word = 0;
13206                 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
13207                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
13208                         /* End of loop. */
13209                 }
13210         }
13211
13212         /*
13213          * Set microcode operating variable for the disconnect per TID bitmask.
13214          */
13215         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
13216                          asc_dvc->cfg->disc_enable);
13217
13218         /*
13219          * Set SCSI_CFG0 Microcode Default Value.
13220          *
13221          * The microcode will set the SCSI_CFG0 register using this value
13222          * after it is started below.
13223          */
13224         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
13225                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
13226                          asc_dvc->chip_scsi_id);
13227
13228         /*
13229          * Determine SCSI_CFG1 Microcode Default Value.
13230          *
13231          * The microcode will set the SCSI_CFG1 register using this value
13232          * after it is started below.
13233          */
13234
13235         /* Read current SCSI_CFG1 Register value. */
13236         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13237
13238         /*
13239          * If all three connectors are in use, return an error.
13240          */
13241         if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
13242             (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
13243                 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
13244                 return ADV_ERROR;
13245         }
13246
13247         /*
13248          * If the internal narrow cable is reversed all of the SCSI_CTRL
13249          * register signals will be set. Check for and return an error if
13250          * this condition is found.
13251          */
13252         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
13253                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
13254                 return ADV_ERROR;
13255         }
13256
13257         /*
13258          * If this is a differential board and a single-ended device
13259          * is attached to one of the connectors, return an error.
13260          */
13261         if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
13262                 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
13263                 return ADV_ERROR;
13264         }
13265
13266         /*
13267          * If automatic termination control is enabled, then set the
13268          * termination value based on a table listed in a_condor.h.
13269          *
13270          * If manual termination was specified with an EEPROM setting
13271          * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
13272          * is ready to be 'ored' into SCSI_CFG1.
13273          */
13274         if (asc_dvc->cfg->termination == 0) {
13275                 /*
13276                  * The software always controls termination by setting TERM_CTL_SEL.
13277                  * If TERM_CTL_SEL were set to 0, the hardware would set termination.
13278                  */
13279                 asc_dvc->cfg->termination |= TERM_CTL_SEL;
13280
13281                 switch (scsi_cfg1 & CABLE_DETECT) {
13282                         /* TERM_CTL_H: on, TERM_CTL_L: on */
13283                 case 0x3:
13284                 case 0x7:
13285                 case 0xB:
13286                 case 0xD:
13287                 case 0xE:
13288                 case 0xF:
13289                         asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
13290                         break;
13291
13292                         /* TERM_CTL_H: on, TERM_CTL_L: off */
13293                 case 0x1:
13294                 case 0x5:
13295                 case 0x9:
13296                 case 0xA:
13297                 case 0xC:
13298                         asc_dvc->cfg->termination |= TERM_CTL_H;
13299                         break;
13300
13301                         /* TERM_CTL_H: off, TERM_CTL_L: off */
13302                 case 0x2:
13303                 case 0x6:
13304                         break;
13305                 }
13306         }
13307
13308         /*
13309          * Clear any set TERM_CTL_H and TERM_CTL_L bits.
13310          */
13311         scsi_cfg1 &= ~TERM_CTL;
13312
13313         /*
13314          * Invert the TERM_CTL_H and TERM_CTL_L bits and then
13315          * set 'scsi_cfg1'. The TERM_POL bit does not need to be
13316          * referenced, because the hardware internally inverts
13317          * the Termination High and Low bits if TERM_POL is set.
13318          */
13319         scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
13320
13321         /*
13322          * Set SCSI_CFG1 Microcode Default Value
13323          *
13324          * Set filter value and possibly modified termination control
13325          * bits in the Microcode SCSI_CFG1 Register Value.
13326          *
13327          * The microcode will set the SCSI_CFG1 register using this value
13328          * after it is started below.
13329          */
13330         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
13331                          FLTR_DISABLE | scsi_cfg1);
13332
13333         /*
13334          * Set MEM_CFG Microcode Default Value
13335          *
13336          * The microcode will set the MEM_CFG register using this value
13337          * after it is started below.
13338          *
13339          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
13340          * are defined.
13341          *
13342          * ASC-3550 has 8KB internal memory.
13343          */
13344         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
13345                          BIOS_EN | RAM_SZ_8KB);
13346
13347         /*
13348          * Set SEL_MASK Microcode Default Value
13349          *
13350          * The microcode will set the SEL_MASK register using this value
13351          * after it is started below.
13352          */
13353         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
13354                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
13355
13356         AdvBuildCarrierFreelist(asc_dvc);
13357
13358         /*
13359          * Set-up the Host->RISC Initiator Command Queue (ICQ).
13360          */
13361
13362         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
13363                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
13364                 return ADV_ERROR;
13365         }
13366         asc_dvc->carr_freelist = (ADV_CARR_T *)
13367             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
13368
13369         /*
13370          * The first command issued will be placed in the stopper carrier.
13371          */
13372         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13373
13374         /*
13375          * Set RISC ICQ physical address start value.
13376          */
13377         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
13378
13379         /*
13380          * Set-up the RISC->Host Initiator Response Queue (IRQ).
13381          */
13382         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
13383                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
13384                 return ADV_ERROR;
13385         }
13386         asc_dvc->carr_freelist = (ADV_CARR_T *)
13387             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
13388
13389         /*
13390          * The first command completed by the RISC will be placed in
13391          * the stopper.
13392          *
13393          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
13394          * completed the RISC will set the ASC_RQ_STOPPER bit.
13395          */
13396         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13397
13398         /*
13399          * Set RISC IRQ physical address start value.
13400          */
13401         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
13402         asc_dvc->carr_pending_cnt = 0;
13403
13404         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
13405                              (ADV_INTR_ENABLE_HOST_INTR |
13406                               ADV_INTR_ENABLE_GLOBAL_INTR));
13407
13408         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
13409         AdvWriteWordRegister(iop_base, IOPW_PC, word);
13410
13411         /* finally, finally, gentlemen, start your engine */
13412         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
13413
13414         /*
13415          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
13416          * Resets should be performed. The RISC has to be running
13417          * to issue a SCSI Bus Reset.
13418          */
13419         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
13420                 /*
13421                  * If the BIOS Signature is present in memory, restore the
13422                  * BIOS Handshake Configuration Table and do not perform
13423                  * a SCSI Bus Reset.
13424                  */
13425                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
13426                     0x55AA) {
13427                         /*
13428                          * Restore per TID negotiated values.
13429                          */
13430                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13431                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13432                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
13433                                          tagqng_able);
13434                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13435                                 AdvWriteByteLram(iop_base,
13436                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
13437                                                  max_cmd[tid]);
13438                         }
13439                 } else {
13440                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
13441                                 warn_code = ASC_WARN_BUSRESET_ERROR;
13442                         }
13443                 }
13444         }
13445
13446         return warn_code;
13447 }
13448
13449 /*
13450  * Initialize the ASC-38C0800.
13451  *
13452  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13453  *
13454  * For a non-fatal error return a warning code. If there are no warnings
13455  * then 0 is returned.
13456  *
13457  * Needed after initialization for error recovery.
13458  */
13459 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
13460 {
13461         AdvPortAddr iop_base;
13462         ushort warn_code;
13463         ADV_DCNT sum;
13464         int begin_addr;
13465         int end_addr;
13466         ushort code_sum;
13467         int word;
13468         int j;
13469         int adv_asc38C0800_expanded_size;
13470         int i;
13471         ushort scsi_cfg1;
13472         uchar byte;
13473         uchar tid;
13474         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
13475         ushort wdtr_able, sdtr_able, tagqng_able;
13476         uchar max_cmd[ADV_MAX_TID + 1];
13477
13478         /* If there is already an error, don't continue. */
13479         if (asc_dvc->err_code != 0) {
13480                 return ADV_ERROR;
13481         }
13482
13483         /*
13484          * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
13485          */
13486         if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
13487                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
13488                 return ADV_ERROR;
13489         }
13490
13491         warn_code = 0;
13492         iop_base = asc_dvc->iop_base;
13493
13494         /*
13495          * Save the RISC memory BIOS region before writing the microcode.
13496          * The BIOS may already be loaded and using its RISC LRAM region
13497          * so its region must be saved and restored.
13498          *
13499          * Note: This code makes the assumption, which is currently true,
13500          * that a chip reset does not clear RISC LRAM.
13501          */
13502         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13503                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13504                                 bios_mem[i]);
13505         }
13506
13507         /*
13508          * Save current per TID negotiated values.
13509          */
13510         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13511         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13512         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
13513         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13514                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
13515                                 max_cmd[tid]);
13516         }
13517
13518         /*
13519          * RAM BIST (RAM Built-In Self Test)
13520          *
13521          * Address : I/O base + offset 0x38h register (byte).
13522          * Function: Bit 7-6(RW) : RAM mode
13523          *                          Normal Mode   : 0x00
13524          *                          Pre-test Mode : 0x40
13525          *                          RAM Test Mode : 0x80
13526          *           Bit 5       : unused
13527          *           Bit 4(RO)   : Done bit
13528          *           Bit 3-0(RO) : Status
13529          *                          Host Error    : 0x08
13530          *                          Int_RAM Error : 0x04
13531          *                          RISC Error    : 0x02
13532          *                          SCSI Error    : 0x01
13533          *                          No Error      : 0x00
13534          *
13535          * Note: RAM BIST code should be put right here, before loading the
13536          * microcode and after saving the RISC memory BIOS region.
13537          */
13538
13539         /*
13540          * LRAM Pre-test
13541          *
13542          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
13543          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
13544          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
13545          * to NORMAL_MODE, return an error too.
13546          */
13547         for (i = 0; i < 2; i++) {
13548                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
13549                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
13550                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
13551                 if ((byte & RAM_TEST_DONE) == 0
13552                     || (byte & 0x0F) != PRE_TEST_VALUE) {
13553                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
13554                         return ADV_ERROR;
13555                 }
13556
13557                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
13558                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
13559                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
13560                     != NORMAL_VALUE) {
13561                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
13562                         return ADV_ERROR;
13563                 }
13564         }
13565
13566         /*
13567          * LRAM Test - It takes about 1.5 ms to run through the test.
13568          *
13569          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
13570          * If Done bit not set or Status not 0, save register byte, set the
13571          * err_code, and return an error.
13572          */
13573         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
13574         DvcSleepMilliSecond(10);        /* Wait for 10ms before checking status. */
13575
13576         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
13577         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
13578                 /* Get here if Done bit not set or Status not 0. */
13579                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
13580                 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
13581                 return ADV_ERROR;
13582         }
13583
13584         /* We need to reset back to normal mode after LRAM test passes. */
13585         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
13586
13587         /*
13588          * Load the Microcode
13589          *
13590          * Write the microcode image to RISC memory starting at address 0.
13591          *
13592          */
13593         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13594
13595         /* Assume the following compressed format of the microcode buffer:
13596          *
13597          *  254 word (508 byte) table indexed by byte code followed
13598          *  by the following byte codes:
13599          *
13600          *    1-Byte Code:
13601          *      00: Emit word 0 in table.
13602          *      01: Emit word 1 in table.
13603          *      .
13604          *      FD: Emit word 253 in table.
13605          *
13606          *    Multi-Byte Code:
13607          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
13608          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
13609          */
13610         word = 0;
13611         for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
13612                 if (_adv_asc38C0800_buf[i] == 0xff) {
13613                         for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
13614                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
13615                                                                     _adv_asc38C0800_buf
13616                                                                     [i +
13617                                                                      3] << 8) |
13618                                                                    _adv_asc38C0800_buf
13619                                                                    [i + 2]));
13620                                 word++;
13621                         }
13622                         i += 3;
13623                 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
13624                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
13625                                                             _adv_asc38C0800_buf
13626                                                             [i +
13627                                                              2] << 8) |
13628                                                            _adv_asc38C0800_buf[i
13629                                                                                +
13630                                                                                1]));
13631                         i += 2;
13632                         word++;
13633                 } else {
13634                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
13635                                                             _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
13636                         word++;
13637                 }
13638         }
13639
13640         /*
13641          * Set 'word' for later use to clear the rest of memory and save
13642          * the expanded mcode size.
13643          */
13644         word *= 2;
13645         adv_asc38C0800_expanded_size = word;
13646
13647         /*
13648          * Clear the rest of ASC-38C0800 Internal RAM (16KB).
13649          */
13650         for (; word < ADV_38C0800_MEMSIZE; word += 2) {
13651                 AdvWriteWordAutoIncLram(iop_base, 0);
13652         }
13653
13654         /*
13655          * Verify the microcode checksum.
13656          */
13657         sum = 0;
13658         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
13659
13660         for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
13661                 sum += AdvReadWordAutoIncLram(iop_base);
13662         }
13663         ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
13664
13665         ASC_DBG2(1,
13666                  "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
13667                  (ulong)sum, (ulong)_adv_asc38C0800_chksum);
13668
13669         if (sum != _adv_asc38C0800_chksum) {
13670                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
13671                 return ADV_ERROR;
13672         }
13673
13674         /*
13675          * Restore the RISC memory BIOS region.
13676          */
13677         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
13678                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
13679                                  bios_mem[i]);
13680         }
13681
13682         /*
13683          * Calculate and write the microcode code checksum to the microcode
13684          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
13685          */
13686         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
13687         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
13688         code_sum = 0;
13689         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
13690         for (word = begin_addr; word < end_addr; word += 2) {
13691                 code_sum += AdvReadWordAutoIncLram(iop_base);
13692         }
13693         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
13694
13695         /*
13696          * Read microcode version and date.
13697          */
13698         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
13699                         asc_dvc->cfg->mcode_date);
13700         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
13701                         asc_dvc->cfg->mcode_version);
13702
13703         /*
13704          * Set the chip type to indicate the ASC38C0800.
13705          */
13706         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
13707
13708         /*
13709          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
13710          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
13711          * cable detection and then we are able to read C_DET[3:0].
13712          *
13713          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
13714          * Microcode Default Value' section below.
13715          */
13716         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13717         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
13718                              scsi_cfg1 | DIS_TERM_DRV);
13719
13720         /*
13721          * If the PCI Configuration Command Register "Parity Error Response
13722          * Control" Bit was clear (0), then set the microcode variable
13723          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
13724          * to ignore DMA parity errors.
13725          */
13726         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
13727                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13728                 word |= CONTROL_FLAG_IGNORE_PERR;
13729                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
13730         }
13731
13732         /*
13733          * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
13734          * bits for the default FIFO threshold.
13735          *
13736          * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
13737          *
13738          * For DMA Errata #4 set the BC_THRESH_ENB bit.
13739          */
13740         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
13741                              BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
13742                              READ_CMD_MRM);
13743
13744         /*
13745          * Microcode operating variables for WDTR, SDTR, and command tag
13746          * queuing will be set in slave_configure() based on what a
13747          * device reports it is capable of in Inquiry byte 7.
13748          *
13749          * If SCSI Bus Resets have been disabled, then directly set
13750          * SDTR and WDTR from the EEPROM configuration. This will allow
13751          * the BIOS and warm boot to work without a SCSI bus hang on
13752          * the Inquiry caused by host and target mismatched DTR values.
13753          * Without the SCSI Bus Reset, before an Inquiry a device can't
13754          * be assumed to be in Asynchronous, Narrow mode.
13755          */
13756         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
13757                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
13758                                  asc_dvc->wdtr_able);
13759                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
13760                                  asc_dvc->sdtr_able);
13761         }
13762
13763         /*
13764          * Set microcode operating variables for DISC and SDTR_SPEED1,
13765          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
13766          * configuration values.
13767          *
13768          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
13769          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
13770          * without determining here whether the device supports SDTR.
13771          */
13772         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
13773                          asc_dvc->cfg->disc_enable);
13774         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
13775         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
13776         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
13777         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
13778
13779         /*
13780          * Set SCSI_CFG0 Microcode Default Value.
13781          *
13782          * The microcode will set the SCSI_CFG0 register using this value
13783          * after it is started below.
13784          */
13785         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
13786                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
13787                          asc_dvc->chip_scsi_id);
13788
13789         /*
13790          * Determine SCSI_CFG1 Microcode Default Value.
13791          *
13792          * The microcode will set the SCSI_CFG1 register using this value
13793          * after it is started below.
13794          */
13795
13796         /* Read current SCSI_CFG1 Register value. */
13797         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
13798
13799         /*
13800          * If the internal narrow cable is reversed all of the SCSI_CTRL
13801          * register signals will be set. Check for and return an error if
13802          * this condition is found.
13803          */
13804         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
13805                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
13806                 return ADV_ERROR;
13807         }
13808
13809         /*
13810          * All kind of combinations of devices attached to one of four connectors
13811          * are acceptable except HVD device attached. For example, LVD device can
13812          * be attached to SE connector while SE device attached to LVD connector.
13813          * If LVD device attached to SE connector, it only runs up to Ultra speed.
13814          *
13815          * If an HVD device is attached to one of LVD connectors, return an error.
13816          * However, there is no way to detect HVD device attached to SE connectors.
13817          */
13818         if (scsi_cfg1 & HVD) {
13819                 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
13820                 return ADV_ERROR;
13821         }
13822
13823         /*
13824          * If either SE or LVD automatic termination control is enabled, then
13825          * set the termination value based on a table listed in a_condor.h.
13826          *
13827          * If manual termination was specified with an EEPROM setting then
13828          * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
13829          * be 'ored' into SCSI_CFG1.
13830          */
13831         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
13832                 /* SE automatic termination control is enabled. */
13833                 switch (scsi_cfg1 & C_DET_SE) {
13834                         /* TERM_SE_HI: on, TERM_SE_LO: on */
13835                 case 0x1:
13836                 case 0x2:
13837                 case 0x3:
13838                         asc_dvc->cfg->termination |= TERM_SE;
13839                         break;
13840
13841                         /* TERM_SE_HI: on, TERM_SE_LO: off */
13842                 case 0x0:
13843                         asc_dvc->cfg->termination |= TERM_SE_HI;
13844                         break;
13845                 }
13846         }
13847
13848         if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
13849                 /* LVD automatic termination control is enabled. */
13850                 switch (scsi_cfg1 & C_DET_LVD) {
13851                         /* TERM_LVD_HI: on, TERM_LVD_LO: on */
13852                 case 0x4:
13853                 case 0x8:
13854                 case 0xC:
13855                         asc_dvc->cfg->termination |= TERM_LVD;
13856                         break;
13857
13858                         /* TERM_LVD_HI: off, TERM_LVD_LO: off */
13859                 case 0x0:
13860                         break;
13861                 }
13862         }
13863
13864         /*
13865          * Clear any set TERM_SE and TERM_LVD bits.
13866          */
13867         scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
13868
13869         /*
13870          * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
13871          */
13872         scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
13873
13874         /*
13875          * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
13876          * and set possibly modified termination control bits in the Microcode
13877          * SCSI_CFG1 Register Value.
13878          */
13879         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
13880
13881         /*
13882          * Set SCSI_CFG1 Microcode Default Value
13883          *
13884          * Set possibly modified termination control and reset DIS_TERM_DRV
13885          * bits in the Microcode SCSI_CFG1 Register Value.
13886          *
13887          * The microcode will set the SCSI_CFG1 register using this value
13888          * after it is started below.
13889          */
13890         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
13891
13892         /*
13893          * Set MEM_CFG Microcode Default Value
13894          *
13895          * The microcode will set the MEM_CFG register using this value
13896          * after it is started below.
13897          *
13898          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
13899          * are defined.
13900          *
13901          * ASC-38C0800 has 16KB internal memory.
13902          */
13903         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
13904                          BIOS_EN | RAM_SZ_16KB);
13905
13906         /*
13907          * Set SEL_MASK Microcode Default Value
13908          *
13909          * The microcode will set the SEL_MASK register using this value
13910          * after it is started below.
13911          */
13912         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
13913                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
13914
13915         AdvBuildCarrierFreelist(asc_dvc);
13916
13917         /*
13918          * Set-up the Host->RISC Initiator Command Queue (ICQ).
13919          */
13920
13921         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
13922                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
13923                 return ADV_ERROR;
13924         }
13925         asc_dvc->carr_freelist = (ADV_CARR_T *)
13926             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
13927
13928         /*
13929          * The first command issued will be placed in the stopper carrier.
13930          */
13931         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13932
13933         /*
13934          * Set RISC ICQ physical address start value.
13935          * carr_pa is LE, must be native before write
13936          */
13937         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
13938
13939         /*
13940          * Set-up the RISC->Host Initiator Response Queue (IRQ).
13941          */
13942         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
13943                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
13944                 return ADV_ERROR;
13945         }
13946         asc_dvc->carr_freelist = (ADV_CARR_T *)
13947             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
13948
13949         /*
13950          * The first command completed by the RISC will be placed in
13951          * the stopper.
13952          *
13953          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
13954          * completed the RISC will set the ASC_RQ_STOPPER bit.
13955          */
13956         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
13957
13958         /*
13959          * Set RISC IRQ physical address start value.
13960          *
13961          * carr_pa is LE, must be native before write *
13962          */
13963         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
13964         asc_dvc->carr_pending_cnt = 0;
13965
13966         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
13967                              (ADV_INTR_ENABLE_HOST_INTR |
13968                               ADV_INTR_ENABLE_GLOBAL_INTR));
13969
13970         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
13971         AdvWriteWordRegister(iop_base, IOPW_PC, word);
13972
13973         /* finally, finally, gentlemen, start your engine */
13974         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
13975
13976         /*
13977          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
13978          * Resets should be performed. The RISC has to be running
13979          * to issue a SCSI Bus Reset.
13980          */
13981         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
13982                 /*
13983                  * If the BIOS Signature is present in memory, restore the
13984                  * BIOS Handshake Configuration Table and do not perform
13985                  * a SCSI Bus Reset.
13986                  */
13987                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
13988                     0x55AA) {
13989                         /*
13990                          * Restore per TID negotiated values.
13991                          */
13992                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
13993                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
13994                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
13995                                          tagqng_able);
13996                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
13997                                 AdvWriteByteLram(iop_base,
13998                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
13999                                                  max_cmd[tid]);
14000                         }
14001                 } else {
14002                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14003                                 warn_code = ASC_WARN_BUSRESET_ERROR;
14004                         }
14005                 }
14006         }
14007
14008         return warn_code;
14009 }
14010
14011 /*
14012  * Initialize the ASC-38C1600.
14013  *
14014  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
14015  *
14016  * For a non-fatal error return a warning code. If there are no warnings
14017  * then 0 is returned.
14018  *
14019  * Needed after initialization for error recovery.
14020  */
14021 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
14022 {
14023         AdvPortAddr iop_base;
14024         ushort warn_code;
14025         ADV_DCNT sum;
14026         int begin_addr;
14027         int end_addr;
14028         ushort code_sum;
14029         long word;
14030         int j;
14031         int adv_asc38C1600_expanded_size;
14032         int i;
14033         ushort scsi_cfg1;
14034         uchar byte;
14035         uchar tid;
14036         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
14037         ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
14038         uchar max_cmd[ASC_MAX_TID + 1];
14039
14040         /* If there is already an error, don't continue. */
14041         if (asc_dvc->err_code != 0) {
14042                 return ADV_ERROR;
14043         }
14044
14045         /*
14046          * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
14047          */
14048         if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14049                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14050                 return ADV_ERROR;
14051         }
14052
14053         warn_code = 0;
14054         iop_base = asc_dvc->iop_base;
14055
14056         /*
14057          * Save the RISC memory BIOS region before writing the microcode.
14058          * The BIOS may already be loaded and using its RISC LRAM region
14059          * so its region must be saved and restored.
14060          *
14061          * Note: This code makes the assumption, which is currently true,
14062          * that a chip reset does not clear RISC LRAM.
14063          */
14064         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14065                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14066                                 bios_mem[i]);
14067         }
14068
14069         /*
14070          * Save current per TID negotiated values.
14071          */
14072         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14073         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14074         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14075         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14076         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
14077                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14078                                 max_cmd[tid]);
14079         }
14080
14081         /*
14082          * RAM BIST (Built-In Self Test)
14083          *
14084          * Address : I/O base + offset 0x38h register (byte).
14085          * Function: Bit 7-6(RW) : RAM mode
14086          *                          Normal Mode   : 0x00
14087          *                          Pre-test Mode : 0x40
14088          *                          RAM Test Mode : 0x80
14089          *           Bit 5       : unused
14090          *           Bit 4(RO)   : Done bit
14091          *           Bit 3-0(RO) : Status
14092          *                          Host Error    : 0x08
14093          *                          Int_RAM Error : 0x04
14094          *                          RISC Error    : 0x02
14095          *                          SCSI Error    : 0x01
14096          *                          No Error      : 0x00
14097          *
14098          * Note: RAM BIST code should be put right here, before loading the
14099          * microcode and after saving the RISC memory BIOS region.
14100          */
14101
14102         /*
14103          * LRAM Pre-test
14104          *
14105          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14106          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14107          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14108          * to NORMAL_MODE, return an error too.
14109          */
14110         for (i = 0; i < 2; i++) {
14111                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14112                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14113                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14114                 if ((byte & RAM_TEST_DONE) == 0
14115                     || (byte & 0x0F) != PRE_TEST_VALUE) {
14116                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14117                         return ADV_ERROR;
14118                 }
14119
14120                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14121                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14122                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14123                     != NORMAL_VALUE) {
14124                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14125                         return ADV_ERROR;
14126                 }
14127         }
14128
14129         /*
14130          * LRAM Test - It takes about 1.5 ms to run through the test.
14131          *
14132          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14133          * If Done bit not set or Status not 0, save register byte, set the
14134          * err_code, and return an error.
14135          */
14136         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14137         DvcSleepMilliSecond(10);        /* Wait for 10ms before checking status. */
14138
14139         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14140         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14141                 /* Get here if Done bit not set or Status not 0. */
14142                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
14143                 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14144                 return ADV_ERROR;
14145         }
14146
14147         /* We need to reset back to normal mode after LRAM test passes. */
14148         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14149
14150         /*
14151          * Load the Microcode
14152          *
14153          * Write the microcode image to RISC memory starting at address 0.
14154          *
14155          */
14156         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14157
14158         /*
14159          * Assume the following compressed format of the microcode buffer:
14160          *
14161          *  254 word (508 byte) table indexed by byte code followed
14162          *  by the following byte codes:
14163          *
14164          *    1-Byte Code:
14165          *      00: Emit word 0 in table.
14166          *      01: Emit word 1 in table.
14167          *      .
14168          *      FD: Emit word 253 in table.
14169          *
14170          *    Multi-Byte Code:
14171          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14172          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14173          */
14174         word = 0;
14175         for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
14176                 if (_adv_asc38C1600_buf[i] == 0xff) {
14177                         for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
14178                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14179                                                                     _adv_asc38C1600_buf
14180                                                                     [i +
14181                                                                      3] << 8) |
14182                                                                    _adv_asc38C1600_buf
14183                                                                    [i + 2]));
14184                                 word++;
14185                         }
14186                         i += 3;
14187                 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
14188                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14189                                                             _adv_asc38C1600_buf
14190                                                             [i +
14191                                                              2] << 8) |
14192                                                            _adv_asc38C1600_buf[i
14193                                                                                +
14194                                                                                1]));
14195                         i += 2;
14196                         word++;
14197                 } else {
14198                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14199                                                             _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
14200                         word++;
14201                 }
14202         }
14203
14204         /*
14205          * Set 'word' for later use to clear the rest of memory and save
14206          * the expanded mcode size.
14207          */
14208         word *= 2;
14209         adv_asc38C1600_expanded_size = word;
14210
14211         /*
14212          * Clear the rest of ASC-38C1600 Internal RAM (32KB).
14213          */
14214         for (; word < ADV_38C1600_MEMSIZE; word += 2) {
14215                 AdvWriteWordAutoIncLram(iop_base, 0);
14216         }
14217
14218         /*
14219          * Verify the microcode checksum.
14220          */
14221         sum = 0;
14222         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14223
14224         for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
14225                 sum += AdvReadWordAutoIncLram(iop_base);
14226         }
14227
14228         if (sum != _adv_asc38C1600_chksum) {
14229                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14230                 return ADV_ERROR;
14231         }
14232
14233         /*
14234          * Restore the RISC memory BIOS region.
14235          */
14236         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14237                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14238                                  bios_mem[i]);
14239         }
14240
14241         /*
14242          * Calculate and write the microcode code checksum to the microcode
14243          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14244          */
14245         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14246         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14247         code_sum = 0;
14248         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14249         for (word = begin_addr; word < end_addr; word += 2) {
14250                 code_sum += AdvReadWordAutoIncLram(iop_base);
14251         }
14252         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14253
14254         /*
14255          * Read microcode version and date.
14256          */
14257         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14258                         asc_dvc->cfg->mcode_date);
14259         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14260                         asc_dvc->cfg->mcode_version);
14261
14262         /*
14263          * Set the chip type to indicate the ASC38C1600.
14264          */
14265         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
14266
14267         /*
14268          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14269          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14270          * cable detection and then we are able to read C_DET[3:0].
14271          *
14272          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14273          * Microcode Default Value' section below.
14274          */
14275         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14276         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14277                              scsi_cfg1 | DIS_TERM_DRV);
14278
14279         /*
14280          * If the PCI Configuration Command Register "Parity Error Response
14281          * Control" Bit was clear (0), then set the microcode variable
14282          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14283          * to ignore DMA parity errors.
14284          */
14285         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14286                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14287                 word |= CONTROL_FLAG_IGNORE_PERR;
14288                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14289         }
14290
14291         /*
14292          * If the BIOS control flag AIPP (Asynchronous Information
14293          * Phase Protection) disable bit is not set, then set the firmware
14294          * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
14295          * AIPP checking and encoding.
14296          */
14297         if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
14298                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14299                 word |= CONTROL_FLAG_ENABLE_AIPP;
14300                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14301         }
14302
14303         /*
14304          * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
14305          * and START_CTL_TH [3:2].
14306          */
14307         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14308                              FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
14309
14310         /*
14311          * Microcode operating variables for WDTR, SDTR, and command tag
14312          * queuing will be set in slave_configure() based on what a
14313          * device reports it is capable of in Inquiry byte 7.
14314          *
14315          * If SCSI Bus Resets have been disabled, then directly set
14316          * SDTR and WDTR from the EEPROM configuration. This will allow
14317          * the BIOS and warm boot to work without a SCSI bus hang on
14318          * the Inquiry caused by host and target mismatched DTR values.
14319          * Without the SCSI Bus Reset, before an Inquiry a device can't
14320          * be assumed to be in Asynchronous, Narrow mode.
14321          */
14322         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14323                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14324                                  asc_dvc->wdtr_able);
14325                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14326                                  asc_dvc->sdtr_able);
14327         }
14328
14329         /*
14330          * Set microcode operating variables for DISC and SDTR_SPEED1,
14331          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14332          * configuration values.
14333          *
14334          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14335          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14336          * without determining here whether the device supports SDTR.
14337          */
14338         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14339                          asc_dvc->cfg->disc_enable);
14340         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14341         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14342         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14343         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14344
14345         /*
14346          * Set SCSI_CFG0 Microcode Default Value.
14347          *
14348          * The microcode will set the SCSI_CFG0 register using this value
14349          * after it is started below.
14350          */
14351         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14352                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14353                          asc_dvc->chip_scsi_id);
14354
14355         /*
14356          * Calculate SCSI_CFG1 Microcode Default Value.
14357          *
14358          * The microcode will set the SCSI_CFG1 register using this value
14359          * after it is started below.
14360          *
14361          * Each ASC-38C1600 function has only two cable detect bits.
14362          * The bus mode override bits are in IOPB_SOFT_OVER_WR.
14363          */
14364         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14365
14366         /*
14367          * If the cable is reversed all of the SCSI_CTRL register signals
14368          * will be set. Check for and return an error if this condition is
14369          * found.
14370          */
14371         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14372                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14373                 return ADV_ERROR;
14374         }
14375
14376         /*
14377          * Each ASC-38C1600 function has two connectors. Only an HVD device
14378          * can not be connected to either connector. An LVD device or SE device
14379          * may be connected to either connecor. If an SE device is connected,
14380          * then at most Ultra speed (20 Mhz) can be used on both connectors.
14381          *
14382          * If an HVD device is attached, return an error.
14383          */
14384         if (scsi_cfg1 & HVD) {
14385                 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14386                 return ADV_ERROR;
14387         }
14388
14389         /*
14390          * Each function in the ASC-38C1600 uses only the SE cable detect and
14391          * termination because there are two connectors for each function. Each
14392          * function may use either LVD or SE mode. Corresponding the SE automatic
14393          * termination control EEPROM bits are used for each function. Each
14394          * function has its own EEPROM. If SE automatic control is enabled for
14395          * the function, then set the termination value based on a table listed
14396          * in a_condor.h.
14397          *
14398          * If manual termination is specified in the EEPROM for the function,
14399          * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
14400          * ready to be 'ored' into SCSI_CFG1.
14401          */
14402         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14403                 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
14404                 /* SE automatic termination control is enabled. */
14405                 switch (scsi_cfg1 & C_DET_SE) {
14406                         /* TERM_SE_HI: on, TERM_SE_LO: on */
14407                 case 0x1:
14408                 case 0x2:
14409                 case 0x3:
14410                         asc_dvc->cfg->termination |= TERM_SE;
14411                         break;
14412
14413                 case 0x0:
14414                         if (PCI_FUNC(pdev->devfn) == 0) {
14415                                 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
14416                         } else {
14417                                 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
14418                                 asc_dvc->cfg->termination |= TERM_SE_HI;
14419                         }
14420                         break;
14421                 }
14422         }
14423
14424         /*
14425          * Clear any set TERM_SE bits.
14426          */
14427         scsi_cfg1 &= ~TERM_SE;
14428
14429         /*
14430          * Invert the TERM_SE bits and then set 'scsi_cfg1'.
14431          */
14432         scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
14433
14434         /*
14435          * Clear Big Endian and Terminator Polarity bits and set possibly
14436          * modified termination control bits in the Microcode SCSI_CFG1
14437          * Register Value.
14438          *
14439          * Big Endian bit is not used even on big endian machines.
14440          */
14441         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
14442
14443         /*
14444          * Set SCSI_CFG1 Microcode Default Value
14445          *
14446          * Set possibly modified termination control bits in the Microcode
14447          * SCSI_CFG1 Register Value.
14448          *
14449          * The microcode will set the SCSI_CFG1 register using this value
14450          * after it is started below.
14451          */
14452         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
14453
14454         /*
14455          * Set MEM_CFG Microcode Default Value
14456          *
14457          * The microcode will set the MEM_CFG register using this value
14458          * after it is started below.
14459          *
14460          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14461          * are defined.
14462          *
14463          * ASC-38C1600 has 32KB internal memory.
14464          *
14465          * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
14466          * out a special 16K Adv Library and Microcode version. After the issue
14467          * resolved, we should turn back to the 32K support. Both a_condor.h and
14468          * mcode.sas files also need to be updated.
14469          *
14470          * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14471          *  BIOS_EN | RAM_SZ_32KB);
14472          */
14473         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14474                          BIOS_EN | RAM_SZ_16KB);
14475
14476         /*
14477          * Set SEL_MASK Microcode Default Value
14478          *
14479          * The microcode will set the SEL_MASK register using this value
14480          * after it is started below.
14481          */
14482         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14483                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14484
14485         AdvBuildCarrierFreelist(asc_dvc);
14486
14487         /*
14488          * Set-up the Host->RISC Initiator Command Queue (ICQ).
14489          */
14490         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14491                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14492                 return ADV_ERROR;
14493         }
14494         asc_dvc->carr_freelist = (ADV_CARR_T *)
14495             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14496
14497         /*
14498          * The first command issued will be placed in the stopper carrier.
14499          */
14500         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14501
14502         /*
14503          * Set RISC ICQ physical address start value. Initialize the
14504          * COMMA register to the same value otherwise the RISC will
14505          * prematurely detect a command is available.
14506          */
14507         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14508         AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
14509                               le32_to_cpu(asc_dvc->icq_sp->carr_pa));
14510
14511         /*
14512          * Set-up the RISC->Host Initiator Response Queue (IRQ).
14513          */
14514         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14515                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14516                 return ADV_ERROR;
14517         }
14518         asc_dvc->carr_freelist = (ADV_CARR_T *)
14519             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14520
14521         /*
14522          * The first command completed by the RISC will be placed in
14523          * the stopper.
14524          *
14525          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14526          * completed the RISC will set the ASC_RQ_STOPPER bit.
14527          */
14528         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14529
14530         /*
14531          * Set RISC IRQ physical address start value.
14532          */
14533         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14534         asc_dvc->carr_pending_cnt = 0;
14535
14536         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14537                              (ADV_INTR_ENABLE_HOST_INTR |
14538                               ADV_INTR_ENABLE_GLOBAL_INTR));
14539         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14540         AdvWriteWordRegister(iop_base, IOPW_PC, word);
14541
14542         /* finally, finally, gentlemen, start your engine */
14543         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14544
14545         /*
14546          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14547          * Resets should be performed. The RISC has to be running
14548          * to issue a SCSI Bus Reset.
14549          */
14550         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14551                 /*
14552                  * If the BIOS Signature is present in memory, restore the
14553                  * per TID microcode operating variables.
14554                  */
14555                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14556                     0x55AA) {
14557                         /*
14558                          * Restore per TID negotiated values.
14559                          */
14560                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14561                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14562                         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
14563                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14564                                          tagqng_able);
14565                         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
14566                                 AdvWriteByteLram(iop_base,
14567                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
14568                                                  max_cmd[tid]);
14569                         }
14570                 } else {
14571                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14572                                 warn_code = ASC_WARN_BUSRESET_ERROR;
14573                         }
14574                 }
14575         }
14576
14577         return warn_code;
14578 }
14579
14580 /*
14581  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
14582  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
14583  * all of this is done.
14584  *
14585  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14586  *
14587  * For a non-fatal error return a warning code. If there are no warnings
14588  * then 0 is returned.
14589  *
14590  * Note: Chip is stopped on entry.
14591  */
14592 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
14593 {
14594         AdvPortAddr iop_base;
14595         ushort warn_code;
14596         ADVEEP_3550_CONFIG eep_config;
14597
14598         iop_base = asc_dvc->iop_base;
14599
14600         warn_code = 0;
14601
14602         /*
14603          * Read the board's EEPROM configuration.
14604          *
14605          * Set default values if a bad checksum is found.
14606          */
14607         if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
14608                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
14609
14610                 /*
14611                  * Set EEPROM default values.
14612                  */
14613                 memcpy(&eep_config, &Default_3550_EEPROM_Config,
14614                         sizeof(ADVEEP_3550_CONFIG));
14615
14616                 /*
14617                  * Assume the 6 byte board serial number that was read from
14618                  * EEPROM is correct even if the EEPROM checksum failed.
14619                  */
14620                 eep_config.serial_number_word3 =
14621                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
14622
14623                 eep_config.serial_number_word2 =
14624                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
14625
14626                 eep_config.serial_number_word1 =
14627                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
14628
14629                 AdvSet3550EEPConfig(iop_base, &eep_config);
14630         }
14631         /*
14632          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
14633          * EEPROM configuration that was read.
14634          *
14635          * This is the mapping of EEPROM fields to Adv Library fields.
14636          */
14637         asc_dvc->wdtr_able = eep_config.wdtr_able;
14638         asc_dvc->sdtr_able = eep_config.sdtr_able;
14639         asc_dvc->ultra_able = eep_config.ultra_able;
14640         asc_dvc->tagqng_able = eep_config.tagqng_able;
14641         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
14642         asc_dvc->max_host_qng = eep_config.max_host_qng;
14643         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14644         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
14645         asc_dvc->start_motor = eep_config.start_motor;
14646         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
14647         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
14648         asc_dvc->no_scam = eep_config.scam_tolerant;
14649         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
14650         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
14651         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
14652
14653         /*
14654          * Set the host maximum queuing (max. 253, min. 16) and the per device
14655          * maximum queuing (max. 63, min. 4).
14656          */
14657         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
14658                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14659         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
14660                 /* If the value is zero, assume it is uninitialized. */
14661                 if (eep_config.max_host_qng == 0) {
14662                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14663                 } else {
14664                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
14665                 }
14666         }
14667
14668         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
14669                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14670         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
14671                 /* If the value is zero, assume it is uninitialized. */
14672                 if (eep_config.max_dvc_qng == 0) {
14673                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14674                 } else {
14675                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
14676                 }
14677         }
14678
14679         /*
14680          * If 'max_dvc_qng' is greater than 'max_host_qng', then
14681          * set 'max_dvc_qng' to 'max_host_qng'.
14682          */
14683         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
14684                 eep_config.max_dvc_qng = eep_config.max_host_qng;
14685         }
14686
14687         /*
14688          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
14689          * values based on possibly adjusted EEPROM values.
14690          */
14691         asc_dvc->max_host_qng = eep_config.max_host_qng;
14692         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14693
14694         /*
14695          * If the EEPROM 'termination' field is set to automatic (0), then set
14696          * the ADV_DVC_CFG 'termination' field to automatic also.
14697          *
14698          * If the termination is specified with a non-zero 'termination'
14699          * value check that a legal value is set and set the ADV_DVC_CFG
14700          * 'termination' field appropriately.
14701          */
14702         if (eep_config.termination == 0) {
14703                 asc_dvc->cfg->termination = 0;  /* auto termination */
14704         } else {
14705                 /* Enable manual control with low off / high off. */
14706                 if (eep_config.termination == 1) {
14707                         asc_dvc->cfg->termination = TERM_CTL_SEL;
14708
14709                         /* Enable manual control with low off / high on. */
14710                 } else if (eep_config.termination == 2) {
14711                         asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
14712
14713                         /* Enable manual control with low on / high on. */
14714                 } else if (eep_config.termination == 3) {
14715                         asc_dvc->cfg->termination =
14716                             TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
14717                 } else {
14718                         /*
14719                          * The EEPROM 'termination' field contains a bad value. Use
14720                          * automatic termination instead.
14721                          */
14722                         asc_dvc->cfg->termination = 0;
14723                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
14724                 }
14725         }
14726
14727         return warn_code;
14728 }
14729
14730 /*
14731  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
14732  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
14733  * all of this is done.
14734  *
14735  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14736  *
14737  * For a non-fatal error return a warning code. If there are no warnings
14738  * then 0 is returned.
14739  *
14740  * Note: Chip is stopped on entry.
14741  */
14742 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
14743 {
14744         AdvPortAddr iop_base;
14745         ushort warn_code;
14746         ADVEEP_38C0800_CONFIG eep_config;
14747         uchar tid, termination;
14748         ushort sdtr_speed = 0;
14749
14750         iop_base = asc_dvc->iop_base;
14751
14752         warn_code = 0;
14753
14754         /*
14755          * Read the board's EEPROM configuration.
14756          *
14757          * Set default values if a bad checksum is found.
14758          */
14759         if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
14760             eep_config.check_sum) {
14761                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
14762
14763                 /*
14764                  * Set EEPROM default values.
14765                  */
14766                 memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
14767                         sizeof(ADVEEP_38C0800_CONFIG));
14768
14769                 /*
14770                  * Assume the 6 byte board serial number that was read from
14771                  * EEPROM is correct even if the EEPROM checksum failed.
14772                  */
14773                 eep_config.serial_number_word3 =
14774                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
14775
14776                 eep_config.serial_number_word2 =
14777                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
14778
14779                 eep_config.serial_number_word1 =
14780                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
14781
14782                 AdvSet38C0800EEPConfig(iop_base, &eep_config);
14783         }
14784         /*
14785          * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
14786          * EEPROM configuration that was read.
14787          *
14788          * This is the mapping of EEPROM fields to Adv Library fields.
14789          */
14790         asc_dvc->wdtr_able = eep_config.wdtr_able;
14791         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
14792         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
14793         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
14794         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
14795         asc_dvc->tagqng_able = eep_config.tagqng_able;
14796         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
14797         asc_dvc->max_host_qng = eep_config.max_host_qng;
14798         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14799         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
14800         asc_dvc->start_motor = eep_config.start_motor;
14801         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
14802         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
14803         asc_dvc->no_scam = eep_config.scam_tolerant;
14804         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
14805         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
14806         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
14807
14808         /*
14809          * For every Target ID if any of its 'sdtr_speed[1234]' bits
14810          * are set, then set an 'sdtr_able' bit for it.
14811          */
14812         asc_dvc->sdtr_able = 0;
14813         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14814                 if (tid == 0) {
14815                         sdtr_speed = asc_dvc->sdtr_speed1;
14816                 } else if (tid == 4) {
14817                         sdtr_speed = asc_dvc->sdtr_speed2;
14818                 } else if (tid == 8) {
14819                         sdtr_speed = asc_dvc->sdtr_speed3;
14820                 } else if (tid == 12) {
14821                         sdtr_speed = asc_dvc->sdtr_speed4;
14822                 }
14823                 if (sdtr_speed & ADV_MAX_TID) {
14824                         asc_dvc->sdtr_able |= (1 << tid);
14825                 }
14826                 sdtr_speed >>= 4;
14827         }
14828
14829         /*
14830          * Set the host maximum queuing (max. 253, min. 16) and the per device
14831          * maximum queuing (max. 63, min. 4).
14832          */
14833         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
14834                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14835         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
14836                 /* If the value is zero, assume it is uninitialized. */
14837                 if (eep_config.max_host_qng == 0) {
14838                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
14839                 } else {
14840                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
14841                 }
14842         }
14843
14844         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
14845                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14846         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
14847                 /* If the value is zero, assume it is uninitialized. */
14848                 if (eep_config.max_dvc_qng == 0) {
14849                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
14850                 } else {
14851                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
14852                 }
14853         }
14854
14855         /*
14856          * If 'max_dvc_qng' is greater than 'max_host_qng', then
14857          * set 'max_dvc_qng' to 'max_host_qng'.
14858          */
14859         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
14860                 eep_config.max_dvc_qng = eep_config.max_host_qng;
14861         }
14862
14863         /*
14864          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
14865          * values based on possibly adjusted EEPROM values.
14866          */
14867         asc_dvc->max_host_qng = eep_config.max_host_qng;
14868         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
14869
14870         /*
14871          * If the EEPROM 'termination' field is set to automatic (0), then set
14872          * the ADV_DVC_CFG 'termination' field to automatic also.
14873          *
14874          * If the termination is specified with a non-zero 'termination'
14875          * value check that a legal value is set and set the ADV_DVC_CFG
14876          * 'termination' field appropriately.
14877          */
14878         if (eep_config.termination_se == 0) {
14879                 termination = 0;        /* auto termination for SE */
14880         } else {
14881                 /* Enable manual control with low off / high off. */
14882                 if (eep_config.termination_se == 1) {
14883                         termination = 0;
14884
14885                         /* Enable manual control with low off / high on. */
14886                 } else if (eep_config.termination_se == 2) {
14887                         termination = TERM_SE_HI;
14888
14889                         /* Enable manual control with low on / high on. */
14890                 } else if (eep_config.termination_se == 3) {
14891                         termination = TERM_SE;
14892                 } else {
14893                         /*
14894                          * The EEPROM 'termination_se' field contains a bad value.
14895                          * Use automatic termination instead.
14896                          */
14897                         termination = 0;
14898                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
14899                 }
14900         }
14901
14902         if (eep_config.termination_lvd == 0) {
14903                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
14904         } else {
14905                 /* Enable manual control with low off / high off. */
14906                 if (eep_config.termination_lvd == 1) {
14907                         asc_dvc->cfg->termination = termination;
14908
14909                         /* Enable manual control with low off / high on. */
14910                 } else if (eep_config.termination_lvd == 2) {
14911                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
14912
14913                         /* Enable manual control with low on / high on. */
14914                 } else if (eep_config.termination_lvd == 3) {
14915                         asc_dvc->cfg->termination = termination | TERM_LVD;
14916                 } else {
14917                         /*
14918                          * The EEPROM 'termination_lvd' field contains a bad value.
14919                          * Use automatic termination instead.
14920                          */
14921                         asc_dvc->cfg->termination = termination;
14922                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
14923                 }
14924         }
14925
14926         return warn_code;
14927 }
14928
14929 /*
14930  * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
14931  * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
14932  * all of this is done.
14933  *
14934  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
14935  *
14936  * For a non-fatal error return a warning code. If there are no warnings
14937  * then 0 is returned.
14938  *
14939  * Note: Chip is stopped on entry.
14940  */
14941 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
14942 {
14943         AdvPortAddr iop_base;
14944         ushort warn_code;
14945         ADVEEP_38C1600_CONFIG eep_config;
14946         uchar tid, termination;
14947         ushort sdtr_speed = 0;
14948
14949         iop_base = asc_dvc->iop_base;
14950
14951         warn_code = 0;
14952
14953         /*
14954          * Read the board's EEPROM configuration.
14955          *
14956          * Set default values if a bad checksum is found.
14957          */
14958         if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
14959             eep_config.check_sum) {
14960                 struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
14961                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
14962
14963                 /*
14964                  * Set EEPROM default values.
14965                  */
14966                 memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
14967                         sizeof(ADVEEP_38C1600_CONFIG));
14968
14969                 if (PCI_FUNC(pdev->devfn) != 0) {
14970                         u8 ints;
14971                         /*
14972                          * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
14973                          * and old Mac system booting problem. The Expansion
14974                          * ROM must be disabled in Function 1 for these systems
14975                          */
14976                         eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
14977                         /*
14978                          * Clear the INTAB (bit 11) if the GPIO 0 input
14979                          * indicates the Function 1 interrupt line is wired
14980                          * to INTB.
14981                          *
14982                          * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
14983                          *   1 - Function 1 interrupt line wired to INT A.
14984                          *   0 - Function 1 interrupt line wired to INT B.
14985                          *
14986                          * Note: Function 0 is always wired to INTA.
14987                          * Put all 5 GPIO bits in input mode and then read
14988                          * their input values.
14989                          */
14990                         AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
14991                         ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
14992                         if ((ints & 0x01) == 0)
14993                                 eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
14994                 }
14995
14996                 /*
14997                  * Assume the 6 byte board serial number that was read from
14998                  * EEPROM is correct even if the EEPROM checksum failed.
14999                  */
15000                 eep_config.serial_number_word3 =
15001                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15002                 eep_config.serial_number_word2 =
15003                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15004                 eep_config.serial_number_word1 =
15005                         AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15006
15007                 AdvSet38C1600EEPConfig(iop_base, &eep_config);
15008         }
15009
15010         /*
15011          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15012          * EEPROM configuration that was read.
15013          *
15014          * This is the mapping of EEPROM fields to Adv Library fields.
15015          */
15016         asc_dvc->wdtr_able = eep_config.wdtr_able;
15017         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
15018         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
15019         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
15020         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
15021         asc_dvc->ppr_able = 0;
15022         asc_dvc->tagqng_able = eep_config.tagqng_able;
15023         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15024         asc_dvc->max_host_qng = eep_config.max_host_qng;
15025         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15026         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
15027         asc_dvc->start_motor = eep_config.start_motor;
15028         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15029         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15030         asc_dvc->no_scam = eep_config.scam_tolerant;
15031
15032         /*
15033          * For every Target ID if any of its 'sdtr_speed[1234]' bits
15034          * are set, then set an 'sdtr_able' bit for it.
15035          */
15036         asc_dvc->sdtr_able = 0;
15037         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15038                 if (tid == 0) {
15039                         sdtr_speed = asc_dvc->sdtr_speed1;
15040                 } else if (tid == 4) {
15041                         sdtr_speed = asc_dvc->sdtr_speed2;
15042                 } else if (tid == 8) {
15043                         sdtr_speed = asc_dvc->sdtr_speed3;
15044                 } else if (tid == 12) {
15045                         sdtr_speed = asc_dvc->sdtr_speed4;
15046                 }
15047                 if (sdtr_speed & ASC_MAX_TID) {
15048                         asc_dvc->sdtr_able |= (1 << tid);
15049                 }
15050                 sdtr_speed >>= 4;
15051         }
15052
15053         /*
15054          * Set the host maximum queuing (max. 253, min. 16) and the per device
15055          * maximum queuing (max. 63, min. 4).
15056          */
15057         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15058                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15059         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15060                 /* If the value is zero, assume it is uninitialized. */
15061                 if (eep_config.max_host_qng == 0) {
15062                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15063                 } else {
15064                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15065                 }
15066         }
15067
15068         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15069                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15070         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15071                 /* If the value is zero, assume it is uninitialized. */
15072                 if (eep_config.max_dvc_qng == 0) {
15073                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15074                 } else {
15075                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15076                 }
15077         }
15078
15079         /*
15080          * If 'max_dvc_qng' is greater than 'max_host_qng', then
15081          * set 'max_dvc_qng' to 'max_host_qng'.
15082          */
15083         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15084                 eep_config.max_dvc_qng = eep_config.max_host_qng;
15085         }
15086
15087         /*
15088          * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
15089          * values based on possibly adjusted EEPROM values.
15090          */
15091         asc_dvc->max_host_qng = eep_config.max_host_qng;
15092         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15093
15094         /*
15095          * If the EEPROM 'termination' field is set to automatic (0), then set
15096          * the ASC_DVC_CFG 'termination' field to automatic also.
15097          *
15098          * If the termination is specified with a non-zero 'termination'
15099          * value check that a legal value is set and set the ASC_DVC_CFG
15100          * 'termination' field appropriately.
15101          */
15102         if (eep_config.termination_se == 0) {
15103                 termination = 0;        /* auto termination for SE */
15104         } else {
15105                 /* Enable manual control with low off / high off. */
15106                 if (eep_config.termination_se == 1) {
15107                         termination = 0;
15108
15109                         /* Enable manual control with low off / high on. */
15110                 } else if (eep_config.termination_se == 2) {
15111                         termination = TERM_SE_HI;
15112
15113                         /* Enable manual control with low on / high on. */
15114                 } else if (eep_config.termination_se == 3) {
15115                         termination = TERM_SE;
15116                 } else {
15117                         /*
15118                          * The EEPROM 'termination_se' field contains a bad value.
15119                          * Use automatic termination instead.
15120                          */
15121                         termination = 0;
15122                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15123                 }
15124         }
15125
15126         if (eep_config.termination_lvd == 0) {
15127                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
15128         } else {
15129                 /* Enable manual control with low off / high off. */
15130                 if (eep_config.termination_lvd == 1) {
15131                         asc_dvc->cfg->termination = termination;
15132
15133                         /* Enable manual control with low off / high on. */
15134                 } else if (eep_config.termination_lvd == 2) {
15135                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
15136
15137                         /* Enable manual control with low on / high on. */
15138                 } else if (eep_config.termination_lvd == 3) {
15139                         asc_dvc->cfg->termination = termination | TERM_LVD;
15140                 } else {
15141                         /*
15142                          * The EEPROM 'termination_lvd' field contains a bad value.
15143                          * Use automatic termination instead.
15144                          */
15145                         asc_dvc->cfg->termination = termination;
15146                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15147                 }
15148         }
15149
15150         return warn_code;
15151 }
15152
15153 /*
15154  * Read EEPROM configuration into the specified buffer.
15155  *
15156  * Return a checksum based on the EEPROM configuration read.
15157  */
15158 static ushort __devinit
15159 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
15160 {
15161         ushort wval, chksum;
15162         ushort *wbuf;
15163         int eep_addr;
15164         ushort *charfields;
15165
15166         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
15167         wbuf = (ushort *)cfg_buf;
15168         chksum = 0;
15169
15170         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
15171              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
15172                 wval = AdvReadEEPWord(iop_base, eep_addr);
15173                 chksum += wval; /* Checksum is calculated from word values. */
15174                 if (*charfields++) {
15175                         *wbuf = le16_to_cpu(wval);
15176                 } else {
15177                         *wbuf = wval;
15178                 }
15179         }
15180         /* Read checksum word. */
15181         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
15182         wbuf++;
15183         charfields++;
15184
15185         /* Read rest of EEPROM not covered by the checksum. */
15186         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
15187              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
15188                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
15189                 if (*charfields++) {
15190                         *wbuf = le16_to_cpu(*wbuf);
15191                 }
15192         }
15193         return chksum;
15194 }
15195
15196 /*
15197  * Read EEPROM configuration into the specified buffer.
15198  *
15199  * Return a checksum based on the EEPROM configuration read.
15200  */
15201 static ushort __devinit
15202 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
15203 {
15204         ushort wval, chksum;
15205         ushort *wbuf;
15206         int eep_addr;
15207         ushort *charfields;
15208
15209         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
15210         wbuf = (ushort *)cfg_buf;
15211         chksum = 0;
15212
15213         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
15214              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
15215                 wval = AdvReadEEPWord(iop_base, eep_addr);
15216                 chksum += wval; /* Checksum is calculated from word values. */
15217                 if (*charfields++) {
15218                         *wbuf = le16_to_cpu(wval);
15219                 } else {
15220                         *wbuf = wval;
15221                 }
15222         }
15223         /* Read checksum word. */
15224         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
15225         wbuf++;
15226         charfields++;
15227
15228         /* Read rest of EEPROM not covered by the checksum. */
15229         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
15230              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
15231                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
15232                 if (*charfields++) {
15233                         *wbuf = le16_to_cpu(*wbuf);
15234                 }
15235         }
15236         return chksum;
15237 }
15238
15239 /*
15240  * Read EEPROM configuration into the specified buffer.
15241  *
15242  * Return a checksum based on the EEPROM configuration read.
15243  */
15244 static ushort __devinit
15245 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
15246 {
15247         ushort wval, chksum;
15248         ushort *wbuf;
15249         int eep_addr;
15250         ushort *charfields;
15251
15252         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
15253         wbuf = (ushort *)cfg_buf;
15254         chksum = 0;
15255
15256         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
15257              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
15258                 wval = AdvReadEEPWord(iop_base, eep_addr);
15259                 chksum += wval; /* Checksum is calculated from word values. */
15260                 if (*charfields++) {
15261                         *wbuf = le16_to_cpu(wval);
15262                 } else {
15263                         *wbuf = wval;
15264                 }
15265         }
15266         /* Read checksum word. */
15267         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
15268         wbuf++;
15269         charfields++;
15270
15271         /* Read rest of EEPROM not covered by the checksum. */
15272         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
15273              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
15274                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
15275                 if (*charfields++) {
15276                         *wbuf = le16_to_cpu(*wbuf);
15277                 }
15278         }
15279         return chksum;
15280 }
15281
15282 /*
15283  * Read the EEPROM from specified location
15284  */
15285 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
15286 {
15287         AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
15288                              ASC_EEP_CMD_READ | eep_word_addr);
15289         AdvWaitEEPCmd(iop_base);
15290         return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
15291 }
15292
15293 /*
15294  * Wait for EEPROM command to complete
15295  */
15296 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
15297 {
15298         int eep_delay_ms;
15299
15300         for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
15301                 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
15302                     ASC_EEP_CMD_DONE) {
15303                         break;
15304                 }
15305                 DvcSleepMilliSecond(1);
15306         }
15307         if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
15308             0) {
15309                 ASC_ASSERT(0);
15310         }
15311         return;
15312 }
15313
15314 /*
15315  * Write the EEPROM from 'cfg_buf'.
15316  */
15317 void __devinit
15318 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
15319 {
15320         ushort *wbuf;
15321         ushort addr, chksum;
15322         ushort *charfields;
15323
15324         wbuf = (ushort *)cfg_buf;
15325         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
15326         chksum = 0;
15327
15328         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
15329         AdvWaitEEPCmd(iop_base);
15330
15331         /*
15332          * Write EEPROM from word 0 to word 20.
15333          */
15334         for (addr = ADV_EEP_DVC_CFG_BEGIN;
15335              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
15336                 ushort word;
15337
15338                 if (*charfields++) {
15339                         word = cpu_to_le16(*wbuf);
15340                 } else {
15341                         word = *wbuf;
15342                 }
15343                 chksum += *wbuf;        /* Checksum is calculated from word values. */
15344                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
15345                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
15346                                      ASC_EEP_CMD_WRITE | addr);
15347                 AdvWaitEEPCmd(iop_base);
15348                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
15349         }
15350
15351         /*
15352          * Write EEPROM checksum at word 21.
15353          */
15354         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
15355         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
15356         AdvWaitEEPCmd(iop_base);
15357         wbuf++;
15358         charfields++;
15359
15360         /*
15361          * Write EEPROM OEM name at words 22 to 29.
15362          */
15363         for (addr = ADV_EEP_DVC_CTL_BEGIN;
15364              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
15365                 ushort word;
15366
15367                 if (*charfields++) {
15368                         word = cpu_to_le16(*wbuf);
15369                 } else {
15370                         word = *wbuf;
15371                 }
15372                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
15373                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
15374                                      ASC_EEP_CMD_WRITE | addr);
15375                 AdvWaitEEPCmd(iop_base);
15376         }
15377         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
15378         AdvWaitEEPCmd(iop_base);
15379         return;
15380 }
15381
15382 /*
15383  * Write the EEPROM from 'cfg_buf'.
15384  */
15385 void __devinit
15386 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
15387 {
15388         ushort *wbuf;
15389         ushort *charfields;
15390         ushort addr, chksum;
15391
15392         wbuf = (ushort *)cfg_buf;
15393         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
15394         chksum = 0;
15395
15396         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
15397         AdvWaitEEPCmd(iop_base);
15398
15399         /*
15400          * Write EEPROM from word 0 to word 20.
15401          */
15402         for (addr = ADV_EEP_DVC_CFG_BEGIN;
15403              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
15404                 ushort word;
15405
15406                 if (*charfields++) {
15407                         word = cpu_to_le16(*wbuf);
15408                 } else {
15409                         word = *wbuf;
15410                 }
15411                 chksum += *wbuf;        /* Checksum is calculated from word values. */
15412                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
15413                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
15414                                      ASC_EEP_CMD_WRITE | addr);
15415                 AdvWaitEEPCmd(iop_base);
15416                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
15417         }
15418
15419         /*
15420          * Write EEPROM checksum at word 21.
15421          */
15422         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
15423         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
15424         AdvWaitEEPCmd(iop_base);
15425         wbuf++;
15426         charfields++;
15427
15428         /*
15429          * Write EEPROM OEM name at words 22 to 29.
15430          */
15431         for (addr = ADV_EEP_DVC_CTL_BEGIN;
15432              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
15433                 ushort word;
15434
15435                 if (*charfields++) {
15436                         word = cpu_to_le16(*wbuf);
15437                 } else {
15438                         word = *wbuf;
15439                 }
15440                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
15441                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
15442                                      ASC_EEP_CMD_WRITE | addr);
15443                 AdvWaitEEPCmd(iop_base);
15444         }
15445         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
15446         AdvWaitEEPCmd(iop_base);
15447         return;
15448 }
15449
15450 /*
15451  * Write the EEPROM from 'cfg_buf'.
15452  */
15453 void __devinit
15454 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
15455 {
15456         ushort *wbuf;
15457         ushort *charfields;
15458         ushort addr, chksum;
15459
15460         wbuf = (ushort *)cfg_buf;
15461         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
15462         chksum = 0;
15463
15464         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
15465         AdvWaitEEPCmd(iop_base);
15466
15467         /*
15468          * Write EEPROM from word 0 to word 20.
15469          */
15470         for (addr = ADV_EEP_DVC_CFG_BEGIN;
15471              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
15472                 ushort word;
15473
15474                 if (*charfields++) {
15475                         word = cpu_to_le16(*wbuf);
15476                 } else {
15477                         word = *wbuf;
15478                 }
15479                 chksum += *wbuf;        /* Checksum is calculated from word values. */
15480                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
15481                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
15482                                      ASC_EEP_CMD_WRITE | addr);
15483                 AdvWaitEEPCmd(iop_base);
15484                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
15485         }
15486
15487         /*
15488          * Write EEPROM checksum at word 21.
15489          */
15490         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
15491         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
15492         AdvWaitEEPCmd(iop_base);
15493         wbuf++;
15494         charfields++;
15495
15496         /*
15497          * Write EEPROM OEM name at words 22 to 29.
15498          */
15499         for (addr = ADV_EEP_DVC_CTL_BEGIN;
15500              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
15501                 ushort word;
15502
15503                 if (*charfields++) {
15504                         word = cpu_to_le16(*wbuf);
15505                 } else {
15506                         word = *wbuf;
15507                 }
15508                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
15509                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
15510                                      ASC_EEP_CMD_WRITE | addr);
15511                 AdvWaitEEPCmd(iop_base);
15512         }
15513         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
15514         AdvWaitEEPCmd(iop_base);
15515         return;
15516 }
15517
15518 /* a_advlib.c */
15519 /*
15520  * AdvExeScsiQueue() - Send a request to the RISC microcode program.
15521  *
15522  *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
15523  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
15524  *   RISC to notify it a new command is ready to be executed.
15525  *
15526  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
15527  * set to SCSI_MAX_RETRY.
15528  *
15529  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
15530  * for DMA addresses or math operations are byte swapped to little-endian
15531  * order.
15532  *
15533  * Return:
15534  *      ADV_SUCCESS(1) - The request was successfully queued.
15535  *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
15536  *                       request completes.
15537  *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
15538  *                       host IC error.
15539  */
15540 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
15541 {
15542         ulong last_int_level;
15543         AdvPortAddr iop_base;
15544         ADV_DCNT req_size;
15545         ADV_PADDR req_paddr;
15546         ADV_CARR_T *new_carrp;
15547
15548         ASC_ASSERT(scsiq != NULL);      /* 'scsiq' should never be NULL. */
15549
15550         /*
15551          * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
15552          */
15553         if (scsiq->target_id > ADV_MAX_TID) {
15554                 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
15555                 scsiq->done_status = QD_WITH_ERROR;
15556                 return ADV_ERROR;
15557         }
15558
15559         iop_base = asc_dvc->iop_base;
15560
15561         last_int_level = DvcEnterCritical();
15562
15563         /*
15564          * Allocate a carrier ensuring at least one carrier always
15565          * remains on the freelist and initialize fields.
15566          */
15567         if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
15568                 DvcLeaveCritical(last_int_level);
15569                 return ADV_BUSY;
15570         }
15571         asc_dvc->carr_freelist = (ADV_CARR_T *)
15572             ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
15573         asc_dvc->carr_pending_cnt++;
15574
15575         /*
15576          * Set the carrier to be a stopper by setting 'next_vpa'
15577          * to the stopper value. The current stopper will be changed
15578          * below to point to the new stopper.
15579          */
15580         new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15581
15582         /*
15583          * Clear the ADV_SCSI_REQ_Q done flag.
15584          */
15585         scsiq->a_flag &= ~ADV_SCSIQ_DONE;
15586
15587         req_size = sizeof(ADV_SCSI_REQ_Q);
15588         req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
15589                                   (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
15590
15591         ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
15592         ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
15593
15594         /* Wait for assertion before making little-endian */
15595         req_paddr = cpu_to_le32(req_paddr);
15596
15597         /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
15598         scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
15599         scsiq->scsiq_rptr = req_paddr;
15600
15601         scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
15602         /*
15603          * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
15604          * order during initialization.
15605          */
15606         scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
15607
15608         /*
15609          * Use the current stopper to send the ADV_SCSI_REQ_Q command to
15610          * the microcode. The newly allocated stopper will become the new
15611          * stopper.
15612          */
15613         asc_dvc->icq_sp->areq_vpa = req_paddr;
15614
15615         /*
15616          * Set the 'next_vpa' pointer for the old stopper to be the
15617          * physical address of the new stopper. The RISC can only
15618          * follow physical addresses.
15619          */
15620         asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
15621
15622         /*
15623          * Set the host adapter stopper pointer to point to the new carrier.
15624          */
15625         asc_dvc->icq_sp = new_carrp;
15626
15627         if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
15628             asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
15629                 /*
15630                  * Tickle the RISC to tell it to read its Command Queue Head pointer.
15631                  */
15632                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
15633                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
15634                         /*
15635                          * Clear the tickle value. In the ASC-3550 the RISC flag
15636                          * command 'clr_tickle_a' does not work unless the host
15637                          * value is cleared.
15638                          */
15639                         AdvWriteByteRegister(iop_base, IOPB_TICKLE,
15640                                              ADV_TICKLE_NOP);
15641                 }
15642         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
15643                 /*
15644                  * Notify the RISC a carrier is ready by writing the physical
15645                  * address of the new carrier stopper to the COMMA register.
15646                  */
15647                 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15648                                       le32_to_cpu(new_carrp->carr_pa));
15649         }
15650
15651         DvcLeaveCritical(last_int_level);
15652
15653         return ADV_SUCCESS;
15654 }
15655
15656 /*
15657  * Reset SCSI Bus and purge all outstanding requests.
15658  *
15659  * Return Value:
15660  *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
15661  *      ADV_FALSE(0) -  Microcode command failed.
15662  *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
15663  *                      may be hung which requires driver recovery.
15664  */
15665 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
15666 {
15667         int status;
15668
15669         /*
15670          * Send the SCSI Bus Reset idle start idle command which asserts
15671          * the SCSI Bus Reset signal.
15672          */
15673         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
15674         if (status != ADV_TRUE) {
15675                 return status;
15676         }
15677
15678         /*
15679          * Delay for the specified SCSI Bus Reset hold time.
15680          *
15681          * The hold time delay is done on the host because the RISC has no
15682          * microsecond accurate timer.
15683          */
15684         DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
15685
15686         /*
15687          * Send the SCSI Bus Reset end idle command which de-asserts
15688          * the SCSI Bus Reset signal and purges any pending requests.
15689          */
15690         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
15691         if (status != ADV_TRUE) {
15692                 return status;
15693         }
15694
15695         DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
15696
15697         return status;
15698 }
15699
15700 /*
15701  * Reset chip and SCSI Bus.
15702  *
15703  * Return Value:
15704  *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
15705  *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
15706  */
15707 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
15708 {
15709         int status;
15710         ushort wdtr_able, sdtr_able, tagqng_able;
15711         ushort ppr_able = 0;
15712         uchar tid, max_cmd[ADV_MAX_TID + 1];
15713         AdvPortAddr iop_base;
15714         ushort bios_sig;
15715
15716         iop_base = asc_dvc->iop_base;
15717
15718         /*
15719          * Save current per TID negotiated values.
15720          */
15721         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15722         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15723         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
15724                 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15725         }
15726         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15727         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15728                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15729                                 max_cmd[tid]);
15730         }
15731
15732         /*
15733          * Force the AdvInitAsc3550/38C0800Driver() function to
15734          * perform a SCSI Bus Reset by clearing the BIOS signature word.
15735          * The initialization functions assumes a SCSI Bus Reset is not
15736          * needed if the BIOS signature word is present.
15737          */
15738         AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
15739         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
15740
15741         /*
15742          * Stop chip and reset it.
15743          */
15744         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
15745         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
15746         DvcSleepMilliSecond(100);
15747         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
15748                              ADV_CTRL_REG_CMD_WR_IO_REG);
15749
15750         /*
15751          * Reset Adv Library error code, if any, and try
15752          * re-initializing the chip.
15753          */
15754         asc_dvc->err_code = 0;
15755         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
15756                 status = AdvInitAsc38C1600Driver(asc_dvc);
15757         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
15758                 status = AdvInitAsc38C0800Driver(asc_dvc);
15759         } else {
15760                 status = AdvInitAsc3550Driver(asc_dvc);
15761         }
15762
15763         /* Translate initialization return value to status value. */
15764         if (status == 0) {
15765                 status = ADV_TRUE;
15766         } else {
15767                 status = ADV_FALSE;
15768         }
15769
15770         /*
15771          * Restore the BIOS signature word.
15772          */
15773         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
15774
15775         /*
15776          * Restore per TID negotiated values.
15777          */
15778         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15779         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15780         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
15781                 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15782         }
15783         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15784         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15785                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15786                                  max_cmd[tid]);
15787         }
15788
15789         return status;
15790 }
15791
15792 /*
15793  * Adv Library Interrupt Service Routine
15794  *
15795  *  This function is called by a driver's interrupt service routine.
15796  *  The function disables and re-enables interrupts.
15797  *
15798  *  When a microcode idle command is completed, the ADV_DVC_VAR
15799  *  'idle_cmd_done' field is set to ADV_TRUE.
15800  *
15801  *  Note: AdvISR() can be called when interrupts are disabled or even
15802  *  when there is no hardware interrupt condition present. It will
15803  *  always check for completed idle commands and microcode requests.
15804  *  This is an important feature that shouldn't be changed because it
15805  *  allows commands to be completed from polling mode loops.
15806  *
15807  * Return:
15808  *   ADV_TRUE(1) - interrupt was pending
15809  *   ADV_FALSE(0) - no interrupt was pending
15810  */
15811 static int AdvISR(ADV_DVC_VAR *asc_dvc)
15812 {
15813         AdvPortAddr iop_base;
15814         uchar int_stat;
15815         ushort target_bit;
15816         ADV_CARR_T *free_carrp;
15817         ADV_VADDR irq_next_vpa;
15818         int flags;
15819         ADV_SCSI_REQ_Q *scsiq;
15820
15821         flags = DvcEnterCritical();
15822
15823         iop_base = asc_dvc->iop_base;
15824
15825         /* Reading the register clears the interrupt. */
15826         int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
15827
15828         if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
15829                          ADV_INTR_STATUS_INTRC)) == 0) {
15830                 DvcLeaveCritical(flags);
15831                 return ADV_FALSE;
15832         }
15833
15834         /*
15835          * Notify the driver of an asynchronous microcode condition by
15836          * calling the adv_async_callback function. The function
15837          * is passed the microcode ASC_MC_INTRB_CODE byte value.
15838          */
15839         if (int_stat & ADV_INTR_STATUS_INTRB) {
15840                 uchar intrb_code;
15841
15842                 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
15843
15844                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
15845                     asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
15846                         if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
15847                             asc_dvc->carr_pending_cnt != 0) {
15848                                 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
15849                                                      ADV_TICKLE_A);
15850                                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
15851                                         AdvWriteByteRegister(iop_base,
15852                                                              IOPB_TICKLE,
15853                                                              ADV_TICKLE_NOP);
15854                                 }
15855                         }
15856                 }
15857
15858                 adv_async_callback(asc_dvc, intrb_code);
15859         }
15860
15861         /*
15862          * Check if the IRQ stopper carrier contains a completed request.
15863          */
15864         while (((irq_next_vpa =
15865                  le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
15866                 /*
15867                  * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
15868                  * The RISC will have set 'areq_vpa' to a virtual address.
15869                  *
15870                  * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
15871                  * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
15872                  * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
15873                  * in AdvExeScsiQueue().
15874                  */
15875                 scsiq = (ADV_SCSI_REQ_Q *)
15876                     ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
15877
15878                 /*
15879                  * Request finished with good status and the queue was not
15880                  * DMAed to host memory by the firmware. Set all status fields
15881                  * to indicate good status.
15882                  */
15883                 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
15884                         scsiq->done_status = QD_NO_ERROR;
15885                         scsiq->host_status = scsiq->scsi_status = 0;
15886                         scsiq->data_cnt = 0L;
15887                 }
15888
15889                 /*
15890                  * Advance the stopper pointer to the next carrier
15891                  * ignoring the lower four bits. Free the previous
15892                  * stopper carrier.
15893                  */
15894                 free_carrp = asc_dvc->irq_sp;
15895                 asc_dvc->irq_sp = (ADV_CARR_T *)
15896                     ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
15897
15898                 free_carrp->next_vpa =
15899                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15900                 asc_dvc->carr_freelist = free_carrp;
15901                 asc_dvc->carr_pending_cnt--;
15902
15903                 ASC_ASSERT(scsiq != NULL);
15904                 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
15905
15906                 /*
15907                  * Clear request microcode control flag.
15908                  */
15909                 scsiq->cntl = 0;
15910
15911                 /*
15912                  * Notify the driver of the completed request by passing
15913                  * the ADV_SCSI_REQ_Q pointer to its callback function.
15914                  */
15915                 scsiq->a_flag |= ADV_SCSIQ_DONE;
15916                 adv_isr_callback(asc_dvc, scsiq);
15917                 /*
15918                  * Note: After the driver callback function is called, 'scsiq'
15919                  * can no longer be referenced.
15920                  *
15921                  * Fall through and continue processing other completed
15922                  * requests...
15923                  */
15924
15925                 /*
15926                  * Disable interrupts again in case the driver inadvertently
15927                  * enabled interrupts in its callback function.
15928                  *
15929                  * The DvcEnterCritical() return value is ignored, because
15930                  * the 'flags' saved when AdvISR() was first entered will be
15931                  * used to restore the interrupt flag on exit.
15932                  */
15933                 (void)DvcEnterCritical();
15934         }
15935         DvcLeaveCritical(flags);
15936         return ADV_TRUE;
15937 }
15938
15939 /*
15940  * Send an idle command to the chip and wait for completion.
15941  *
15942  * Command completion is polled for once per microsecond.
15943  *
15944  * The function can be called from anywhere including an interrupt handler.
15945  * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
15946  * functions to prevent reentrancy.
15947  *
15948  * Return Values:
15949  *   ADV_TRUE - command completed successfully
15950  *   ADV_FALSE - command failed
15951  *   ADV_ERROR - command timed out
15952  */
15953 static int
15954 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
15955                ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
15956 {
15957         ulong last_int_level;
15958         int result;
15959         ADV_DCNT i, j;
15960         AdvPortAddr iop_base;
15961
15962         last_int_level = DvcEnterCritical();
15963
15964         iop_base = asc_dvc->iop_base;
15965
15966         /*
15967          * Clear the idle command status which is set by the microcode
15968          * to a non-zero value to indicate when the command is completed.
15969          * The non-zero result is one of the IDLE_CMD_STATUS_* values
15970          * defined in a_advlib.h.
15971          */
15972         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
15973
15974         /*
15975          * Write the idle command value after the idle command parameter
15976          * has been written to avoid a race condition. If the order is not
15977          * followed, the microcode may process the idle command before the
15978          * parameters have been written to LRAM.
15979          */
15980         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
15981                                 cpu_to_le32(idle_cmd_parameter));
15982         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
15983
15984         /*
15985          * Tickle the RISC to tell it to process the idle command.
15986          */
15987         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
15988         if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
15989                 /*
15990                  * Clear the tickle value. In the ASC-3550 the RISC flag
15991                  * command 'clr_tickle_b' does not work unless the host
15992                  * value is cleared.
15993                  */
15994                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
15995         }
15996
15997         /* Wait for up to 100 millisecond for the idle command to timeout. */
15998         for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
15999                 /* Poll once each microsecond for command completion. */
16000                 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
16001                         AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
16002                                         result);
16003                         if (result != 0) {
16004                                 DvcLeaveCritical(last_int_level);
16005                                 return result;
16006                         }
16007                         DvcDelayMicroSecond(asc_dvc, (ushort)1);
16008                 }
16009         }
16010
16011         ASC_ASSERT(0);          /* The idle command should never timeout. */
16012         DvcLeaveCritical(last_int_level);
16013         return ADV_ERROR;
16014 }
16015
16016 static int __devinit
16017 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
16018 {
16019         int req_cnt = 0;
16020         adv_req_t *reqp = NULL;
16021         int sg_cnt = 0;
16022         adv_sgblk_t *sgp;
16023         int warn_code, err_code;
16024
16025         /*
16026          * Allocate buffer carrier structures. The total size
16027          * is about 4 KB, so allocate all at once.
16028          */
16029         boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
16030         ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
16031
16032         if (!boardp->carrp)
16033                 goto kmalloc_failed;
16034
16035         /*
16036          * Allocate up to 'max_host_qng' request structures for the Wide
16037          * board. The total size is about 16 KB, so allocate all at once.
16038          * If the allocation fails decrement and try again.
16039          */
16040         for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
16041                 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
16042
16043                 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
16044                          "bytes %lu\n", reqp, req_cnt,
16045                          (ulong)sizeof(adv_req_t) * req_cnt);
16046
16047                 if (reqp)
16048                         break;
16049         }
16050
16051         if (!reqp)
16052                 goto kmalloc_failed;
16053
16054         boardp->orig_reqp = reqp;
16055
16056         /*
16057          * Allocate up to ADV_TOT_SG_BLOCK request structures for
16058          * the Wide board. Each structure is about 136 bytes.
16059          */
16060         boardp->adv_sgblkp = NULL;
16061         for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
16062                 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
16063
16064                 if (!sgp)
16065                         break;
16066
16067                 sgp->next_sgblkp = boardp->adv_sgblkp;
16068                 boardp->adv_sgblkp = sgp;
16069
16070         }
16071
16072         ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
16073                  sg_cnt, sizeof(adv_sgblk_t),
16074                  (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
16075
16076         if (!boardp->adv_sgblkp)
16077                 goto kmalloc_failed;
16078
16079         adv_dvc_varp->carrier_buf = boardp->carrp;
16080
16081         /*
16082          * Point 'adv_reqp' to the request structures and
16083          * link them together.
16084          */
16085         req_cnt--;
16086         reqp[req_cnt].next_reqp = NULL;
16087         for (; req_cnt > 0; req_cnt--) {
16088                 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
16089         }
16090         boardp->adv_reqp = &reqp[0];
16091
16092         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
16093                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
16094                 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
16095         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
16096                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
16097                            "\n");
16098                 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
16099         } else {
16100                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
16101                            "\n");
16102                 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
16103         }
16104         err_code = adv_dvc_varp->err_code;
16105
16106         if (warn_code || err_code) {
16107                 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
16108                            " error 0x%x\n", boardp->id, warn_code, err_code);
16109         }
16110
16111         goto exit;
16112
16113  kmalloc_failed:
16114         ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
16115                    "failed\n", boardp->id);
16116         err_code = ADV_ERROR;
16117  exit:
16118         return err_code;
16119 }
16120
16121 static void advansys_wide_free_mem(asc_board_t *boardp)
16122 {
16123         kfree(boardp->carrp);
16124         boardp->carrp = NULL;
16125         kfree(boardp->orig_reqp);
16126         boardp->orig_reqp = boardp->adv_reqp = NULL;
16127         while (boardp->adv_sgblkp) {
16128                 adv_sgblk_t *sgp = boardp->adv_sgblkp;
16129                 boardp->adv_sgblkp = sgp->next_sgblkp;
16130                 kfree(sgp);
16131         }
16132 }
16133
16134 static struct Scsi_Host *__devinit
16135 advansys_board_found(int iop, struct device *dev, int bus_type)
16136 {
16137         struct Scsi_Host *shost;
16138         struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
16139         asc_board_t *boardp;
16140         ASC_DVC_VAR *asc_dvc_varp = NULL;
16141         ADV_DVC_VAR *adv_dvc_varp = NULL;
16142         int share_irq;
16143         int warn_code, err_code;
16144         int ret;
16145
16146         /*
16147          * Register the adapter, get its configuration, and
16148          * initialize it.
16149          */
16150         ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
16151         shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
16152         if (!shost)
16153                 return NULL;
16154
16155         /* Initialize private per board data */
16156         boardp = ASC_BOARDP(shost);
16157         memset(boardp, 0, sizeof(asc_board_t));
16158         boardp->id = asc_board_count++;
16159         spin_lock_init(&boardp->lock);
16160         boardp->dev = dev;
16161
16162         /*
16163          * Handle both narrow and wide boards.
16164          *
16165          * If a Wide board was detected, set the board structure
16166          * wide board flag. Set-up the board structure based on
16167          * the board type.
16168          */
16169 #ifdef CONFIG_PCI
16170         if (bus_type == ASC_IS_PCI &&
16171             (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
16172              pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
16173              pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
16174                 boardp->flags |= ASC_IS_WIDE_BOARD;
16175         }
16176 #endif /* CONFIG_PCI */
16177
16178         if (ASC_NARROW_BOARD(boardp)) {
16179                 ASC_DBG(1, "advansys_board_found: narrow board\n");
16180                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
16181                 asc_dvc_varp->bus_type = bus_type;
16182                 asc_dvc_varp->drv_ptr = boardp;
16183                 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
16184                 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
16185                 asc_dvc_varp->iop_base = iop;
16186         } else {
16187 #ifdef CONFIG_PCI
16188                 ASC_DBG(1, "advansys_board_found: wide board\n");
16189                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
16190                 adv_dvc_varp->drv_ptr = boardp;
16191                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
16192                 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
16193                         ASC_DBG(1, "advansys_board_found: ASC-3550\n");
16194                         adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
16195                 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
16196                         ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
16197                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
16198                 } else {
16199                         ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
16200                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
16201                 }
16202
16203                 boardp->asc_n_io_port = pci_resource_len(pdev, 1);
16204                 boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
16205                                                boardp->asc_n_io_port);
16206                 if (!boardp->ioremap_addr) {
16207                         ASC_PRINT3
16208                             ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
16209                              boardp->id, pci_resource_start(pdev, 1),
16210                              boardp->asc_n_io_port);
16211                         goto err_shost;
16212                 }
16213                 adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
16214                 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
16215                          adv_dvc_varp->iop_base);
16216
16217                 /*
16218                  * Even though it isn't used to access wide boards, other
16219                  * than for the debug line below, save I/O Port address so
16220                  * that it can be reported.
16221                  */
16222                 boardp->ioport = iop;
16223
16224                 ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
16225                          "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
16226                          (ushort)inpw(iop));
16227 #endif /* CONFIG_PCI */
16228         }
16229
16230 #ifdef CONFIG_PROC_FS
16231         /*
16232          * Allocate buffer for printing information from
16233          * /proc/scsi/advansys/[0...].
16234          */
16235         boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
16236         if (!boardp->prtbuf) {
16237                 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
16238                            "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
16239                 goto err_unmap;
16240         }
16241 #endif /* CONFIG_PROC_FS */
16242
16243         if (ASC_NARROW_BOARD(boardp)) {
16244                 /*
16245                  * Set the board bus type and PCI IRQ before
16246                  * calling AscInitGetConfig().
16247                  */
16248                 switch (asc_dvc_varp->bus_type) {
16249 #ifdef CONFIG_ISA
16250                 case ASC_IS_ISA:
16251                         shost->unchecked_isa_dma = TRUE;
16252                         share_irq = 0;
16253                         break;
16254                 case ASC_IS_VL:
16255                         shost->unchecked_isa_dma = FALSE;
16256                         share_irq = 0;
16257                         break;
16258                 case ASC_IS_EISA:
16259                         shost->unchecked_isa_dma = FALSE;
16260                         share_irq = IRQF_SHARED;
16261                         break;
16262 #endif /* CONFIG_ISA */
16263 #ifdef CONFIG_PCI
16264                 case ASC_IS_PCI:
16265                         shost->irq = asc_dvc_varp->irq_no = pdev->irq;
16266                         shost->unchecked_isa_dma = FALSE;
16267                         share_irq = IRQF_SHARED;
16268                         break;
16269 #endif /* CONFIG_PCI */
16270                 default:
16271                         ASC_PRINT2
16272                             ("advansys_board_found: board %d: unknown adapter type: %d\n",
16273                              boardp->id, asc_dvc_varp->bus_type);
16274                         shost->unchecked_isa_dma = TRUE;
16275                         share_irq = 0;
16276                         break;
16277                 }
16278         } else {
16279                 /*
16280                  * For Wide boards set PCI information before calling
16281                  * AdvInitGetConfig().
16282                  */
16283 #ifdef CONFIG_PCI
16284                 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
16285                 shost->unchecked_isa_dma = FALSE;
16286                 share_irq = IRQF_SHARED;
16287 #endif /* CONFIG_PCI */
16288         }
16289
16290         /*
16291          * Read the board configuration.
16292          */
16293         if (ASC_NARROW_BOARD(boardp)) {
16294                 /*
16295                  * NOTE: AscInitGetConfig() may change the board's
16296                  * bus_type value. The bus_type value should no
16297                  * longer be used. If the bus_type field must be
16298                  * referenced only use the bit-wise AND operator "&".
16299                  */
16300                 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
16301                 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
16302                 case 0: /* No error */
16303                         break;
16304                 case ASC_WARN_IO_PORT_ROTATE:
16305                         ASC_PRINT1
16306                             ("AscInitGetConfig: board %d: I/O port address modified\n",
16307                              boardp->id);
16308                         break;
16309                 case ASC_WARN_AUTO_CONFIG:
16310                         ASC_PRINT1
16311                             ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
16312                              boardp->id);
16313                         break;
16314                 case ASC_WARN_EEPROM_CHKSUM:
16315                         ASC_PRINT1
16316                             ("AscInitGetConfig: board %d: EEPROM checksum error\n",
16317                              boardp->id);
16318                         break;
16319                 case ASC_WARN_IRQ_MODIFIED:
16320                         ASC_PRINT1
16321                             ("AscInitGetConfig: board %d: IRQ modified\n",
16322                              boardp->id);
16323                         break;
16324                 case ASC_WARN_CMD_QNG_CONFLICT:
16325                         ASC_PRINT1
16326                             ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
16327                              boardp->id);
16328                         break;
16329                 default:
16330                         ASC_PRINT2
16331                             ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
16332                              boardp->id, ret);
16333                         break;
16334                 }
16335                 if ((err_code = asc_dvc_varp->err_code) != 0) {
16336                         ASC_PRINT3
16337                             ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
16338                              boardp->id,
16339                              asc_dvc_varp->init_state, asc_dvc_varp->err_code);
16340                 }
16341         } else {
16342                 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
16343
16344                 ret = AdvInitGetConfig(pdev, adv_dvc_varp);
16345                 if (ret != 0) {
16346                         ASC_PRINT2
16347                             ("AdvInitGetConfig: board %d: warning: 0x%x\n",
16348                              boardp->id, ret);
16349                 }
16350                 if ((err_code = adv_dvc_varp->err_code) != 0) {
16351                         ASC_PRINT2
16352                             ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
16353                              boardp->id, adv_dvc_varp->err_code);
16354                 }
16355         }
16356
16357         if (err_code != 0)
16358                 goto err_free_proc;
16359
16360         /*
16361          * Save the EEPROM configuration so that it can be displayed
16362          * from /proc/scsi/advansys/[0...].
16363          */
16364         if (ASC_NARROW_BOARD(boardp)) {
16365
16366                 ASCEEP_CONFIG *ep;
16367
16368                 /*
16369                  * Set the adapter's target id bit in the 'init_tidmask' field.
16370                  */
16371                 boardp->init_tidmask |=
16372                     ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
16373
16374                 /*
16375                  * Save EEPROM settings for the board.
16376                  */
16377                 ep = &boardp->eep_config.asc_eep;
16378
16379                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
16380                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
16381                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
16382                 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
16383                 ep->start_motor = asc_dvc_varp->start_motor;
16384                 ep->cntl = asc_dvc_varp->dvc_cntl;
16385                 ep->no_scam = asc_dvc_varp->no_scam;
16386                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
16387                 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
16388                 /* 'max_tag_qng' is set to the same value for every device. */
16389                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
16390                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
16391                 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
16392                 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
16393                 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
16394                 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
16395                 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
16396
16397                 /*
16398                  * Modify board configuration.
16399                  */
16400                 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
16401                 switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) {
16402                 case 0: /* No error. */
16403                         break;
16404                 case ASC_WARN_IO_PORT_ROTATE:
16405                         ASC_PRINT1
16406                             ("AscInitSetConfig: board %d: I/O port address modified\n",
16407                              boardp->id);
16408                         break;
16409                 case ASC_WARN_AUTO_CONFIG:
16410                         ASC_PRINT1
16411                             ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
16412                              boardp->id);
16413                         break;
16414                 case ASC_WARN_EEPROM_CHKSUM:
16415                         ASC_PRINT1
16416                             ("AscInitSetConfig: board %d: EEPROM checksum error\n",
16417                              boardp->id);
16418                         break;
16419                 case ASC_WARN_IRQ_MODIFIED:
16420                         ASC_PRINT1
16421                             ("AscInitSetConfig: board %d: IRQ modified\n",
16422                              boardp->id);
16423                         break;
16424                 case ASC_WARN_CMD_QNG_CONFLICT:
16425                         ASC_PRINT1
16426                             ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
16427                              boardp->id);
16428                         break;
16429                 default:
16430                         ASC_PRINT2
16431                             ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
16432                              boardp->id, ret);
16433                         break;
16434                 }
16435                 if (asc_dvc_varp->err_code != 0) {
16436                         ASC_PRINT3
16437                             ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
16438                              boardp->id,
16439                              asc_dvc_varp->init_state, asc_dvc_varp->err_code);
16440                         goto err_free_proc;
16441                 }
16442
16443                 /*
16444                  * Finish initializing the 'Scsi_Host' structure.
16445                  */
16446                 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
16447                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
16448                         shost->irq = asc_dvc_varp->irq_no;
16449                 }
16450         } else {
16451                 ADVEEP_3550_CONFIG *ep_3550;
16452                 ADVEEP_38C0800_CONFIG *ep_38C0800;
16453                 ADVEEP_38C1600_CONFIG *ep_38C1600;
16454
16455                 /*
16456                  * Save Wide EEP Configuration Information.
16457                  */
16458                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
16459                         ep_3550 = &boardp->eep_config.adv_3550_eep;
16460
16461                         ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
16462                         ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
16463                         ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
16464                         ep_3550->termination = adv_dvc_varp->cfg->termination;
16465                         ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
16466                         ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
16467                         ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
16468                         ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
16469                         ep_3550->ultra_able = adv_dvc_varp->ultra_able;
16470                         ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
16471                         ep_3550->start_motor = adv_dvc_varp->start_motor;
16472                         ep_3550->scsi_reset_delay =
16473                             adv_dvc_varp->scsi_reset_wait;
16474                         ep_3550->serial_number_word1 =
16475                             adv_dvc_varp->cfg->serial1;
16476                         ep_3550->serial_number_word2 =
16477                             adv_dvc_varp->cfg->serial2;
16478                         ep_3550->serial_number_word3 =
16479                             adv_dvc_varp->cfg->serial3;
16480                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
16481                         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
16482
16483                         ep_38C0800->adapter_scsi_id =
16484                             adv_dvc_varp->chip_scsi_id;
16485                         ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
16486                         ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
16487                         ep_38C0800->termination_lvd =
16488                             adv_dvc_varp->cfg->termination;
16489                         ep_38C0800->disc_enable =
16490                             adv_dvc_varp->cfg->disc_enable;
16491                         ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
16492                         ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
16493                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
16494                         ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
16495                         ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
16496                         ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
16497                         ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
16498                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
16499                         ep_38C0800->start_motor = adv_dvc_varp->start_motor;
16500                         ep_38C0800->scsi_reset_delay =
16501                             adv_dvc_varp->scsi_reset_wait;
16502                         ep_38C0800->serial_number_word1 =
16503                             adv_dvc_varp->cfg->serial1;
16504                         ep_38C0800->serial_number_word2 =
16505                             adv_dvc_varp->cfg->serial2;
16506                         ep_38C0800->serial_number_word3 =
16507                             adv_dvc_varp->cfg->serial3;
16508                 } else {
16509                         ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
16510
16511                         ep_38C1600->adapter_scsi_id =
16512                             adv_dvc_varp->chip_scsi_id;
16513                         ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
16514                         ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
16515                         ep_38C1600->termination_lvd =
16516                             adv_dvc_varp->cfg->termination;
16517                         ep_38C1600->disc_enable =
16518                             adv_dvc_varp->cfg->disc_enable;
16519                         ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
16520                         ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
16521                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
16522                         ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
16523                         ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
16524                         ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
16525                         ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
16526                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
16527                         ep_38C1600->start_motor = adv_dvc_varp->start_motor;
16528                         ep_38C1600->scsi_reset_delay =
16529                             adv_dvc_varp->scsi_reset_wait;
16530                         ep_38C1600->serial_number_word1 =
16531                             adv_dvc_varp->cfg->serial1;
16532                         ep_38C1600->serial_number_word2 =
16533                             adv_dvc_varp->cfg->serial2;
16534                         ep_38C1600->serial_number_word3 =
16535                             adv_dvc_varp->cfg->serial3;
16536                 }
16537
16538                 /*
16539                  * Set the adapter's target id bit in the 'init_tidmask' field.
16540                  */
16541                 boardp->init_tidmask |=
16542                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
16543         }
16544
16545         /*
16546          * Channels are numbered beginning with 0. For AdvanSys one host
16547          * structure supports one channel. Multi-channel boards have a
16548          * separate host structure for each channel.
16549          */
16550         shost->max_channel = 0;
16551         if (ASC_NARROW_BOARD(boardp)) {
16552                 shost->max_id = ASC_MAX_TID + 1;
16553                 shost->max_lun = ASC_MAX_LUN + 1;
16554
16555                 shost->io_port = asc_dvc_varp->iop_base;
16556                 boardp->asc_n_io_port = ASC_IOADR_GAP;
16557                 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
16558
16559                 /* Set maximum number of queues the adapter can handle. */
16560                 shost->can_queue = asc_dvc_varp->max_total_qng;
16561         } else {
16562                 shost->max_id = ADV_MAX_TID + 1;
16563                 shost->max_lun = ADV_MAX_LUN + 1;
16564
16565                 /*
16566                  * Save the I/O Port address and length even though
16567                  * I/O ports are not used to access Wide boards.
16568                  * Instead the Wide boards are accessed with
16569                  * PCI Memory Mapped I/O.
16570                  */
16571                 shost->io_port = iop;
16572
16573                 shost->this_id = adv_dvc_varp->chip_scsi_id;
16574
16575                 /* Set maximum number of queues the adapter can handle. */
16576                 shost->can_queue = adv_dvc_varp->max_host_qng;
16577         }
16578
16579         /*
16580          * Following v1.3.89, 'cmd_per_lun' is no longer needed
16581          * and should be set to zero.
16582          *
16583          * But because of a bug introduced in v1.3.89 if the driver is
16584          * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
16585          * SCSI function 'allocate_device' will panic. To allow the driver
16586          * to work as a module in these kernels set 'cmd_per_lun' to 1.
16587          *
16588          * Note: This is wrong.  cmd_per_lun should be set to the depth
16589          * you want on untagged devices always.
16590          #ifdef MODULE
16591          */
16592         shost->cmd_per_lun = 1;
16593 /* #else
16594             shost->cmd_per_lun = 0;
16595 #endif */
16596
16597         /*
16598          * Set the maximum number of scatter-gather elements the
16599          * adapter can handle.
16600          */
16601         if (ASC_NARROW_BOARD(boardp)) {
16602                 /*
16603                  * Allow two commands with 'sg_tablesize' scatter-gather
16604                  * elements to be executed simultaneously. This value is
16605                  * the theoretical hardware limit. It may be decreased
16606                  * below.
16607                  */
16608                 shost->sg_tablesize =
16609                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
16610                      ASC_SG_LIST_PER_Q) + 1;
16611         } else {
16612                 shost->sg_tablesize = ADV_MAX_SG_LIST;
16613         }
16614
16615         /*
16616          * The value of 'sg_tablesize' can not exceed the SCSI
16617          * mid-level driver definition of SG_ALL. SG_ALL also
16618          * must not be exceeded, because it is used to define the
16619          * size of the scatter-gather table in 'struct asc_sg_head'.
16620          */
16621         if (shost->sg_tablesize > SG_ALL) {
16622                 shost->sg_tablesize = SG_ALL;
16623         }
16624
16625         ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
16626
16627         /* BIOS start address. */
16628         if (ASC_NARROW_BOARD(boardp)) {
16629                 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
16630                                                     asc_dvc_varp->bus_type);
16631         } else {
16632                 /*
16633                  * Fill-in BIOS board variables. The Wide BIOS saves
16634                  * information in LRAM that is used by the driver.
16635                  */
16636                 AdvReadWordLram(adv_dvc_varp->iop_base,
16637                                 BIOS_SIGNATURE, boardp->bios_signature);
16638                 AdvReadWordLram(adv_dvc_varp->iop_base,
16639                                 BIOS_VERSION, boardp->bios_version);
16640                 AdvReadWordLram(adv_dvc_varp->iop_base,
16641                                 BIOS_CODESEG, boardp->bios_codeseg);
16642                 AdvReadWordLram(adv_dvc_varp->iop_base,
16643                                 BIOS_CODELEN, boardp->bios_codelen);
16644
16645                 ASC_DBG2(1,
16646                          "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
16647                          boardp->bios_signature, boardp->bios_version);
16648
16649                 ASC_DBG2(1,
16650                          "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
16651                          boardp->bios_codeseg, boardp->bios_codelen);
16652
16653                 /*
16654                  * If the BIOS saved a valid signature, then fill in
16655                  * the BIOS code segment base address.
16656                  */
16657                 if (boardp->bios_signature == 0x55AA) {
16658                         /*
16659                          * Convert x86 realmode code segment to a linear
16660                          * address by shifting left 4.
16661                          */
16662                         shost->base = ((ulong)boardp->bios_codeseg << 4);
16663                 } else {
16664                         shost->base = 0;
16665                 }
16666         }
16667
16668         /*
16669          * Register Board Resources - I/O Port, DMA, IRQ
16670          */
16671
16672         /* Register DMA Channel for Narrow boards. */
16673         shost->dma_channel = NO_ISA_DMA;        /* Default to no ISA DMA. */
16674 #ifdef CONFIG_ISA
16675         if (ASC_NARROW_BOARD(boardp)) {
16676                 /* Register DMA channel for ISA bus. */
16677                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
16678                         shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
16679                         ret = request_dma(shost->dma_channel, "advansys");
16680                         if (ret) {
16681                                 ASC_PRINT3
16682                                     ("advansys_board_found: board %d: request_dma() %d failed %d\n",
16683                                      boardp->id, shost->dma_channel, ret);
16684                                 goto err_free_proc;
16685                         }
16686                         AscEnableIsaDma(shost->dma_channel);
16687                 }
16688         }
16689 #endif /* CONFIG_ISA */
16690
16691         /* Register IRQ Number. */
16692         ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
16693
16694         ret = request_irq(shost->irq, advansys_interrupt, share_irq,
16695                           "advansys", shost);
16696
16697         if (ret) {
16698                 if (ret == -EBUSY) {
16699                         ASC_PRINT2
16700                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
16701                              boardp->id, shost->irq);
16702                 } else if (ret == -EINVAL) {
16703                         ASC_PRINT2
16704                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
16705                              boardp->id, shost->irq);
16706                 } else {
16707                         ASC_PRINT3
16708                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
16709                              boardp->id, shost->irq, ret);
16710                 }
16711                 goto err_free_dma;
16712         }
16713
16714         /*
16715          * Initialize board RISC chip and enable interrupts.
16716          */
16717         if (ASC_NARROW_BOARD(boardp)) {
16718                 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
16719                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
16720                 err_code = asc_dvc_varp->err_code;
16721
16722                 if (warn_code || err_code) {
16723                         ASC_PRINT4
16724                             ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
16725                              boardp->id,
16726                              asc_dvc_varp->init_state, warn_code, err_code);
16727                 }
16728         } else {
16729                 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
16730         }
16731
16732         if (err_code != 0)
16733                 goto err_free_wide_mem;
16734
16735         ASC_DBG_PRT_SCSI_HOST(2, shost);
16736
16737         ret = scsi_add_host(shost, dev);
16738         if (ret)
16739                 goto err_free_wide_mem;
16740
16741         scsi_scan_host(shost);
16742         return shost;
16743
16744  err_free_wide_mem:
16745         advansys_wide_free_mem(boardp);
16746         free_irq(shost->irq, shost);
16747  err_free_dma:
16748         if (shost->dma_channel != NO_ISA_DMA)
16749                 free_dma(shost->dma_channel);
16750  err_free_proc:
16751         kfree(boardp->prtbuf);
16752  err_unmap:
16753         if (boardp->ioremap_addr)
16754                 iounmap(boardp->ioremap_addr);
16755  err_shost:
16756         scsi_host_put(shost);
16757         return NULL;
16758 }
16759
16760 /*
16761  * advansys_release()
16762  *
16763  * Release resources allocated for a single AdvanSys adapter.
16764  */
16765 static int advansys_release(struct Scsi_Host *shost)
16766 {
16767         asc_board_t *boardp;
16768
16769         ASC_DBG(1, "advansys_release: begin\n");
16770         scsi_remove_host(shost);
16771         boardp = ASC_BOARDP(shost);
16772         free_irq(shost->irq, shost);
16773         if (shost->dma_channel != NO_ISA_DMA) {
16774                 ASC_DBG(1, "advansys_release: free_dma()\n");
16775                 free_dma(shost->dma_channel);
16776         }
16777         if (ASC_WIDE_BOARD(boardp)) {
16778                 iounmap(boardp->ioremap_addr);
16779                 advansys_wide_free_mem(boardp);
16780         }
16781         kfree(boardp->prtbuf);
16782         scsi_host_put(shost);
16783         ASC_DBG(1, "advansys_release: end\n");
16784         return 0;
16785 }
16786
16787 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
16788         0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
16789         0x0210, 0x0230, 0x0250, 0x0330
16790 };
16791
16792 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
16793 {
16794         PortAddr iop_base = _asc_def_iop_base[id];
16795         struct Scsi_Host *shost;
16796
16797         if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
16798                 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
16799                          iop_base);
16800                 return -ENODEV;
16801         }
16802         ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
16803         if (!AscFindSignature(iop_base))
16804                 goto nodev;
16805         if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
16806                 goto nodev;
16807
16808         shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
16809         if (!shost)
16810                 goto nodev;
16811
16812         dev_set_drvdata(dev, shost);
16813         return 0;
16814
16815  nodev:
16816         release_region(iop_base, ASC_IOADR_GAP);
16817         return -ENODEV;
16818 }
16819
16820 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
16821 {
16822         int ioport = _asc_def_iop_base[id];
16823         advansys_release(dev_get_drvdata(dev));
16824         release_region(ioport, ASC_IOADR_GAP);
16825         return 0;
16826 }
16827
16828 static struct isa_driver advansys_isa_driver = {
16829         .probe          = advansys_isa_probe,
16830         .remove         = __devexit_p(advansys_isa_remove),
16831         .driver = {
16832                 .owner  = THIS_MODULE,
16833                 .name   = "advansys",
16834         },
16835 };
16836
16837 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
16838 {
16839         PortAddr iop_base = _asc_def_iop_base[id];
16840         struct Scsi_Host *shost;
16841
16842         if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
16843                 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
16844                          iop_base);
16845                 return -ENODEV;
16846         }
16847         ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
16848         if (!AscFindSignature(iop_base))
16849                 goto nodev;
16850         /*
16851          * I don't think this condition can actually happen, but the old
16852          * driver did it, and the chances of finding a VLB setup in 2007
16853          * to do testing with is slight to none.
16854          */
16855         if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
16856                 goto nodev;
16857
16858         shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
16859         if (!shost)
16860                 goto nodev;
16861
16862         dev_set_drvdata(dev, shost);
16863         return 0;
16864
16865  nodev:
16866         release_region(iop_base, ASC_IOADR_GAP);
16867         return -ENODEV;
16868 }
16869
16870 static struct isa_driver advansys_vlb_driver = {
16871         .probe          = advansys_vlb_probe,
16872         .remove         = __devexit_p(advansys_isa_remove),
16873         .driver = {
16874                 .owner  = THIS_MODULE,
16875                 .name   = "advansys_vlb",
16876         },
16877 };
16878
16879 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
16880         { "ABP7401" },
16881         { "ABP7501" },
16882         { "" }
16883 };
16884
16885 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
16886
16887 /*
16888  * EISA is a little more tricky than PCI; each EISA device may have two
16889  * channels, and this driver is written to make each channel its own Scsi_Host
16890  */
16891 struct eisa_scsi_data {
16892         struct Scsi_Host *host[2];
16893 };
16894
16895 static int __devinit advansys_eisa_probe(struct device *dev)
16896 {
16897         int i, ioport;
16898         int err;
16899         struct eisa_device *edev = to_eisa_device(dev);
16900         struct eisa_scsi_data *data;
16901
16902         err = -ENOMEM;
16903         data = kzalloc(sizeof(*data), GFP_KERNEL);
16904         if (!data)
16905                 goto fail;
16906         ioport = edev->base_addr + 0xc30;
16907
16908         err = -ENODEV;
16909         for (i = 0; i < 2; i++, ioport += 0x20) {
16910                 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
16911                         printk(KERN_WARNING "Region %x-%x busy\n", ioport,
16912                                ioport + ASC_IOADR_GAP - 1);
16913                         continue;
16914                 }
16915                 if (!AscFindSignature(ioport)) {
16916                         release_region(ioport, ASC_IOADR_GAP);
16917                         continue;
16918                 }
16919
16920                 /*
16921                  * I don't know why we need to do this for EISA chips, but
16922                  * not for any others.  It looks to be equivalent to
16923                  * AscGetChipCfgMsw, but I may have overlooked something,
16924                  * so I'm not converting it until I get an EISA board to
16925                  * test with.
16926                  */
16927                 inw(ioport + 4);
16928                 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
16929                 if (data->host[i]) {
16930                         err = 0;
16931                 } else {
16932                         release_region(ioport, ASC_IOADR_GAP);
16933                 }
16934         }
16935
16936         if (err) {
16937                 kfree(data);
16938         } else {
16939                 dev_set_drvdata(dev, data);
16940         }
16941
16942  fail:
16943         return err;
16944 }
16945
16946 static __devexit int advansys_eisa_remove(struct device *dev)
16947 {
16948         int i;
16949         struct eisa_scsi_data *data = dev_get_drvdata(dev);
16950
16951         for (i = 0; i < 2; i++) {
16952                 int ioport;
16953                 struct Scsi_Host *shost = data->host[i];
16954                 if (!shost)
16955                         continue;
16956                 ioport = shost->io_port;
16957                 advansys_release(shost);
16958                 release_region(ioport, ASC_IOADR_GAP);
16959         }
16960
16961         kfree(data);
16962         return 0;
16963 }
16964
16965 static struct eisa_driver advansys_eisa_driver = {
16966         .id_table =             advansys_eisa_table,
16967         .driver = {
16968                 .name =         "advansys",
16969                 .probe =        advansys_eisa_probe,
16970                 .remove =       __devexit_p(advansys_eisa_remove),
16971         }
16972 };
16973
16974 /* PCI Devices supported by this driver */
16975 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
16976         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
16977          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
16978         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
16979          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
16980         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
16981          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
16982         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
16983          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
16984         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
16985          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
16986         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
16987          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
16988         {}
16989 };
16990
16991 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
16992
16993 static void __devinit advansys_set_latency(struct pci_dev *pdev)
16994 {
16995         if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
16996             (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
16997                 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
16998         } else {
16999                 u8 latency;
17000                 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
17001                 if (latency < 0x20)
17002                         pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
17003         }
17004 }
17005
17006 static int __devinit
17007 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
17008 {
17009         int err, ioport;
17010         struct Scsi_Host *shost;
17011
17012         err = pci_enable_device(pdev);
17013         if (err)
17014                 goto fail;
17015         err = pci_request_regions(pdev, "advansys");
17016         if (err)
17017                 goto disable_device;
17018         pci_set_master(pdev);
17019         advansys_set_latency(pdev);
17020
17021         if (pci_resource_len(pdev, 0) == 0)
17022                 goto nodev;
17023
17024         ioport = pci_resource_start(pdev, 0);
17025         shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
17026
17027         if (!shost)
17028                 goto nodev;
17029
17030         pci_set_drvdata(pdev, shost);
17031         return 0;
17032
17033  nodev:
17034         err = -ENODEV;
17035         pci_release_regions(pdev);
17036  disable_device:
17037         pci_disable_device(pdev);
17038  fail:
17039         return err;
17040 }
17041
17042 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
17043 {
17044         advansys_release(pci_get_drvdata(pdev));
17045         pci_release_regions(pdev);
17046         pci_disable_device(pdev);
17047 }
17048
17049 static struct pci_driver advansys_pci_driver = {
17050         .name =         "advansys",
17051         .id_table =     advansys_pci_tbl,
17052         .probe =        advansys_pci_probe,
17053         .remove =       __devexit_p(advansys_pci_remove),
17054 };
17055
17056 static int __init advansys_init(void)
17057 {
17058         int error;
17059
17060         error = isa_register_driver(&advansys_isa_driver,
17061                                     ASC_IOADR_TABLE_MAX_IX);
17062         if (error)
17063                 goto fail;
17064
17065         error = isa_register_driver(&advansys_vlb_driver,
17066                                     ASC_IOADR_TABLE_MAX_IX);
17067         if (error)
17068                 goto unregister_isa;
17069
17070         error = eisa_driver_register(&advansys_eisa_driver);
17071         if (error)
17072                 goto unregister_vlb;
17073
17074         error = pci_register_driver(&advansys_pci_driver);
17075         if (error)
17076                 goto unregister_eisa;
17077
17078         return 0;
17079
17080  unregister_eisa:
17081         eisa_driver_unregister(&advansys_eisa_driver);
17082  unregister_vlb:
17083         isa_unregister_driver(&advansys_vlb_driver);
17084  unregister_isa:
17085         isa_unregister_driver(&advansys_isa_driver);
17086  fail:
17087         return error;
17088 }
17089
17090 static void __exit advansys_exit(void)
17091 {
17092         pci_unregister_driver(&advansys_pci_driver);
17093         eisa_driver_unregister(&advansys_eisa_driver);
17094         isa_unregister_driver(&advansys_vlb_driver);
17095         isa_unregister_driver(&advansys_isa_driver);
17096 }
17097
17098 module_init(advansys_init);
17099 module_exit(advansys_exit);
17100
17101 MODULE_LICENSE("GPL");