linux/drivers/scsi/advansys.c
<<
>>
Prefs
   1#define DRV_NAME "advansys"
   2#define ASC_VERSION "3.4"       /* AdvanSys Driver Version */
   3
   4/*
   5 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
   6 *
   7 * Copyright (c) 1995-2000 Advanced System Products, Inc.
   8 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
   9 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
  10 * All Rights Reserved.
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2 of the License, or
  15 * (at your option) any later version.
  16 */
  17
  18/*
  19 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
  20 * changed its name to ConnectCom Solutions, Inc.
  21 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
  22 */
  23
  24#include <linux/module.h>
  25#include <linux/string.h>
  26#include <linux/kernel.h>
  27#include <linux/types.h>
  28#include <linux/ioport.h>
  29#include <linux/interrupt.h>
  30#include <linux/delay.h>
  31#include <linux/slab.h>
  32#include <linux/mm.h>
  33#include <linux/proc_fs.h>
  34#include <linux/init.h>
  35#include <linux/blkdev.h>
  36#include <linux/isa.h>
  37#include <linux/eisa.h>
  38#include <linux/pci.h>
  39#include <linux/spinlock.h>
  40#include <linux/dma-mapping.h>
  41
  42#include <asm/io.h>
  43#include <asm/system.h>
  44#include <asm/dma.h>
  45
  46#include <scsi/scsi_cmnd.h>
  47#include <scsi/scsi_device.h>
  48#include <scsi/scsi_tcq.h>
  49#include <scsi/scsi.h>
  50#include <scsi/scsi_host.h>
  51
  52/* FIXME:
  53 *
  54 *  1. Although all of the necessary command mapping places have the
  55 *     appropriate dma_map.. APIs, the driver still processes its internal
  56 *     queue using bus_to_virt() and virt_to_bus() which are illegal under
  57 *     the API.  The entire queue processing structure will need to be
  58 *     altered to fix this.
  59 *  2. Need to add memory mapping workaround. Test the memory mapping.
  60 *     If it doesn't work revert to I/O port access. Can a test be done
  61 *     safely?
  62 *  3. Handle an interrupt not working. Keep an interrupt counter in
  63 *     the interrupt handler. In the timeout function if the interrupt
  64 *     has not occurred then print a message and run in polled mode.
  65 *  4. Need to add support for target mode commands, cf. CAM XPT.
  66 *  5. check DMA mapping functions for failure
  67 *  6. Use scsi_transport_spi
  68 *  7. advansys_info is not safe against multiple simultaneous callers
  69 *  8. Add module_param to override ISA/VLB ioport array
  70 */
  71#warning this driver is still not properly converted to the DMA API
  72
  73/* Enable driver /proc statistics. */
  74#define ADVANSYS_STATS
  75
  76/* Enable driver tracing. */
  77#undef ADVANSYS_DEBUG
  78
  79/*
  80 * Portable Data Types
  81 *
  82 * Any instance where a 32-bit long or pointer type is assumed
  83 * for precision or HW defined structures, the following define
  84 * types must be used. In Linux the char, short, and int types
  85 * are all consistent at 8, 16, and 32 bits respectively. Pointers
  86 * and long types are 64 bits on Alpha and UltraSPARC.
  87 */
  88#define ASC_PADDR __u32         /* Physical/Bus address data type. */
  89#define ASC_VADDR __u32         /* Virtual address data type. */
  90#define ASC_DCNT  __u32         /* Unsigned Data count type. */
  91#define ASC_SDCNT __s32         /* Signed Data count type. */
  92
  93typedef unsigned char uchar;
  94
  95#ifndef TRUE
  96#define TRUE     (1)
  97#endif
  98#ifndef FALSE
  99#define FALSE    (0)
 100#endif
 101
 102#define ERR      (-1)
 103#define UW_ERR   (uint)(0xFFFF)
 104#define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
 105
 106#define PCI_VENDOR_ID_ASP               0x10cd
 107#define PCI_DEVICE_ID_ASP_1200A         0x1100
 108#define PCI_DEVICE_ID_ASP_ABP940        0x1200
 109#define PCI_DEVICE_ID_ASP_ABP940U       0x1300
 110#define PCI_DEVICE_ID_ASP_ABP940UW      0x2300
 111#define PCI_DEVICE_ID_38C0800_REV1      0x2500
 112#define PCI_DEVICE_ID_38C1600_REV1      0x2700
 113
 114/*
 115 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
 116 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
 117 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
 118 * SRB structure.
 119 */
 120#define CC_VERY_LONG_SG_LIST 0
 121#define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
 122
 123#define PortAddr                 unsigned int   /* port address size  */
 124#define inp(port)                inb(port)
 125#define outp(port, byte)         outb((byte), (port))
 126
 127#define inpw(port)               inw(port)
 128#define outpw(port, word)        outw((word), (port))
 129
 130#define ASC_MAX_SG_QUEUE    7
 131#define ASC_MAX_SG_LIST     255
 132
 133#define ASC_CS_TYPE  unsigned short
 134
 135#define ASC_IS_ISA          (0x0001)
 136#define ASC_IS_ISAPNP       (0x0081)
 137#define ASC_IS_EISA         (0x0002)
 138#define ASC_IS_PCI          (0x0004)
 139#define ASC_IS_PCI_ULTRA    (0x0104)
 140#define ASC_IS_PCMCIA       (0x0008)
 141#define ASC_IS_MCA          (0x0020)
 142#define ASC_IS_VL           (0x0040)
 143#define ASC_IS_WIDESCSI_16  (0x0100)
 144#define ASC_IS_WIDESCSI_32  (0x0200)
 145#define ASC_IS_BIG_ENDIAN   (0x8000)
 146
 147#define ASC_CHIP_MIN_VER_VL      (0x01)
 148#define ASC_CHIP_MAX_VER_VL      (0x07)
 149#define ASC_CHIP_MIN_VER_PCI     (0x09)
 150#define ASC_CHIP_MAX_VER_PCI     (0x0F)
 151#define ASC_CHIP_VER_PCI_BIT     (0x08)
 152#define ASC_CHIP_MIN_VER_ISA     (0x11)
 153#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
 154#define ASC_CHIP_MAX_VER_ISA     (0x27)
 155#define ASC_CHIP_VER_ISA_BIT     (0x30)
 156#define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
 157#define ASC_CHIP_VER_ASYN_BUG    (0x21)
 158#define ASC_CHIP_VER_PCI             0x08
 159#define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
 160#define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
 161#define ASC_CHIP_MIN_VER_EISA (0x41)
 162#define ASC_CHIP_MAX_VER_EISA (0x47)
 163#define ASC_CHIP_VER_EISA_BIT (0x40)
 164#define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
 165#define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
 166#define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
 167#define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
 168
 169#define ASC_SCSI_ID_BITS  3
 170#define ASC_SCSI_TIX_TYPE     uchar
 171#define ASC_ALL_DEVICE_BIT_SET  0xFF
 172#define ASC_SCSI_BIT_ID_TYPE  uchar
 173#define ASC_MAX_TID       7
 174#define ASC_MAX_LUN       7
 175#define ASC_SCSI_WIDTH_BIT_SET  0xFF
 176#define ASC_MAX_SENSE_LEN   32
 177#define ASC_MIN_SENSE_LEN   14
 178#define ASC_SCSI_RESET_HOLD_TIME_US  60
 179
 180/*
 181 * Narrow boards only support 12-byte commands, while wide boards
 182 * extend to 16-byte commands.
 183 */
 184#define ASC_MAX_CDB_LEN     12
 185#define ADV_MAX_CDB_LEN     16
 186
 187#define MS_SDTR_LEN    0x03
 188#define MS_WDTR_LEN    0x02
 189
 190#define ASC_SG_LIST_PER_Q   7
 191#define QS_FREE        0x00
 192#define QS_READY       0x01
 193#define QS_DISC1       0x02
 194#define QS_DISC2       0x04
 195#define QS_BUSY        0x08
 196#define QS_ABORTED     0x40
 197#define QS_DONE        0x80
 198#define QC_NO_CALLBACK   0x01
 199#define QC_SG_SWAP_QUEUE 0x02
 200#define QC_SG_HEAD       0x04
 201#define QC_DATA_IN       0x08
 202#define QC_DATA_OUT      0x10
 203#define QC_URGENT        0x20
 204#define QC_MSG_OUT       0x40
 205#define QC_REQ_SENSE     0x80
 206#define QCSG_SG_XFER_LIST  0x02
 207#define QCSG_SG_XFER_MORE  0x04
 208#define QCSG_SG_XFER_END   0x08
 209#define QD_IN_PROGRESS       0x00
 210#define QD_NO_ERROR          0x01
 211#define QD_ABORTED_BY_HOST   0x02
 212#define QD_WITH_ERROR        0x04
 213#define QD_INVALID_REQUEST   0x80
 214#define QD_INVALID_HOST_NUM  0x81
 215#define QD_INVALID_DEVICE    0x82
 216#define QD_ERR_INTERNAL      0xFF
 217#define QHSTA_NO_ERROR               0x00
 218#define QHSTA_M_SEL_TIMEOUT          0x11
 219#define QHSTA_M_DATA_OVER_RUN        0x12
 220#define QHSTA_M_DATA_UNDER_RUN       0x12
 221#define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
 222#define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
 223#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
 224#define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
 225#define QHSTA_D_HOST_ABORT_FAILED       0x23
 226#define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
 227#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
 228#define QHSTA_D_ASPI_NO_BUF_POOL        0x26
 229#define QHSTA_M_WTM_TIMEOUT         0x41
 230#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
 231#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
 232#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
 233#define QHSTA_M_TARGET_STATUS_BUSY  0x45
 234#define QHSTA_M_BAD_TAG_CODE        0x46
 235#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
 236#define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
 237#define QHSTA_D_LRAM_CMP_ERROR        0x81
 238#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
 239#define ASC_FLAG_SCSIQ_REQ        0x01
 240#define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
 241#define ASC_FLAG_BIOS_ASYNC_IO    0x04
 242#define ASC_FLAG_SRB_LINEAR_ADDR  0x08
 243#define ASC_FLAG_WIN16            0x10
 244#define ASC_FLAG_WIN32            0x20
 245#define ASC_FLAG_ISA_OVER_16MB    0x40
 246#define ASC_FLAG_DOS_VM_CALLBACK  0x80
 247#define ASC_TAG_FLAG_EXTRA_BYTES               0x10
 248#define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
 249#define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
 250#define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
 251#define ASC_SCSIQ_CPY_BEG              4
 252#define ASC_SCSIQ_SGHD_CPY_BEG         2
 253#define ASC_SCSIQ_B_FWD                0
 254#define ASC_SCSIQ_B_BWD                1
 255#define ASC_SCSIQ_B_STATUS             2
 256#define ASC_SCSIQ_B_QNO                3
 257#define ASC_SCSIQ_B_CNTL               4
 258#define ASC_SCSIQ_B_SG_QUEUE_CNT       5
 259#define ASC_SCSIQ_D_DATA_ADDR          8
 260#define ASC_SCSIQ_D_DATA_CNT          12
 261#define ASC_SCSIQ_B_SENSE_LEN         20
 262#define ASC_SCSIQ_DONE_INFO_BEG       22
 263#define ASC_SCSIQ_D_SRBPTR            22
 264#define ASC_SCSIQ_B_TARGET_IX         26
 265#define ASC_SCSIQ_B_CDB_LEN           28
 266#define ASC_SCSIQ_B_TAG_CODE          29
 267#define ASC_SCSIQ_W_VM_ID             30
 268#define ASC_SCSIQ_DONE_STATUS         32
 269#define ASC_SCSIQ_HOST_STATUS         33
 270#define ASC_SCSIQ_SCSI_STATUS         34
 271#define ASC_SCSIQ_CDB_BEG             36
 272#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
 273#define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
 274#define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
 275#define ASC_SCSIQ_B_SG_WK_QP          49
 276#define ASC_SCSIQ_B_SG_WK_IX          50
 277#define ASC_SCSIQ_W_ALT_DC1           52
 278#define ASC_SCSIQ_B_LIST_CNT          6
 279#define ASC_SCSIQ_B_CUR_LIST_CNT      7
 280#define ASC_SGQ_B_SG_CNTL             4
 281#define ASC_SGQ_B_SG_HEAD_QP          5
 282#define ASC_SGQ_B_SG_LIST_CNT         6
 283#define ASC_SGQ_B_SG_CUR_LIST_CNT     7
 284#define ASC_SGQ_LIST_BEG              8
 285#define ASC_DEF_SCSI1_QNG    4
 286#define ASC_MAX_SCSI1_QNG    4
 287#define ASC_DEF_SCSI2_QNG    16
 288#define ASC_MAX_SCSI2_QNG    32
 289#define ASC_TAG_CODE_MASK    0x23
 290#define ASC_STOP_REQ_RISC_STOP      0x01
 291#define ASC_STOP_ACK_RISC_STOP      0x03
 292#define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
 293#define ASC_STOP_CLEAN_UP_DISC_Q    0x20
 294#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
 295#define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
 296#define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
 297#define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
 298#define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
 299#define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
 300#define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
 301#define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
 302
 303typedef struct asc_scsiq_1 {
 304        uchar status;
 305        uchar q_no;
 306        uchar cntl;
 307        uchar sg_queue_cnt;
 308        uchar target_id;
 309        uchar target_lun;
 310        ASC_PADDR data_addr;
 311        ASC_DCNT data_cnt;
 312        ASC_PADDR sense_addr;
 313        uchar sense_len;
 314        uchar extra_bytes;
 315} ASC_SCSIQ_1;
 316
 317typedef struct asc_scsiq_2 {
 318        ASC_VADDR srb_ptr;
 319        uchar target_ix;
 320        uchar flag;
 321        uchar cdb_len;
 322        uchar tag_code;
 323        ushort vm_id;
 324} ASC_SCSIQ_2;
 325
 326typedef struct asc_scsiq_3 {
 327        uchar done_stat;
 328        uchar host_stat;
 329        uchar scsi_stat;
 330        uchar scsi_msg;
 331} ASC_SCSIQ_3;
 332
 333typedef struct asc_scsiq_4 {
 334        uchar cdb[ASC_MAX_CDB_LEN];
 335        uchar y_first_sg_list_qp;
 336        uchar y_working_sg_qp;
 337        uchar y_working_sg_ix;
 338        uchar y_res;
 339        ushort x_req_count;
 340        ushort x_reconnect_rtn;
 341        ASC_PADDR x_saved_data_addr;
 342        ASC_DCNT x_saved_data_cnt;
 343} ASC_SCSIQ_4;
 344
 345typedef struct asc_q_done_info {
 346        ASC_SCSIQ_2 d2;
 347        ASC_SCSIQ_3 d3;
 348        uchar q_status;
 349        uchar q_no;
 350        uchar cntl;
 351        uchar sense_len;
 352        uchar extra_bytes;
 353        uchar res;
 354        ASC_DCNT remain_bytes;
 355} ASC_QDONE_INFO;
 356
 357typedef struct asc_sg_list {
 358        ASC_PADDR addr;
 359        ASC_DCNT bytes;
 360} ASC_SG_LIST;
 361
 362typedef struct asc_sg_head {
 363        ushort entry_cnt;
 364        ushort queue_cnt;
 365        ushort entry_to_copy;
 366        ushort res;
 367        ASC_SG_LIST sg_list[0];
 368} ASC_SG_HEAD;
 369
 370typedef struct asc_scsi_q {
 371        ASC_SCSIQ_1 q1;
 372        ASC_SCSIQ_2 q2;
 373        uchar *cdbptr;
 374        ASC_SG_HEAD *sg_head;
 375        ushort remain_sg_entry_cnt;
 376        ushort next_sg_index;
 377} ASC_SCSI_Q;
 378
 379typedef struct asc_scsi_req_q {
 380        ASC_SCSIQ_1 r1;
 381        ASC_SCSIQ_2 r2;
 382        uchar *cdbptr;
 383        ASC_SG_HEAD *sg_head;
 384        uchar *sense_ptr;
 385        ASC_SCSIQ_3 r3;
 386        uchar cdb[ASC_MAX_CDB_LEN];
 387        uchar sense[ASC_MIN_SENSE_LEN];
 388} ASC_SCSI_REQ_Q;
 389
 390typedef struct asc_scsi_bios_req_q {
 391        ASC_SCSIQ_1 r1;
 392        ASC_SCSIQ_2 r2;
 393        uchar *cdbptr;
 394        ASC_SG_HEAD *sg_head;
 395        uchar *sense_ptr;
 396        ASC_SCSIQ_3 r3;
 397        uchar cdb[ASC_MAX_CDB_LEN];
 398        uchar sense[ASC_MIN_SENSE_LEN];
 399} ASC_SCSI_BIOS_REQ_Q;
 400
 401typedef struct asc_risc_q {
 402        uchar fwd;
 403        uchar bwd;
 404        ASC_SCSIQ_1 i1;
 405        ASC_SCSIQ_2 i2;
 406        ASC_SCSIQ_3 i3;
 407        ASC_SCSIQ_4 i4;
 408} ASC_RISC_Q;
 409
 410typedef struct asc_sg_list_q {
 411        uchar seq_no;
 412        uchar q_no;
 413        uchar cntl;
 414        uchar sg_head_qp;
 415        uchar sg_list_cnt;
 416        uchar sg_cur_list_cnt;
 417} ASC_SG_LIST_Q;
 418
 419typedef struct asc_risc_sg_list_q {
 420        uchar fwd;
 421        uchar bwd;
 422        ASC_SG_LIST_Q sg;
 423        ASC_SG_LIST sg_list[7];
 424} ASC_RISC_SG_LIST_Q;
 425
 426#define ASCQ_ERR_Q_STATUS             0x0D
 427#define ASCQ_ERR_CUR_QNG              0x17
 428#define ASCQ_ERR_SG_Q_LINKS           0x18
 429#define ASCQ_ERR_ISR_RE_ENTRY         0x1A
 430#define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
 431#define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
 432
 433/*
 434 * Warning code values are set in ASC_DVC_VAR  'warn_code'.
 435 */
 436#define ASC_WARN_NO_ERROR             0x0000
 437#define ASC_WARN_IO_PORT_ROTATE       0x0001
 438#define ASC_WARN_EEPROM_CHKSUM        0x0002
 439#define ASC_WARN_IRQ_MODIFIED         0x0004
 440#define ASC_WARN_AUTO_CONFIG          0x0008
 441#define ASC_WARN_CMD_QNG_CONFLICT     0x0010
 442#define ASC_WARN_EEPROM_RECOVER       0x0020
 443#define ASC_WARN_CFG_MSW_RECOVER      0x0040
 444
 445/*
 446 * Error code values are set in {ASC/ADV}_DVC_VAR  'err_code'.
 447 */
 448#define ASC_IERR_NO_CARRIER             0x0001  /* No more carrier memory */
 449#define ASC_IERR_MCODE_CHKSUM           0x0002  /* micro code check sum error */
 450#define ASC_IERR_SET_PC_ADDR            0x0004
 451#define ASC_IERR_START_STOP_CHIP        0x0008  /* start/stop chip failed */
 452#define ASC_IERR_ILLEGAL_CONNECTION     0x0010  /* Illegal cable connection */
 453#define ASC_IERR_SINGLE_END_DEVICE      0x0020  /* SE device on DIFF bus */
 454#define ASC_IERR_REVERSED_CABLE         0x0040  /* Narrow flat cable reversed */
 455#define ASC_IERR_SET_SCSI_ID            0x0080  /* set SCSI ID failed */
 456#define ASC_IERR_HVD_DEVICE             0x0100  /* HVD device on LVD port */
 457#define ASC_IERR_BAD_SIGNATURE          0x0200  /* signature not found */
 458#define ASC_IERR_NO_BUS_TYPE            0x0400
 459#define ASC_IERR_BIST_PRE_TEST          0x0800  /* BIST pre-test error */
 460#define ASC_IERR_BIST_RAM_TEST          0x1000  /* BIST RAM test error */
 461#define ASC_IERR_BAD_CHIPTYPE           0x2000  /* Invalid chip_type setting */
 462
 463#define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
 464#define ASC_MIN_TAG_Q_PER_DVC   (0x04)
 465#define ASC_MIN_FREE_Q        (0x02)
 466#define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
 467#define ASC_MAX_TOTAL_QNG 240
 468#define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
 469#define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
 470#define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
 471#define ASC_MAX_INRAM_TAG_QNG   16
 472#define ASC_IOADR_GAP   0x10
 473#define ASC_SYN_MAX_OFFSET         0x0F
 474#define ASC_DEF_SDTR_OFFSET        0x0F
 475#define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
 476#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
 477
 478/* The narrow chip only supports a limited selection of transfer rates.
 479 * These are encoded in the range 0..7 or 0..15 depending whether the chip
 480 * is Ultra-capable or not.  These tables let us convert from one to the other.
 481 */
 482static const unsigned char asc_syn_xfer_period[8] = {
 483        25, 30, 35, 40, 50, 60, 70, 85
 484};
 485
 486static const unsigned char asc_syn_ultra_xfer_period[16] = {
 487        12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107
 488};
 489
 490typedef struct ext_msg {
 491        uchar msg_type;
 492        uchar msg_len;
 493        uchar msg_req;
 494        union {
 495                struct {
 496                        uchar sdtr_xfer_period;
 497                        uchar sdtr_req_ack_offset;
 498                } sdtr;
 499                struct {
 500                        uchar wdtr_width;
 501                } wdtr;
 502                struct {
 503                        uchar mdp_b3;
 504                        uchar mdp_b2;
 505                        uchar mdp_b1;
 506                        uchar mdp_b0;
 507                } mdp;
 508        } u_ext_msg;
 509        uchar res;
 510} EXT_MSG;
 511
 512#define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
 513#define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
 514#define wdtr_width      u_ext_msg.wdtr.wdtr_width
 515#define mdp_b3          u_ext_msg.mdp_b3
 516#define mdp_b2          u_ext_msg.mdp_b2
 517#define mdp_b1          u_ext_msg.mdp_b1
 518#define mdp_b0          u_ext_msg.mdp_b0
 519
 520typedef struct asc_dvc_cfg {
 521        ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
 522        ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
 523        ASC_SCSI_BIT_ID_TYPE disc_enable;
 524        ASC_SCSI_BIT_ID_TYPE sdtr_enable;
 525        uchar chip_scsi_id;
 526        uchar isa_dma_speed;
 527        uchar isa_dma_channel;
 528        uchar chip_version;
 529        ushort mcode_date;
 530        ushort mcode_version;
 531        uchar max_tag_qng[ASC_MAX_TID + 1];
 532        uchar sdtr_period_offset[ASC_MAX_TID + 1];
 533        uchar adapter_info[6];
 534} ASC_DVC_CFG;
 535
 536#define ASC_DEF_DVC_CNTL       0xFFFF
 537#define ASC_DEF_CHIP_SCSI_ID   7
 538#define ASC_DEF_ISA_DMA_SPEED  4
 539#define ASC_INIT_STATE_BEG_GET_CFG   0x0001
 540#define ASC_INIT_STATE_END_GET_CFG   0x0002
 541#define ASC_INIT_STATE_BEG_SET_CFG   0x0004
 542#define ASC_INIT_STATE_END_SET_CFG   0x0008
 543#define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
 544#define ASC_INIT_STATE_END_LOAD_MC   0x0020
 545#define ASC_INIT_STATE_BEG_INQUIRY   0x0040
 546#define ASC_INIT_STATE_END_INQUIRY   0x0080
 547#define ASC_INIT_RESET_SCSI_DONE     0x0100
 548#define ASC_INIT_STATE_WITHOUT_EEP   0x8000
 549#define ASC_BUG_FIX_IF_NOT_DWB       0x0001
 550#define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
 551#define ASC_MIN_TAGGED_CMD  7
 552#define ASC_MAX_SCSI_RESET_WAIT      30
 553#define ASC_OVERRUN_BSIZE               64
 554
 555struct asc_dvc_var;             /* Forward Declaration. */
 556
 557typedef struct asc_dvc_var {
 558        PortAddr iop_base;
 559        ushort err_code;
 560        ushort dvc_cntl;
 561        ushort bug_fix_cntl;
 562        ushort bus_type;
 563        ASC_SCSI_BIT_ID_TYPE init_sdtr;
 564        ASC_SCSI_BIT_ID_TYPE sdtr_done;
 565        ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
 566        ASC_SCSI_BIT_ID_TYPE unit_not_ready;
 567        ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
 568        ASC_SCSI_BIT_ID_TYPE start_motor;
 569        uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8);
 570        dma_addr_t overrun_dma;
 571        uchar scsi_reset_wait;
 572        uchar chip_no;
 573        char is_in_int;
 574        uchar max_total_qng;
 575        uchar cur_total_qng;
 576        uchar in_critical_cnt;
 577        uchar last_q_shortage;
 578        ushort init_state;
 579        uchar cur_dvc_qng[ASC_MAX_TID + 1];
 580        uchar max_dvc_qng[ASC_MAX_TID + 1];
 581        ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
 582        ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
 583        const uchar *sdtr_period_tbl;
 584        ASC_DVC_CFG *cfg;
 585        ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
 586        char redo_scam;
 587        ushort res2;
 588        uchar dos_int13_table[ASC_MAX_TID + 1];
 589        ASC_DCNT max_dma_count;
 590        ASC_SCSI_BIT_ID_TYPE no_scam;
 591        ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
 592        uchar min_sdtr_index;
 593        uchar max_sdtr_index;
 594        struct asc_board *drv_ptr;
 595        int ptr_map_count;
 596        void **ptr_map;
 597        ASC_DCNT uc_break;
 598} ASC_DVC_VAR;
 599
 600typedef struct asc_dvc_inq_info {
 601        uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
 602} ASC_DVC_INQ_INFO;
 603
 604typedef struct asc_cap_info {
 605        ASC_DCNT lba;
 606        ASC_DCNT blk_size;
 607} ASC_CAP_INFO;
 608
 609typedef struct asc_cap_info_array {
 610        ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
 611} ASC_CAP_INFO_ARRAY;
 612
 613#define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
 614#define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
 615#define ASC_CNTL_INITIATOR         (ushort)0x0001
 616#define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
 617#define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
 618#define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
 619#define ASC_CNTL_NO_SCAM           (ushort)0x0010
 620#define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
 621#define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
 622#define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
 623#define ASC_CNTL_RESET_SCSI        (ushort)0x0200
 624#define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
 625#define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
 626#define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
 627#define ASC_CNTL_BURST_MODE        (ushort)0x2000
 628#define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
 629#define ASC_EEP_DVC_CFG_BEG_VL    2
 630#define ASC_EEP_MAX_DVC_ADDR_VL   15
 631#define ASC_EEP_DVC_CFG_BEG      32
 632#define ASC_EEP_MAX_DVC_ADDR     45
 633#define ASC_EEP_MAX_RETRY        20
 634
 635/*
 636 * These macros keep the chip SCSI id and ISA DMA speed
 637 * bitfields in board order. C bitfields aren't portable
 638 * between big and little-endian platforms so they are
 639 * not used.
 640 */
 641
 642#define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
 643#define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
 644#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
 645   ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
 646#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
 647   ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
 648
 649typedef struct asceep_config {
 650        ushort cfg_lsw;
 651        ushort cfg_msw;
 652        uchar init_sdtr;
 653        uchar disc_enable;
 654        uchar use_cmd_qng;
 655        uchar start_motor;
 656        uchar max_total_qng;
 657        uchar max_tag_qng;
 658        uchar bios_scan;
 659        uchar power_up_wait;
 660        uchar no_scam;
 661        uchar id_speed;         /* low order 4 bits is chip scsi id */
 662        /* high order 4 bits is isa dma speed */
 663        uchar dos_int13_table[ASC_MAX_TID + 1];
 664        uchar adapter_info[6];
 665        ushort cntl;
 666        ushort chksum;
 667} ASCEEP_CONFIG;
 668
 669#define ASC_EEP_CMD_READ          0x80
 670#define ASC_EEP_CMD_WRITE         0x40
 671#define ASC_EEP_CMD_WRITE_ABLE    0x30
 672#define ASC_EEP_CMD_WRITE_DISABLE 0x00
 673#define ASCV_MSGOUT_BEG         0x0000
 674#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
 675#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
 676#define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
 677#define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
 678#define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
 679#define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
 680#define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
 681#define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
 682#define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
 683#define ASCV_BREAK_ADDR           (ushort)0x0028
 684#define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
 685#define ASCV_BREAK_CONTROL        (ushort)0x002C
 686#define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
 687
 688#define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
 689#define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
 690#define ASCV_MCODE_SIZE_W     (ushort)0x0034
 691#define ASCV_STOP_CODE_B      (ushort)0x0036
 692#define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
 693#define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
 694#define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
 695#define ASCV_HALTCODE_W       (ushort)0x0040
 696#define ASCV_CHKSUM_W         (ushort)0x0042
 697#define ASCV_MC_DATE_W        (ushort)0x0044
 698#define ASCV_MC_VER_W         (ushort)0x0046
 699#define ASCV_NEXTRDY_B        (ushort)0x0048
 700#define ASCV_DONENEXT_B       (ushort)0x0049
 701#define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
 702#define ASCV_SCSIBUSY_B       (ushort)0x004B
 703#define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
 704#define ASCV_CURCDB_B         (ushort)0x004D
 705#define ASCV_RCLUN_B          (ushort)0x004E
 706#define ASCV_BUSY_QHEAD_B     (ushort)0x004F
 707#define ASCV_DISC1_QHEAD_B    (ushort)0x0050
 708#define ASCV_DISC_ENABLE_B    (ushort)0x0052
 709#define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
 710#define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
 711#define ASCV_MCODE_CNTL_B     (ushort)0x0056
 712#define ASCV_NULL_TARGET_B    (ushort)0x0057
 713#define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
 714#define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
 715#define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
 716#define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
 717#define ASCV_HOST_FLAG_B      (ushort)0x005D
 718#define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
 719#define ASCV_VER_SERIAL_B     (ushort)0x0065
 720#define ASCV_HALTCODE_SAVED_W (ushort)0x0066
 721#define ASCV_WTM_FLAG_B       (ushort)0x0068
 722#define ASCV_RISC_FLAG_B      (ushort)0x006A
 723#define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
 724#define ASC_HOST_FLAG_IN_ISR        0x01
 725#define ASC_HOST_FLAG_ACK_INT       0x02
 726#define ASC_RISC_FLAG_GEN_INT      0x01
 727#define ASC_RISC_FLAG_REQ_SG_LIST  0x02
 728#define IOP_CTRL         (0x0F)
 729#define IOP_STATUS       (0x0E)
 730#define IOP_INT_ACK      IOP_STATUS
 731#define IOP_REG_IFC      (0x0D)
 732#define IOP_SYN_OFFSET    (0x0B)
 733#define IOP_EXTRA_CONTROL (0x0D)
 734#define IOP_REG_PC        (0x0C)
 735#define IOP_RAM_ADDR      (0x0A)
 736#define IOP_RAM_DATA      (0x08)
 737#define IOP_EEP_DATA      (0x06)
 738#define IOP_EEP_CMD       (0x07)
 739#define IOP_VERSION       (0x03)
 740#define IOP_CONFIG_HIGH   (0x04)
 741#define IOP_CONFIG_LOW    (0x02)
 742#define IOP_SIG_BYTE      (0x01)
 743#define IOP_SIG_WORD      (0x00)
 744#define IOP_REG_DC1      (0x0E)
 745#define IOP_REG_DC0      (0x0C)
 746#define IOP_REG_SB       (0x0B)
 747#define IOP_REG_DA1      (0x0A)
 748#define IOP_REG_DA0      (0x08)
 749#define IOP_REG_SC       (0x09)
 750#define IOP_DMA_SPEED    (0x07)
 751#define IOP_REG_FLAG     (0x07)
 752#define IOP_FIFO_H       (0x06)
 753#define IOP_FIFO_L       (0x04)
 754#define IOP_REG_ID       (0x05)
 755#define IOP_REG_QP       (0x03)
 756#define IOP_REG_IH       (0x02)
 757#define IOP_REG_IX       (0x01)
 758#define IOP_REG_AX       (0x00)
 759#define IFC_REG_LOCK      (0x00)
 760#define IFC_REG_UNLOCK    (0x09)
 761#define IFC_WR_EN_FILTER  (0x10)
 762#define IFC_RD_NO_EEPROM  (0x10)
 763#define IFC_SLEW_RATE     (0x20)
 764#define IFC_ACT_NEG       (0x40)
 765#define IFC_INP_FILTER    (0x80)
 766#define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
 767#define SC_SEL   (uchar)(0x80)
 768#define SC_BSY   (uchar)(0x40)
 769#define SC_ACK   (uchar)(0x20)
 770#define SC_REQ   (uchar)(0x10)
 771#define SC_ATN   (uchar)(0x08)
 772#define SC_IO    (uchar)(0x04)
 773#define SC_CD    (uchar)(0x02)
 774#define SC_MSG   (uchar)(0x01)
 775#define SEC_SCSI_CTL         (uchar)(0x80)
 776#define SEC_ACTIVE_NEGATE    (uchar)(0x40)
 777#define SEC_SLEW_RATE        (uchar)(0x20)
 778#define SEC_ENABLE_FILTER    (uchar)(0x10)
 779#define ASC_HALT_EXTMSG_IN     (ushort)0x8000
 780#define ASC_HALT_CHK_CONDITION (ushort)0x8100
 781#define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
 782#define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
 783#define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
 784#define ASC_HALT_SDTR_REJECTED (ushort)0x4000
 785#define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
 786#define ASC_MAX_QNO        0xF8
 787#define ASC_DATA_SEC_BEG   (ushort)0x0080
 788#define ASC_DATA_SEC_END   (ushort)0x0080
 789#define ASC_CODE_SEC_BEG   (ushort)0x0080
 790#define ASC_CODE_SEC_END   (ushort)0x0080
 791#define ASC_QADR_BEG       (0x4000)
 792#define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
 793#define ASC_QADR_END       (ushort)0x7FFF
 794#define ASC_QLAST_ADR      (ushort)0x7FC0
 795#define ASC_QBLK_SIZE      0x40
 796#define ASC_BIOS_DATA_QBEG 0xF8
 797#define ASC_MIN_ACTIVE_QNO 0x01
 798#define ASC_QLINK_END      0xFF
 799#define ASC_EEPROM_WORDS   0x10
 800#define ASC_MAX_MGS_LEN    0x10
 801#define ASC_BIOS_ADDR_DEF  0xDC00
 802#define ASC_BIOS_SIZE      0x3800
 803#define ASC_BIOS_RAM_OFF   0x3800
 804#define ASC_BIOS_RAM_SIZE  0x800
 805#define ASC_BIOS_MIN_ADDR  0xC000
 806#define ASC_BIOS_MAX_ADDR  0xEC00
 807#define ASC_BIOS_BANK_SIZE 0x0400
 808#define ASC_MCODE_START_ADDR  0x0080
 809#define ASC_CFG0_HOST_INT_ON    0x0020
 810#define ASC_CFG0_BIOS_ON        0x0040
 811#define ASC_CFG0_VERA_BURST_ON  0x0080
 812#define ASC_CFG0_SCSI_PARITY_ON 0x0800
 813#define ASC_CFG1_SCSI_TARGET_ON 0x0080
 814#define ASC_CFG1_LRAM_8BITS_ON  0x0800
 815#define ASC_CFG_MSW_CLR_MASK    0x3080
 816#define CSW_TEST1             (ASC_CS_TYPE)0x8000
 817#define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
 818#define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
 819#define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
 820#define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
 821#define CSW_TEST2             (ASC_CS_TYPE)0x0400
 822#define CSW_TEST3             (ASC_CS_TYPE)0x0200
 823#define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
 824#define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
 825#define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
 826#define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
 827#define CSW_HALTED            (ASC_CS_TYPE)0x0010
 828#define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
 829#define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
 830#define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
 831#define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
 832#define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
 833#define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
 834#define CIW_TEST1        (ASC_CS_TYPE)0x0200
 835#define CIW_TEST2        (ASC_CS_TYPE)0x0400
 836#define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
 837#define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
 838#define CC_CHIP_RESET   (uchar)0x80
 839#define CC_SCSI_RESET   (uchar)0x40
 840#define CC_HALT         (uchar)0x20
 841#define CC_SINGLE_STEP  (uchar)0x10
 842#define CC_DMA_ABLE     (uchar)0x08
 843#define CC_TEST         (uchar)0x04
 844#define CC_BANK_ONE     (uchar)0x02
 845#define CC_DIAG         (uchar)0x01
 846#define ASC_1000_ID0W      0x04C1
 847#define ASC_1000_ID0W_FIX  0x00C1
 848#define ASC_1000_ID1B      0x25
 849#define ASC_EISA_REV_IOP_MASK  (0x0C83)
 850#define ASC_EISA_CFG_IOP_MASK  (0x0C86)
 851#define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
 852#define INS_HALTINT        (ushort)0x6281
 853#define INS_HALT           (ushort)0x6280
 854#define INS_SINT           (ushort)0x6200
 855#define INS_RFLAG_WTM      (ushort)0x7380
 856#define ASC_MC_SAVE_CODE_WSIZE  0x500
 857#define ASC_MC_SAVE_DATA_WSIZE  0x40
 858
 859typedef struct asc_mc_saved {
 860        ushort data[ASC_MC_SAVE_DATA_WSIZE];
 861        ushort code[ASC_MC_SAVE_CODE_WSIZE];
 862} ASC_MC_SAVED;
 863
 864#define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
 865#define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
 866#define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
 867#define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
 868#define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
 869#define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
 870#define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
 871#define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
 872#define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
 873#define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
 874#define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data))
 875#define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id))
 876#define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data)
 877#define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id))
 878#define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
 879#define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
 880#define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
 881#define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
 882#define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
 883#define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
 884#define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
 885#define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
 886#define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
 887#define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
 888#define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
 889#define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
 890#define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
 891#define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
 892#define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
 893#define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
 894#define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
 895#define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
 896#define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
 897#define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
 898#define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
 899#define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
 900#define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
 901#define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
 902#define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
 903#define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
 904#define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
 905#define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
 906#define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
 907#define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
 908#define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
 909#define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
 910#define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
 911#define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
 912#define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
 913#define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
 914#define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
 915#define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
 916#define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
 917#define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
 918#define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
 919#define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
 920#define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
 921#define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
 922#define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
 923#define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
 924#define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
 925#define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
 926#define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
 927#define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
 928#define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
 929#define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
 930#define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
 931
 932/*
 933 * Portable Data Types
 934 *
 935 * Any instance where a 32-bit long or pointer type is assumed
 936 * for precision or HW defined structures, the following define
 937 * types must be used. In Linux the char, short, and int types
 938 * are all consistent at 8, 16, and 32 bits respectively. Pointers
 939 * and long types are 64 bits on Alpha and UltraSPARC.
 940 */
 941#define ADV_PADDR __u32         /* Physical address data type. */
 942#define ADV_VADDR __u32         /* Virtual address data type. */
 943#define ADV_DCNT  __u32         /* Unsigned Data count type. */
 944#define ADV_SDCNT __s32         /* Signed Data count type. */
 945
 946/*
 947 * These macros are used to convert a virtual address to a
 948 * 32-bit value. This currently can be used on Linux Alpha
 949 * which uses 64-bit virtual address but a 32-bit bus address.
 950 * This is likely to break in the future, but doing this now
 951 * will give us time to change the HW and FW to handle 64-bit
 952 * addresses.
 953 */
 954#define ADV_VADDR_TO_U32   virt_to_bus
 955#define ADV_U32_TO_VADDR   bus_to_virt
 956
 957#define AdvPortAddr  void __iomem *     /* Virtual memory address size */
 958
 959/*
 960 * Define Adv Library required memory access macros.
 961 */
 962#define ADV_MEM_READB(addr) readb(addr)
 963#define ADV_MEM_READW(addr) readw(addr)
 964#define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
 965#define ADV_MEM_WRITEW(addr, word) writew(word, addr)
 966#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
 967
 968#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
 969
 970/*
 971 * Define total number of simultaneous maximum element scatter-gather
 972 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
 973 * maximum number of outstanding commands per wide host adapter. Each
 974 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
 975 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
 976 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
 977 * structures or 255 scatter-gather elements.
 978 */
 979#define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
 980
 981/*
 982 * Define maximum number of scatter-gather elements per request.
 983 */
 984#define ADV_MAX_SG_LIST         255
 985#define NO_OF_SG_PER_BLOCK              15
 986
 987#define ADV_EEP_DVC_CFG_BEGIN           (0x00)
 988#define ADV_EEP_DVC_CFG_END             (0x15)
 989#define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
 990#define ADV_EEP_MAX_WORD_ADDR           (0x1E)
 991
 992#define ADV_EEP_DELAY_MS                100
 993
 994#define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
 995#define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
 996/*
 997 * For the ASC3550 Bit 13 is Termination Polarity control bit.
 998 * For later ICs Bit 13 controls whether the CIS (Card Information
 999 * Service Section) is loaded from EEPROM.
1000 */
1001#define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
1002#define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
1003/*
1004 * ASC38C1600 Bit 11
1005 *
1006 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
1007 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
1008 * Function 0 will specify INT B.
1009 *
1010 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
1011 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
1012 * Function 1 will specify INT A.
1013 */
1014#define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
1015
1016typedef struct adveep_3550_config {
1017        /* Word Offset, Description */
1018
1019        ushort cfg_lsw;         /* 00 power up initialization */
1020        /*  bit 13 set - Term Polarity Control */
1021        /*  bit 14 set - BIOS Enable */
1022        /*  bit 15 set - Big Endian Mode */
1023        ushort cfg_msw;         /* 01 unused      */
1024        ushort disc_enable;     /* 02 disconnect enable */
1025        ushort wdtr_able;       /* 03 Wide DTR able */
1026        ushort sdtr_able;       /* 04 Synchronous DTR able */
1027        ushort start_motor;     /* 05 send start up motor */
1028        ushort tagqng_able;     /* 06 tag queuing able */
1029        ushort bios_scan;       /* 07 BIOS device control */
1030        ushort scam_tolerant;   /* 08 no scam */
1031
1032        uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1033        uchar bios_boot_delay;  /*    power up wait */
1034
1035        uchar scsi_reset_delay; /* 10 reset delay */
1036        uchar bios_id_lun;      /*    first boot device scsi id & lun */
1037        /*    high nibble is lun */
1038        /*    low nibble is scsi id */
1039
1040        uchar termination;      /* 11 0 - automatic */
1041        /*    1 - low off / high off */
1042        /*    2 - low off / high on */
1043        /*    3 - low on  / high on */
1044        /*    There is no low on  / high off */
1045
1046        uchar reserved1;        /*    reserved byte (not used) */
1047
1048        ushort bios_ctrl;       /* 12 BIOS control bits */
1049        /*  bit 0  BIOS don't act as initiator. */
1050        /*  bit 1  BIOS > 1 GB support */
1051        /*  bit 2  BIOS > 2 Disk Support */
1052        /*  bit 3  BIOS don't support removables */
1053        /*  bit 4  BIOS support bootable CD */
1054        /*  bit 5  BIOS scan enabled */
1055        /*  bit 6  BIOS support multiple LUNs */
1056        /*  bit 7  BIOS display of message */
1057        /*  bit 8  SCAM disabled */
1058        /*  bit 9  Reset SCSI bus during init. */
1059        /*  bit 10 */
1060        /*  bit 11 No verbose initialization. */
1061        /*  bit 12 SCSI parity enabled */
1062        /*  bit 13 */
1063        /*  bit 14 */
1064        /*  bit 15 */
1065        ushort ultra_able;      /* 13 ULTRA speed able */
1066        ushort reserved2;       /* 14 reserved */
1067        uchar max_host_qng;     /* 15 maximum host queuing */
1068        uchar max_dvc_qng;      /*    maximum per device queuing */
1069        ushort dvc_cntl;        /* 16 control bit for driver */
1070        ushort bug_fix;         /* 17 control bit for bug fix */
1071        ushort serial_number_word1;     /* 18 Board serial number word 1 */
1072        ushort serial_number_word2;     /* 19 Board serial number word 2 */
1073        ushort serial_number_word3;     /* 20 Board serial number word 3 */
1074        ushort check_sum;       /* 21 EEP check sum */
1075        uchar oem_name[16];     /* 22 OEM name */
1076        ushort dvc_err_code;    /* 30 last device driver error code */
1077        ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1078        ushort adv_err_addr;    /* 32 last uc error address */
1079        ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1080        ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1081        ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1082        ushort num_of_err;      /* 36 number of error */
1083} ADVEEP_3550_CONFIG;
1084
1085typedef struct adveep_38C0800_config {
1086        /* Word Offset, Description */
1087
1088        ushort cfg_lsw;         /* 00 power up initialization */
1089        /*  bit 13 set - Load CIS */
1090        /*  bit 14 set - BIOS Enable */
1091        /*  bit 15 set - Big Endian Mode */
1092        ushort cfg_msw;         /* 01 unused      */
1093        ushort disc_enable;     /* 02 disconnect enable */
1094        ushort wdtr_able;       /* 03 Wide DTR able */
1095        ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
1096        ushort start_motor;     /* 05 send start up motor */
1097        ushort tagqng_able;     /* 06 tag queuing able */
1098        ushort bios_scan;       /* 07 BIOS device control */
1099        ushort scam_tolerant;   /* 08 no scam */
1100
1101        uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1102        uchar bios_boot_delay;  /*    power up wait */
1103
1104        uchar scsi_reset_delay; /* 10 reset delay */
1105        uchar bios_id_lun;      /*    first boot device scsi id & lun */
1106        /*    high nibble is lun */
1107        /*    low nibble is scsi id */
1108
1109        uchar termination_se;   /* 11 0 - automatic */
1110        /*    1 - low off / high off */
1111        /*    2 - low off / high on */
1112        /*    3 - low on  / high on */
1113        /*    There is no low on  / high off */
1114
1115        uchar termination_lvd;  /* 11 0 - automatic */
1116        /*    1 - low off / high off */
1117        /*    2 - low off / high on */
1118        /*    3 - low on  / high on */
1119        /*    There is no low on  / high off */
1120
1121        ushort bios_ctrl;       /* 12 BIOS control bits */
1122        /*  bit 0  BIOS don't act as initiator. */
1123        /*  bit 1  BIOS > 1 GB support */
1124        /*  bit 2  BIOS > 2 Disk Support */
1125        /*  bit 3  BIOS don't support removables */
1126        /*  bit 4  BIOS support bootable CD */
1127        /*  bit 5  BIOS scan enabled */
1128        /*  bit 6  BIOS support multiple LUNs */
1129        /*  bit 7  BIOS display of message */
1130        /*  bit 8  SCAM disabled */
1131        /*  bit 9  Reset SCSI bus during init. */
1132        /*  bit 10 */
1133        /*  bit 11 No verbose initialization. */
1134        /*  bit 12 SCSI parity enabled */
1135        /*  bit 13 */
1136        /*  bit 14 */
1137        /*  bit 15 */
1138        ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
1139        ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
1140        uchar max_host_qng;     /* 15 maximum host queueing */
1141        uchar max_dvc_qng;      /*    maximum per device queuing */
1142        ushort dvc_cntl;        /* 16 control bit for driver */
1143        ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
1144        ushort serial_number_word1;     /* 18 Board serial number word 1 */
1145        ushort serial_number_word2;     /* 19 Board serial number word 2 */
1146        ushort serial_number_word3;     /* 20 Board serial number word 3 */
1147        ushort check_sum;       /* 21 EEP check sum */
1148        uchar oem_name[16];     /* 22 OEM name */
1149        ushort dvc_err_code;    /* 30 last device driver error code */
1150        ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1151        ushort adv_err_addr;    /* 32 last uc error address */
1152        ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1153        ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1154        ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1155        ushort reserved36;      /* 36 reserved */
1156        ushort reserved37;      /* 37 reserved */
1157        ushort reserved38;      /* 38 reserved */
1158        ushort reserved39;      /* 39 reserved */
1159        ushort reserved40;      /* 40 reserved */
1160        ushort reserved41;      /* 41 reserved */
1161        ushort reserved42;      /* 42 reserved */
1162        ushort reserved43;      /* 43 reserved */
1163        ushort reserved44;      /* 44 reserved */
1164        ushort reserved45;      /* 45 reserved */
1165        ushort reserved46;      /* 46 reserved */
1166        ushort reserved47;      /* 47 reserved */
1167        ushort reserved48;      /* 48 reserved */
1168        ushort reserved49;      /* 49 reserved */
1169        ushort reserved50;      /* 50 reserved */
1170        ushort reserved51;      /* 51 reserved */
1171        ushort reserved52;      /* 52 reserved */
1172        ushort reserved53;      /* 53 reserved */
1173        ushort reserved54;      /* 54 reserved */
1174        ushort reserved55;      /* 55 reserved */
1175        ushort cisptr_lsw;      /* 56 CIS PTR LSW */
1176        ushort cisprt_msw;      /* 57 CIS PTR MSW */
1177        ushort subsysvid;       /* 58 SubSystem Vendor ID */
1178        ushort subsysid;        /* 59 SubSystem ID */
1179        ushort reserved60;      /* 60 reserved */
1180        ushort reserved61;      /* 61 reserved */
1181        ushort reserved62;      /* 62 reserved */
1182        ushort reserved63;      /* 63 reserved */
1183} ADVEEP_38C0800_CONFIG;
1184
1185typedef struct adveep_38C1600_config {
1186        /* Word Offset, Description */
1187
1188        ushort cfg_lsw;         /* 00 power up initialization */
1189        /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
1190        /*       clear - Func. 0 INTA, Func. 1 INTB */
1191        /*  bit 13 set - Load CIS */
1192        /*  bit 14 set - BIOS Enable */
1193        /*  bit 15 set - Big Endian Mode */
1194        ushort cfg_msw;         /* 01 unused */
1195        ushort disc_enable;     /* 02 disconnect enable */
1196        ushort wdtr_able;       /* 03 Wide DTR able */
1197        ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
1198        ushort start_motor;     /* 05 send start up motor */
1199        ushort tagqng_able;     /* 06 tag queuing able */
1200        ushort bios_scan;       /* 07 BIOS device control */
1201        ushort scam_tolerant;   /* 08 no scam */
1202
1203        uchar adapter_scsi_id;  /* 09 Host Adapter ID */
1204        uchar bios_boot_delay;  /*    power up wait */
1205
1206        uchar scsi_reset_delay; /* 10 reset delay */
1207        uchar bios_id_lun;      /*    first boot device scsi id & lun */
1208        /*    high nibble is lun */
1209        /*    low nibble is scsi id */
1210
1211        uchar termination_se;   /* 11 0 - automatic */
1212        /*    1 - low off / high off */
1213        /*    2 - low off / high on */
1214        /*    3 - low on  / high on */
1215        /*    There is no low on  / high off */
1216
1217        uchar termination_lvd;  /* 11 0 - automatic */
1218        /*    1 - low off / high off */
1219        /*    2 - low off / high on */
1220        /*    3 - low on  / high on */
1221        /*    There is no low on  / high off */
1222
1223        ushort bios_ctrl;       /* 12 BIOS control bits */
1224        /*  bit 0  BIOS don't act as initiator. */
1225        /*  bit 1  BIOS > 1 GB support */
1226        /*  bit 2  BIOS > 2 Disk Support */
1227        /*  bit 3  BIOS don't support removables */
1228        /*  bit 4  BIOS support bootable CD */
1229        /*  bit 5  BIOS scan enabled */
1230        /*  bit 6  BIOS support multiple LUNs */
1231        /*  bit 7  BIOS display of message */
1232        /*  bit 8  SCAM disabled */
1233        /*  bit 9  Reset SCSI bus during init. */
1234        /*  bit 10 Basic Integrity Checking disabled */
1235        /*  bit 11 No verbose initialization. */
1236        /*  bit 12 SCSI parity enabled */
1237        /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
1238        /*  bit 14 */
1239        /*  bit 15 */
1240        ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
1241        ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
1242        uchar max_host_qng;     /* 15 maximum host queueing */
1243        uchar max_dvc_qng;      /*    maximum per device queuing */
1244        ushort dvc_cntl;        /* 16 control bit for driver */
1245        ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
1246        ushort serial_number_word1;     /* 18 Board serial number word 1 */
1247        ushort serial_number_word2;     /* 19 Board serial number word 2 */
1248        ushort serial_number_word3;     /* 20 Board serial number word 3 */
1249        ushort check_sum;       /* 21 EEP check sum */
1250        uchar oem_name[16];     /* 22 OEM name */
1251        ushort dvc_err_code;    /* 30 last device driver error code */
1252        ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
1253        ushort adv_err_addr;    /* 32 last uc error address */
1254        ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
1255        ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
1256        ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
1257        ushort reserved36;      /* 36 reserved */
1258        ushort reserved37;      /* 37 reserved */
1259        ushort reserved38;      /* 38 reserved */
1260        ushort reserved39;      /* 39 reserved */
1261        ushort reserved40;      /* 40 reserved */
1262        ushort reserved41;      /* 41 reserved */
1263        ushort reserved42;      /* 42 reserved */
1264        ushort reserved43;      /* 43 reserved */
1265        ushort reserved44;      /* 44 reserved */
1266        ushort reserved45;      /* 45 reserved */
1267        ushort reserved46;      /* 46 reserved */
1268        ushort reserved47;      /* 47 reserved */
1269        ushort reserved48;      /* 48 reserved */
1270        ushort reserved49;      /* 49 reserved */
1271        ushort reserved50;      /* 50 reserved */
1272        ushort reserved51;      /* 51 reserved */
1273        ushort reserved52;      /* 52 reserved */
1274        ushort reserved53;      /* 53 reserved */
1275        ushort reserved54;      /* 54 reserved */
1276        ushort reserved55;      /* 55 reserved */
1277        ushort cisptr_lsw;      /* 56 CIS PTR LSW */
1278        ushort cisprt_msw;      /* 57 CIS PTR MSW */
1279        ushort subsysvid;       /* 58 SubSystem Vendor ID */
1280        ushort subsysid;        /* 59 SubSystem ID */
1281        ushort reserved60;      /* 60 reserved */
1282        ushort reserved61;      /* 61 reserved */
1283        ushort reserved62;      /* 62 reserved */
1284        ushort reserved63;      /* 63 reserved */
1285} ADVEEP_38C1600_CONFIG;
1286
1287/*
1288 * EEPROM Commands
1289 */
1290#define ASC_EEP_CMD_DONE             0x0200
1291
1292/* bios_ctrl */
1293#define BIOS_CTRL_BIOS               0x0001
1294#define BIOS_CTRL_EXTENDED_XLAT      0x0002
1295#define BIOS_CTRL_GT_2_DISK          0x0004
1296#define BIOS_CTRL_BIOS_REMOVABLE     0x0008
1297#define BIOS_CTRL_BOOTABLE_CD        0x0010
1298#define BIOS_CTRL_MULTIPLE_LUN       0x0040
1299#define BIOS_CTRL_DISPLAY_MSG        0x0080
1300#define BIOS_CTRL_NO_SCAM            0x0100
1301#define BIOS_CTRL_RESET_SCSI_BUS     0x0200
1302#define BIOS_CTRL_INIT_VERBOSE       0x0800
1303#define BIOS_CTRL_SCSI_PARITY        0x1000
1304#define BIOS_CTRL_AIPP_DIS           0x2000
1305
1306#define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
1307
1308#define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
1309
1310/*
1311 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
1312 * a special 16K Adv Library and Microcode version. After the issue is
1313 * resolved, should restore 32K support.
1314 *
1315 * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
1316 */
1317#define ADV_38C1600_MEMSIZE  0x4000     /* 16 KB Internal Memory */
1318
1319/*
1320 * Byte I/O register address from base of 'iop_base'.
1321 */
1322#define IOPB_INTR_STATUS_REG    0x00
1323#define IOPB_CHIP_ID_1          0x01
1324#define IOPB_INTR_ENABLES       0x02
1325#define IOPB_CHIP_TYPE_REV      0x03
1326#define IOPB_RES_ADDR_4         0x04
1327#define IOPB_RES_ADDR_5         0x05
1328#define IOPB_RAM_DATA           0x06
1329#define IOPB_RES_ADDR_7         0x07
1330#define IOPB_FLAG_REG           0x08
1331#define IOPB_RES_ADDR_9         0x09
1332#define IOPB_RISC_CSR           0x0A
1333#define IOPB_RES_ADDR_B         0x0B
1334#define IOPB_RES_ADDR_C         0x0C
1335#define IOPB_RES_ADDR_D         0x0D
1336#define IOPB_SOFT_OVER_WR       0x0E
1337#define IOPB_RES_ADDR_F         0x0F
1338#define IOPB_MEM_CFG            0x10
1339#define IOPB_RES_ADDR_11        0x11
1340#define IOPB_GPIO_DATA          0x12
1341#define IOPB_RES_ADDR_13        0x13
1342#define IOPB_FLASH_PAGE         0x14
1343#define IOPB_RES_ADDR_15        0x15
1344#define IOPB_GPIO_CNTL          0x16
1345#define IOPB_RES_ADDR_17        0x17
1346#define IOPB_FLASH_DATA         0x18
1347#define IOPB_RES_ADDR_19        0x19
1348#define IOPB_RES_ADDR_1A        0x1A
1349#define IOPB_RES_ADDR_1B        0x1B
1350#define IOPB_RES_ADDR_1C        0x1C
1351#define IOPB_RES_ADDR_1D        0x1D
1352#define IOPB_RES_ADDR_1E        0x1E
1353#define IOPB_RES_ADDR_1F        0x1F
1354#define IOPB_DMA_CFG0           0x20
1355#define IOPB_DMA_CFG1           0x21
1356#define IOPB_TICKLE             0x22
1357#define IOPB_DMA_REG_WR         0x23
1358#define IOPB_SDMA_STATUS        0x24
1359#define IOPB_SCSI_BYTE_CNT      0x25
1360#define IOPB_HOST_BYTE_CNT      0x26
1361#define IOPB_BYTE_LEFT_TO_XFER  0x27
1362#define IOPB_BYTE_TO_XFER_0     0x28
1363#define IOPB_BYTE_TO_XFER_1     0x29
1364#define IOPB_BYTE_TO_XFER_2     0x2A
1365#define IOPB_BYTE_TO_XFER_3     0x2B
1366#define IOPB_ACC_GRP            0x2C
1367#define IOPB_RES_ADDR_2D        0x2D
1368#define IOPB_DEV_ID             0x2E
1369#define IOPB_RES_ADDR_2F        0x2F
1370#define IOPB_SCSI_DATA          0x30
1371#define IOPB_RES_ADDR_31        0x31
1372#define IOPB_RES_ADDR_32        0x32
1373#define IOPB_SCSI_DATA_HSHK     0x33
1374#define IOPB_SCSI_CTRL          0x34
1375#define IOPB_RES_ADDR_35        0x35
1376#define IOPB_RES_ADDR_36        0x36
1377#define IOPB_RES_ADDR_37        0x37
1378#define IOPB_RAM_BIST           0x38
1379#define IOPB_PLL_TEST           0x39
1380#define IOPB_PCI_INT_CFG        0x3A
1381#define IOPB_RES_ADDR_3B        0x3B
1382#define IOPB_RFIFO_CNT          0x3C
1383#define IOPB_RES_ADDR_3D        0x3D
1384#define IOPB_RES_ADDR_3E        0x3E
1385#define IOPB_RES_ADDR_3F        0x3F
1386
1387/*
1388 * Word I/O register address from base of 'iop_base'.
1389 */
1390#define IOPW_CHIP_ID_0          0x00    /* CID0  */
1391#define IOPW_CTRL_REG           0x02    /* CC    */
1392#define IOPW_RAM_ADDR           0x04    /* LA    */
1393#define IOPW_RAM_DATA           0x06    /* LD    */
1394#define IOPW_RES_ADDR_08        0x08
1395#define IOPW_RISC_CSR           0x0A    /* CSR   */
1396#define IOPW_SCSI_CFG0          0x0C    /* CFG0  */
1397#define IOPW_SCSI_CFG1          0x0E    /* CFG1  */
1398#define IOPW_RES_ADDR_10        0x10
1399#define IOPW_SEL_MASK           0x12    /* SM    */
1400#define IOPW_RES_ADDR_14        0x14
1401#define IOPW_FLASH_ADDR         0x16    /* FA    */
1402#define IOPW_RES_ADDR_18        0x18
1403#define IOPW_EE_CMD             0x1A    /* EC    */
1404#define IOPW_EE_DATA            0x1C    /* ED    */
1405#define IOPW_SFIFO_CNT          0x1E    /* SFC   */
1406#define IOPW_RES_ADDR_20        0x20
1407#define IOPW_Q_BASE             0x22    /* QB    */
1408#define IOPW_QP                 0x24    /* QP    */
1409#define IOPW_IX                 0x26    /* IX    */
1410#define IOPW_SP                 0x28    /* SP    */
1411#define IOPW_PC                 0x2A    /* PC    */
1412#define IOPW_RES_ADDR_2C        0x2C
1413#define IOPW_RES_ADDR_2E        0x2E
1414#define IOPW_SCSI_DATA          0x30    /* SD    */
1415#define IOPW_SCSI_DATA_HSHK     0x32    /* SDH   */
1416#define IOPW_SCSI_CTRL          0x34    /* SC    */
1417#define IOPW_HSHK_CFG           0x36    /* HCFG  */
1418#define IOPW_SXFR_STATUS        0x36    /* SXS   */
1419#define IOPW_SXFR_CNTL          0x38    /* SXL   */
1420#define IOPW_SXFR_CNTH          0x3A    /* SXH   */
1421#define IOPW_RES_ADDR_3C        0x3C
1422#define IOPW_RFIFO_DATA         0x3E    /* RFD   */
1423
1424/*
1425 * Doubleword I/O register address from base of 'iop_base'.
1426 */
1427#define IOPDW_RES_ADDR_0         0x00
1428#define IOPDW_RAM_DATA           0x04
1429#define IOPDW_RES_ADDR_8         0x08
1430#define IOPDW_RES_ADDR_C         0x0C
1431#define IOPDW_RES_ADDR_10        0x10
1432#define IOPDW_COMMA              0x14
1433#define IOPDW_COMMB              0x18
1434#define IOPDW_RES_ADDR_1C        0x1C
1435#define IOPDW_SDMA_ADDR0         0x20
1436#define IOPDW_SDMA_ADDR1         0x24
1437#define IOPDW_SDMA_COUNT         0x28
1438#define IOPDW_SDMA_ERROR         0x2C
1439#define IOPDW_RDMA_ADDR0         0x30
1440#define IOPDW_RDMA_ADDR1         0x34
1441#define IOPDW_RDMA_COUNT         0x38
1442#define IOPDW_RDMA_ERROR         0x3C
1443
1444#define ADV_CHIP_ID_BYTE         0x25
1445#define ADV_CHIP_ID_WORD         0x04C1
1446
1447#define ADV_INTR_ENABLE_HOST_INTR                   0x01
1448#define ADV_INTR_ENABLE_SEL_INTR                    0x02
1449#define ADV_INTR_ENABLE_DPR_INTR                    0x04
1450#define ADV_INTR_ENABLE_RTA_INTR                    0x08
1451#define ADV_INTR_ENABLE_RMA_INTR                    0x10
1452#define ADV_INTR_ENABLE_RST_INTR                    0x20
1453#define ADV_INTR_ENABLE_DPE_INTR                    0x40
1454#define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
1455
1456#define ADV_INTR_STATUS_INTRA            0x01
1457#define ADV_INTR_STATUS_INTRB            0x02
1458#define ADV_INTR_STATUS_INTRC            0x04
1459
1460#define ADV_RISC_CSR_STOP           (0x0000)
1461#define ADV_RISC_TEST_COND          (0x2000)
1462#define ADV_RISC_CSR_RUN            (0x4000)
1463#define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
1464
1465#define ADV_CTRL_REG_HOST_INTR      0x0100
1466#define ADV_CTRL_REG_SEL_INTR       0x0200
1467#define ADV_CTRL_REG_DPR_INTR       0x0400
1468#define ADV_CTRL_REG_RTA_INTR       0x0800
1469#define ADV_CTRL_REG_RMA_INTR       0x1000
1470#define ADV_CTRL_REG_RES_BIT14      0x2000
1471#define ADV_CTRL_REG_DPE_INTR       0x4000
1472#define ADV_CTRL_REG_POWER_DONE     0x8000
1473#define ADV_CTRL_REG_ANY_INTR       0xFF00
1474
1475#define ADV_CTRL_REG_CMD_RESET             0x00C6
1476#define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
1477#define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
1478#define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
1479#define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
1480
1481#define ADV_TICKLE_NOP                      0x00
1482#define ADV_TICKLE_A                        0x01
1483#define ADV_TICKLE_B                        0x02
1484#define ADV_TICKLE_C                        0x03
1485
1486#define AdvIsIntPending(port) \
1487    (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
1488
1489/*
1490 * SCSI_CFG0 Register bit definitions
1491 */
1492#define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
1493#define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
1494#define EVEN_PARITY     0x1000  /* Select Even Parity */
1495#define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
1496#define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
1497#define PRIM_MODE       0x0100  /* Primitive SCSI mode */
1498#define SCAM_EN         0x0080  /* Enable SCAM selection */
1499#define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
1500#define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
1501#define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
1502#define OUR_ID          0x000F  /* SCSI ID */
1503
1504/*
1505 * SCSI_CFG1 Register bit definitions
1506 */
1507#define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
1508#define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
1509#define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
1510#define FILTER_SEL      0x0C00  /* Filter Period Selection */
1511#define  FLTR_DISABLE    0x0000 /* Input Filtering Disabled */
1512#define  FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
1513#define  FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
1514#define ACTIVE_DBL      0x0200  /* Disable Active Negation */
1515#define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
1516#define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
1517#define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
1518#define TERM_CTL        0x0030  /* External SCSI Termination Bits */
1519#define  TERM_CTL_H      0x0020 /* Enable External SCSI Upper Termination */
1520#define  TERM_CTL_L      0x0010 /* Enable External SCSI Lower Termination */
1521#define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
1522
1523/*
1524 * Addendum for ASC-38C0800 Chip
1525 *
1526 * The ASC-38C1600 Chip uses the same definitions except that the
1527 * bus mode override bits [12:10] have been moved to byte register
1528 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
1529 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
1530 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
1531 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
1532 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
1533 */
1534#define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
1535#define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
1536#define  HVD             0x1000 /* HVD Device Detect */
1537#define  LVD             0x0800 /* LVD Device Detect */
1538#define  SE              0x0400 /* SE Device Detect */
1539#define TERM_LVD        0x00C0  /* LVD Termination Bits */
1540#define  TERM_LVD_HI     0x0080 /* Enable LVD Upper Termination */
1541#define  TERM_LVD_LO     0x0040 /* Enable LVD Lower Termination */
1542#define TERM_SE         0x0030  /* SE Termination Bits */
1543#define  TERM_SE_HI      0x0020 /* Enable SE Upper Termination */
1544#define  TERM_SE_LO      0x0010 /* Enable SE Lower Termination */
1545#define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
1546#define  C_DET3          0x0008 /* Cable Detect for LVD External Wide */
1547#define  C_DET2          0x0004 /* Cable Detect for LVD Internal Wide */
1548#define C_DET_SE        0x0003  /* SE Cable Detect Bits */
1549#define  C_DET1          0x0002 /* Cable Detect for SE Internal Wide */
1550#define  C_DET0          0x0001 /* Cable Detect for SE Internal Narrow */
1551
1552#define CABLE_ILLEGAL_A 0x7
1553    /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
1554
1555#define CABLE_ILLEGAL_B 0xB
1556    /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
1557
1558/*
1559 * MEM_CFG Register bit definitions
1560 */
1561#define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
1562#define FAST_EE_CLK     0x20    /* Diagnostic Bit */
1563#define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
1564#define  RAM_SZ_2KB      0x00   /* 2 KB */
1565#define  RAM_SZ_4KB      0x04   /* 4 KB */
1566#define  RAM_SZ_8KB      0x08   /* 8 KB */
1567#define  RAM_SZ_16KB     0x0C   /* 16 KB */
1568#define  RAM_SZ_32KB     0x10   /* 32 KB */
1569#define  RAM_SZ_64KB     0x14   /* 64 KB */
1570
1571/*
1572 * DMA_CFG0 Register bit definitions
1573 *
1574 * This register is only accessible to the host.
1575 */
1576#define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
1577#define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
1578#define  FIFO_THRESH_16B  0x00  /* 16 bytes */
1579#define  FIFO_THRESH_32B  0x20  /* 32 bytes */
1580#define  FIFO_THRESH_48B  0x30  /* 48 bytes */
1581#define  FIFO_THRESH_64B  0x40  /* 64 bytes */
1582#define  FIFO_THRESH_80B  0x50  /* 80 bytes (default) */
1583#define  FIFO_THRESH_96B  0x60  /* 96 bytes */
1584#define  FIFO_THRESH_112B 0x70  /* 112 bytes */
1585#define START_CTL       0x0C    /* DMA start conditions */
1586#define  START_CTL_TH    0x00   /* Wait threshold level (default) */
1587#define  START_CTL_ID    0x04   /* Wait SDMA/SBUS idle */
1588#define  START_CTL_THID  0x08   /* Wait threshold and SDMA/SBUS idle */
1589#define  START_CTL_EMFU  0x0C   /* Wait SDMA FIFO empty/full */
1590#define READ_CMD        0x03    /* Memory Read Method */
1591#define  READ_CMD_MR     0x00   /* Memory Read */
1592#define  READ_CMD_MRL    0x02   /* Memory Read Long */
1593#define  READ_CMD_MRM    0x03   /* Memory Read Multiple (default) */
1594
1595/*
1596 * ASC-38C0800 RAM BIST Register bit definitions
1597 */
1598#define RAM_TEST_MODE         0x80
1599#define PRE_TEST_MODE         0x40
1600#define NORMAL_MODE           0x00
1601#define RAM_TEST_DONE         0x10
1602#define RAM_TEST_STATUS       0x0F
1603#define  RAM_TEST_HOST_ERROR   0x08
1604#define  RAM_TEST_INTRAM_ERROR 0x04
1605#define  RAM_TEST_RISC_ERROR   0x02
1606#define  RAM_TEST_SCSI_ERROR   0x01
1607#define  RAM_TEST_SUCCESS      0x00
1608#define PRE_TEST_VALUE        0x05
1609#define NORMAL_VALUE          0x00
1610
1611/*
1612 * ASC38C1600 Definitions
1613 *
1614 * IOPB_PCI_INT_CFG Bit Field Definitions
1615 */
1616
1617#define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
1618
1619/*
1620 * Bit 1 can be set to change the interrupt for the Function to operate in
1621 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
1622 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
1623 * mode, otherwise the operating mode is undefined.
1624 */
1625#define TOTEMPOLE       0x02
1626
1627/*
1628 * Bit 0 can be used to change the Int Pin for the Function. The value is
1629 * 0 by default for both Functions with Function 0 using INT A and Function
1630 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
1631 * INT A is used.
1632 *
1633 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
1634 * value specified in the PCI Configuration Space.
1635 */
1636#define INTAB           0x01
1637
1638/*
1639 * Adv Library Status Definitions
1640 */
1641#define ADV_TRUE        1
1642#define ADV_FALSE       0
1643#define ADV_SUCCESS     1
1644#define ADV_BUSY        0
1645#define ADV_ERROR       (-1)
1646
1647/*
1648 * ADV_DVC_VAR 'warn_code' values
1649 */
1650#define ASC_WARN_BUSRESET_ERROR         0x0001  /* SCSI Bus Reset error */
1651#define ASC_WARN_EEPROM_CHKSUM          0x0002  /* EEP check sum error */
1652#define ASC_WARN_EEPROM_TERMINATION     0x0004  /* EEP termination bad field */
1653#define ASC_WARN_ERROR                  0xFFFF  /* ADV_ERROR return */
1654
1655#define ADV_MAX_TID                     15      /* max. target identifier */
1656#define ADV_MAX_LUN                     7       /* max. logical unit number */
1657
1658/*
1659 * Fixed locations of microcode operating variables.
1660 */
1661#define ASC_MC_CODE_BEGIN_ADDR          0x0028  /* microcode start address */
1662#define ASC_MC_CODE_END_ADDR            0x002A  /* microcode end address */
1663#define ASC_MC_CODE_CHK_SUM             0x002C  /* microcode code checksum */
1664#define ASC_MC_VERSION_DATE             0x0038  /* microcode version */
1665#define ASC_MC_VERSION_NUM              0x003A  /* microcode number */
1666#define ASC_MC_BIOSMEM                  0x0040  /* BIOS RISC Memory Start */
1667#define ASC_MC_BIOSLEN                  0x0050  /* BIOS RISC Memory Length */
1668#define ASC_MC_BIOS_SIGNATURE           0x0058  /* BIOS Signature 0x55AA */
1669#define ASC_MC_BIOS_VERSION             0x005A  /* BIOS Version (2 bytes) */
1670#define ASC_MC_SDTR_SPEED1              0x0090  /* SDTR Speed for TID 0-3 */
1671#define ASC_MC_SDTR_SPEED2              0x0092  /* SDTR Speed for TID 4-7 */
1672#define ASC_MC_SDTR_SPEED3              0x0094  /* SDTR Speed for TID 8-11 */
1673#define ASC_MC_SDTR_SPEED4              0x0096  /* SDTR Speed for TID 12-15 */
1674#define ASC_MC_CHIP_TYPE                0x009A
1675#define ASC_MC_INTRB_CODE               0x009B
1676#define ASC_MC_WDTR_ABLE                0x009C
1677#define ASC_MC_SDTR_ABLE                0x009E
1678#define ASC_MC_TAGQNG_ABLE              0x00A0
1679#define ASC_MC_DISC_ENABLE              0x00A2
1680#define ASC_MC_IDLE_CMD_STATUS          0x00A4
1681#define ASC_MC_IDLE_CMD                 0x00A6
1682#define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
1683#define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
1684#define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
1685#define ASC_MC_DEFAULT_MEM_CFG          0x00B0
1686#define ASC_MC_DEFAULT_SEL_MASK         0x00B2
1687#define ASC_MC_SDTR_DONE                0x00B6
1688#define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
1689#define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
1690#define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
1691#define ASC_MC_CONTROL_FLAG             0x0122  /* Microcode control flag. */
1692#define ASC_MC_WDTR_DONE                0x0124
1693#define ASC_MC_CAM_MODE_MASK            0x015E  /* CAM mode TID bitmask. */
1694#define ASC_MC_ICQ                      0x0160
1695#define ASC_MC_IRQ                      0x0164
1696#define ASC_MC_PPR_ABLE                 0x017A
1697
1698/*
1699 * BIOS LRAM variable absolute offsets.
1700 */
1701#define BIOS_CODESEG    0x54
1702#define BIOS_CODELEN    0x56
1703#define BIOS_SIGNATURE  0x58
1704#define BIOS_VERSION    0x5A
1705
1706/*
1707 * Microcode Control Flags
1708 *
1709 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
1710 * and handled by the microcode.
1711 */
1712#define CONTROL_FLAG_IGNORE_PERR        0x0001  /* Ignore DMA Parity Errors */
1713#define CONTROL_FLAG_ENABLE_AIPP        0x0002  /* Enabled AIPP checking. */
1714
1715/*
1716 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
1717 */
1718#define HSHK_CFG_WIDE_XFR       0x8000
1719#define HSHK_CFG_RATE           0x0F00
1720#define HSHK_CFG_OFFSET         0x001F
1721
1722#define ASC_DEF_MAX_HOST_QNG    0xFD    /* Max. number of host commands (253) */
1723#define ASC_DEF_MIN_HOST_QNG    0x10    /* Min. number of host commands (16) */
1724#define ASC_DEF_MAX_DVC_QNG     0x3F    /* Max. number commands per device (63) */
1725#define ASC_DEF_MIN_DVC_QNG     0x04    /* Min. number commands per device (4) */
1726
1727#define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
1728#define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
1729#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
1730#define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
1731#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
1732
1733#define ASC_QSC_NO_DISC     0x01        /* Don't allow disconnect for request. */
1734#define ASC_QSC_NO_TAGMSG   0x02        /* Don't allow tag queuing for request. */
1735#define ASC_QSC_NO_SYNC     0x04        /* Don't use Synch. transfer on request. */
1736#define ASC_QSC_NO_WIDE     0x08        /* Don't use Wide transfer on request. */
1737#define ASC_QSC_REDO_DTR    0x10        /* Renegotiate WDTR/SDTR before request. */
1738/*
1739 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
1740 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
1741 */
1742#define ASC_QSC_HEAD_TAG    0x40        /* Use Head Tag Message (0x21). */
1743#define ASC_QSC_ORDERED_TAG 0x80        /* Use Ordered Tag Message (0x22). */
1744
1745/*
1746 * All fields here are accessed by the board microcode and need to be
1747 * little-endian.
1748 */
1749typedef struct adv_carr_t {
1750        ADV_VADDR carr_va;      /* Carrier Virtual Address */
1751        ADV_PADDR carr_pa;      /* Carrier Physical Address */
1752        ADV_VADDR areq_vpa;     /* ASC_SCSI_REQ_Q Virtual or Physical Address */
1753        /*
1754         * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
1755         *
1756         * next_vpa [3:1]             Reserved Bits
1757         * next_vpa [0]               Done Flag set in Response Queue.
1758         */
1759        ADV_VADDR next_vpa;
1760} ADV_CARR_T;
1761
1762/*
1763 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
1764 */
1765#define ASC_NEXT_VPA_MASK       0xFFFFFFF0
1766
1767#define ASC_RQ_DONE             0x00000001
1768#define ASC_RQ_GOOD             0x00000002
1769#define ASC_CQ_STOPPER          0x00000000
1770
1771#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
1772
1773#define ADV_CARRIER_NUM_PAGE_CROSSING \
1774    (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + (PAGE_SIZE - 1))/PAGE_SIZE)
1775
1776#define ADV_CARRIER_BUFSIZE \
1777    ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
1778
1779/*
1780 * ASC_SCSI_REQ_Q 'a_flag' definitions
1781 *
1782 * The Adv Library should limit use to the lower nibble (4 bits) of
1783 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
1784 */
1785#define ADV_POLL_REQUEST                0x01    /* poll for request completion */
1786#define ADV_SCSIQ_DONE                  0x02    /* request done */
1787#define ADV_DONT_RETRY                  0x08    /* don't do retry */
1788
1789#define ADV_CHIP_ASC3550          0x01  /* Ultra-Wide IC */
1790#define ADV_CHIP_ASC38C0800       0x02  /* Ultra2-Wide/LVD IC */
1791#define ADV_CHIP_ASC38C1600       0x03  /* Ultra3-Wide/LVD2 IC */
1792
1793/*
1794 * Adapter temporary configuration structure
1795 *
1796 * This structure can be discarded after initialization. Don't add
1797 * fields here needed after initialization.
1798 *
1799 * Field naming convention:
1800 *
1801 *  *_enable indicates the field enables or disables a feature. The
1802 *  value of the field is never reset.
1803 */
1804typedef struct adv_dvc_cfg {
1805        ushort disc_enable;     /* enable disconnection */
1806        uchar chip_version;     /* chip version */
1807        uchar termination;      /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
1808        ushort control_flag;    /* Microcode Control Flag */
1809        ushort mcode_date;      /* Microcode date */
1810        ushort mcode_version;   /* Microcode version */
1811        ushort serial1;         /* EEPROM serial number word 1 */
1812        ushort serial2;         /* EEPROM serial number word 2 */
1813        ushort serial3;         /* EEPROM serial number word 3 */
1814} ADV_DVC_CFG;
1815
1816struct adv_dvc_var;
1817struct adv_scsi_req_q;
1818
1819typedef struct asc_sg_block {
1820        uchar reserved1;
1821        uchar reserved2;
1822        uchar reserved3;
1823        uchar sg_cnt;           /* Valid entries in block. */
1824        ADV_PADDR sg_ptr;       /* Pointer to next sg block. */
1825        struct {
1826                ADV_PADDR sg_addr;      /* SG element address. */
1827                ADV_DCNT sg_count;      /* SG element count. */
1828        } sg_list[NO_OF_SG_PER_BLOCK];
1829} ADV_SG_BLOCK;
1830
1831/*
1832 * ADV_SCSI_REQ_Q - microcode request structure
1833 *
1834 * All fields in this structure up to byte 60 are used by the microcode.
1835 * The microcode makes assumptions about the size and ordering of fields
1836 * in this structure. Do not change the structure definition here without
1837 * coordinating the change with the microcode.
1838 *
1839 * All fields accessed by microcode must be maintained in little_endian
1840 * order.
1841 */
1842typedef struct adv_scsi_req_q {
1843        uchar cntl;             /* Ucode flags and state (ASC_MC_QC_*). */
1844        uchar target_cmd;
1845        uchar target_id;        /* Device target identifier. */
1846        uchar target_lun;       /* Device target logical unit number. */
1847        ADV_PADDR data_addr;    /* Data buffer physical address. */
1848        ADV_DCNT data_cnt;      /* Data count. Ucode sets to residual. */
1849        ADV_PADDR sense_addr;
1850        ADV_PADDR carr_pa;
1851        uchar mflag;
1852        uchar sense_len;
1853        uchar cdb_len;          /* SCSI CDB length. Must <= 16 bytes. */
1854        uchar scsi_cntl;
1855        uchar done_status;      /* Completion status. */
1856        uchar scsi_status;      /* SCSI status byte. */
1857        uchar host_status;      /* Ucode host status. */
1858        uchar sg_working_ix;
1859        uchar cdb[12];          /* SCSI CDB bytes 0-11. */
1860        ADV_PADDR sg_real_addr; /* SG list physical address. */
1861        ADV_PADDR scsiq_rptr;
1862        uchar cdb16[4];         /* SCSI CDB bytes 12-15. */
1863        ADV_VADDR scsiq_ptr;
1864        ADV_VADDR carr_va;
1865        /*
1866         * End of microcode structure - 60 bytes. The rest of the structure
1867         * is used by the Adv Library and ignored by the microcode.
1868         */
1869        ADV_VADDR srb_ptr;
1870        ADV_SG_BLOCK *sg_list_ptr;      /* SG list virtual address. */
1871        char *vdata_addr;       /* Data buffer virtual address. */
1872        uchar a_flag;
1873        uchar pad[2];           /* Pad out to a word boundary. */
1874} ADV_SCSI_REQ_Q;
1875
1876/*
1877 * The following two structures are used to process Wide Board requests.
1878 *
1879 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
1880 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
1881 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
1882 * Mid-Level SCSI request structure.
1883 *
1884 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
1885 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
1886 * up to 255 scatter-gather elements may be used per request or
1887 * ADV_SCSI_REQ_Q.
1888 *
1889 * Both structures must be 32 byte aligned.
1890 */
1891typedef struct adv_sgblk {
1892        ADV_SG_BLOCK sg_block;  /* Sgblock structure. */
1893        uchar align[32];        /* Sgblock structure padding. */
1894        struct adv_sgblk *next_sgblkp;  /* Next scatter-gather structure. */
1895} adv_sgblk_t;
1896
1897typedef struct adv_req {
1898        ADV_SCSI_REQ_Q scsi_req_q;      /* Adv Library request structure. */
1899        uchar align[32];        /* Request structure padding. */
1900        struct scsi_cmnd *cmndp;        /* Mid-Level SCSI command pointer. */
1901        adv_sgblk_t *sgblkp;    /* Adv Library scatter-gather pointer. */
1902        struct adv_req *next_reqp;      /* Next Request Structure. */
1903} adv_req_t;
1904
1905/*
1906 * Adapter operation variable structure.
1907 *
1908 * One structure is required per host adapter.
1909 *
1910 * Field naming convention:
1911 *
1912 *  *_able indicates both whether a feature should be enabled or disabled
1913 *  and whether a device isi capable of the feature. At initialization
1914 *  this field may be set, but later if a device is found to be incapable
1915 *  of the feature, the field is cleared.
1916 */
1917typedef struct adv_dvc_var {
1918        AdvPortAddr iop_base;   /* I/O port address */
1919        ushort err_code;        /* fatal error code */
1920        ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
1921        ushort wdtr_able;       /* try WDTR for a device */
1922        ushort sdtr_able;       /* try SDTR for a device */
1923        ushort ultra_able;      /* try SDTR Ultra speed for a device */
1924        ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
1925        ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
1926        ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
1927        ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
1928        ushort tagqng_able;     /* try tagged queuing with a device */
1929        ushort ppr_able;        /* PPR message capable per TID bitmask. */
1930        uchar max_dvc_qng;      /* maximum number of tagged commands per device */
1931        ushort start_motor;     /* start motor command allowed */
1932        uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
1933        uchar chip_no;          /* should be assigned by caller */
1934        uchar max_host_qng;     /* maximum number of Q'ed command allowed */
1935        ushort no_scam;         /* scam_tolerant of EEPROM */
1936        struct asc_board *drv_ptr;      /* driver pointer to private structure */
1937        uchar chip_scsi_id;     /* chip SCSI target ID */
1938        uchar chip_type;
1939        uchar bist_err_code;
1940        ADV_CARR_T *carrier_buf;
1941        ADV_CARR_T *carr_freelist;      /* Carrier free list. */
1942        ADV_CARR_T *icq_sp;     /* Initiator command queue stopper pointer. */
1943        ADV_CARR_T *irq_sp;     /* Initiator response queue stopper pointer. */
1944        ushort carr_pending_cnt;        /* Count of pending carriers. */
1945        struct adv_req *orig_reqp;      /* adv_req_t memory block. */
1946        /*
1947         * Note: The following fields will not be used after initialization. The
1948         * driver may discard the buffer after initialization is done.
1949         */
1950        ADV_DVC_CFG *cfg;       /* temporary configuration structure  */
1951} ADV_DVC_VAR;
1952
1953/*
1954 * Microcode idle loop commands
1955 */
1956#define IDLE_CMD_COMPLETED           0
1957#define IDLE_CMD_STOP_CHIP           0x0001
1958#define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
1959#define IDLE_CMD_SEND_INT            0x0004
1960#define IDLE_CMD_ABORT               0x0008
1961#define IDLE_CMD_DEVICE_RESET        0x0010
1962#define IDLE_CMD_SCSI_RESET_START    0x0020     /* Assert SCSI Bus Reset */
1963#define IDLE_CMD_SCSI_RESET_END      0x0040     /* Deassert SCSI Bus Reset */
1964#define IDLE_CMD_SCSIREQ             0x0080
1965
1966#define IDLE_CMD_STATUS_SUCCESS      0x0001
1967#define IDLE_CMD_STATUS_FAILURE      0x0002
1968
1969/*
1970 * AdvSendIdleCmd() flag definitions.
1971 */
1972#define ADV_NOWAIT     0x01
1973
1974/*
1975 * Wait loop time out values.
1976 */
1977#define SCSI_WAIT_100_MSEC           100UL      /* 100 milliseconds */
1978#define SCSI_US_PER_MSEC             1000       /* microseconds per millisecond */
1979#define SCSI_MAX_RETRY               10 /* retry count */
1980
1981#define ADV_ASYNC_RDMA_FAILURE          0x01    /* Fatal RDMA failure. */
1982#define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02    /* Detected SCSI Bus Reset. */
1983#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03    /* Carrier Ready failure. */
1984#define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04    /* RDMAed-in data invalid. */
1985
1986#define ADV_HOST_SCSI_BUS_RESET      0x80       /* Host Initiated SCSI Bus Reset. */
1987
1988/* Read byte from a register. */
1989#define AdvReadByteRegister(iop_base, reg_off) \
1990     (ADV_MEM_READB((iop_base) + (reg_off)))
1991
1992/* Write byte to a register. */
1993#define AdvWriteByteRegister(iop_base, reg_off, byte) \
1994     (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
1995
1996/* Read word (2 bytes) from a register. */
1997#define AdvReadWordRegister(iop_base, reg_off) \
1998     (ADV_MEM_READW((iop_base) + (reg_off)))
1999
2000/* Write word (2 bytes) to a register. */
2001#define AdvWriteWordRegister(iop_base, reg_off, word) \
2002     (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
2003
2004/* Write dword (4 bytes) to a register. */
2005#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
2006     (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
2007
2008/* Read byte from LRAM. */
2009#define AdvReadByteLram(iop_base, addr, byte) \
2010do { \
2011    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2012    (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
2013} while (0)
2014
2015/* Write byte to LRAM. */
2016#define AdvWriteByteLram(iop_base, addr, byte) \
2017    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2018     ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
2019
2020/* Read word (2 bytes) from LRAM. */
2021#define AdvReadWordLram(iop_base, addr, word) \
2022do { \
2023    ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
2024    (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
2025} while (0)
2026
2027/* Write word (2 bytes) to LRAM. */
2028#define AdvWriteWordLram(iop_base, addr, word) \
2029    (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2030     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2031
2032/* Write little-endian double word (4 bytes) to LRAM */
2033/* Because of unspecified C language ordering don't use auto-increment. */
2034#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
2035    ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
2036      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2037                     cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
2038     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
2039      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
2040                     cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
2041
2042/* Read word (2 bytes) from LRAM assuming that the address is already set. */
2043#define AdvReadWordAutoIncLram(iop_base) \
2044     (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
2045
2046/* Write word (2 bytes) to LRAM assuming that the address is already set. */
2047#define AdvWriteWordAutoIncLram(iop_base, word) \
2048     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
2049
2050/*
2051 * Define macro to check for Condor signature.
2052 *
2053 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
2054 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
2055 */
2056#define AdvFindSignature(iop_base) \
2057    (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
2058    ADV_CHIP_ID_BYTE) && \
2059     (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
2060    ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
2061
2062/*
2063 * Define macro to Return the version number of the chip at 'iop_base'.
2064 *
2065 * The second parameter 'bus_type' is currently unused.
2066 */
2067#define AdvGetChipVersion(iop_base, bus_type) \
2068    AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
2069
2070/*
2071 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
2072 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
2073 *
2074 * If the request has not yet been sent to the device it will simply be
2075 * aborted from RISC memory. If the request is disconnected it will be
2076 * aborted on reselection by sending an Abort Message to the target ID.
2077 *
2078 * Return value:
2079 *      ADV_TRUE(1) - Queue was successfully aborted.
2080 *      ADV_FALSE(0) - Queue was not found on the active queue list.
2081 */
2082#define AdvAbortQueue(asc_dvc, scsiq) \
2083        AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
2084                       (ADV_DCNT) (scsiq))
2085
2086/*
2087 * Send a Bus Device Reset Message to the specified target ID.
2088 *
2089 * All outstanding commands will be purged if sending the
2090 * Bus Device Reset Message is successful.
2091 *
2092 * Return Value:
2093 *      ADV_TRUE(1) - All requests on the target are purged.
2094 *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
2095 *                     are not purged.
2096 */
2097#define AdvResetDevice(asc_dvc, target_id) \
2098        AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
2099                    (ADV_DCNT) (target_id))
2100
2101/*
2102 * SCSI Wide Type definition.
2103 */
2104#define ADV_SCSI_BIT_ID_TYPE   ushort
2105
2106/*
2107 * AdvInitScsiTarget() 'cntl_flag' options.
2108 */
2109#define ADV_SCAN_LUN           0x01
2110#define ADV_CAPINFO_NOLUN      0x02
2111
2112/*
2113 * Convert target id to target id bit mask.
2114 */
2115#define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
2116
2117/*
2118 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
2119 */
2120
2121#define QD_NO_STATUS         0x00       /* Request not completed yet. */
2122#define QD_NO_ERROR          0x01
2123#define QD_ABORTED_BY_HOST   0x02
2124#define QD_WITH_ERROR        0x04
2125
2126#define QHSTA_NO_ERROR              0x00
2127#define QHSTA_M_SEL_TIMEOUT         0x11
2128#define QHSTA_M_DATA_OVER_RUN       0x12
2129#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
2130#define QHSTA_M_QUEUE_ABORTED       0x15
2131#define QHSTA_M_SXFR_SDMA_ERR       0x16        /* SXFR_STATUS SCSI DMA Error */
2132#define QHSTA_M_SXFR_SXFR_PERR      0x17        /* SXFR_STATUS SCSI Bus Parity Error */
2133#define QHSTA_M_RDMA_PERR           0x18        /* RISC PCI DMA parity error */
2134#define QHSTA_M_SXFR_OFF_UFLW       0x19        /* SXFR_STATUS Offset Underflow */
2135#define QHSTA_M_SXFR_OFF_OFLW       0x20        /* SXFR_STATUS Offset Overflow */
2136#define QHSTA_M_SXFR_WD_TMO         0x21        /* SXFR_STATUS Watchdog Timeout */
2137#define QHSTA_M_SXFR_DESELECTED     0x22        /* SXFR_STATUS Deselected */
2138/* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
2139#define QHSTA_M_SXFR_XFR_OFLW       0x12        /* SXFR_STATUS Transfer Overflow */
2140#define QHSTA_M_SXFR_XFR_PH_ERR     0x24        /* SXFR_STATUS Transfer Phase Error */
2141#define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25        /* SXFR_STATUS Unknown Error */
2142#define QHSTA_M_SCSI_BUS_RESET      0x30        /* Request aborted from SBR */
2143#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31       /* Request aborted from unsol. SBR */
2144#define QHSTA_M_BUS_DEVICE_RESET    0x32        /* Request aborted from BDR */
2145#define QHSTA_M_DIRECTION_ERR       0x35        /* Data Phase mismatch */
2146#define QHSTA_M_DIRECTION_ERR_HUNG  0x36        /* Data Phase mismatch and bus hang */
2147#define QHSTA_M_WTM_TIMEOUT         0x41
2148#define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
2149#define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
2150#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
2151#define QHSTA_M_INVALID_DEVICE      0x45        /* Bad target ID */
2152#define QHSTA_M_FROZEN_TIDQ         0x46        /* TID Queue frozen. */
2153#define QHSTA_M_SGBACKUP_ERROR      0x47        /* Scatter-Gather backup error */
2154
2155/* Return the address that is aligned at the next doubleword >= to 'addr'. */
2156#define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
2157#define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
2158#define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
2159
2160/*
2161 * Total contiguous memory needed for driver SG blocks.
2162 *
2163 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
2164 * number of scatter-gather elements the driver supports in a
2165 * single request.
2166 */
2167
2168#define ADV_SG_LIST_MAX_BYTE_SIZE \
2169         (sizeof(ADV_SG_BLOCK) * \
2170          ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
2171
2172/* struct asc_board flags */
2173#define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
2174
2175#define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
2176
2177#define NO_ISA_DMA              0xff    /* No ISA DMA Channel Used */
2178
2179#define ASC_INFO_SIZE           128     /* advansys_info() line size */
2180
2181#ifdef CONFIG_PROC_FS
2182/* /proc/scsi/advansys/[0...] related definitions */
2183#define ASC_PRTBUF_SIZE         2048
2184#define ASC_PRTLINE_SIZE        160
2185
2186#define ASC_PRT_NEXT() \
2187    if (cp) { \
2188        totlen += len; \
2189        leftlen -= len; \
2190        if (leftlen == 0) { \
2191            return totlen; \
2192        } \
2193        cp += len; \
2194    }
2195#endif /* CONFIG_PROC_FS */
2196
2197/* Asc Library return codes */
2198#define ASC_TRUE        1
2199#define ASC_FALSE       0
2200#define ASC_NOERROR     1
2201#define ASC_BUSY        0
2202#define ASC_ERROR       (-1)
2203
2204/* struct scsi_cmnd function return codes */
2205#define STATUS_BYTE(byte)   (byte)
2206#define MSG_BYTE(byte)      ((byte) << 8)
2207#define HOST_BYTE(byte)     ((byte) << 16)
2208#define DRIVER_BYTE(byte)   ((byte) << 24)
2209
2210#define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
2211#ifndef ADVANSYS_STATS
2212#define ASC_STATS_ADD(shost, counter, count)
2213#else /* ADVANSYS_STATS */
2214#define ASC_STATS_ADD(shost, counter, count) \
2215        (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
2216#endif /* ADVANSYS_STATS */
2217
2218/* If the result wraps when calculating tenths, return 0. */
2219#define ASC_TENTHS(num, den) \
2220    (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
2221    0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
2222
2223/*
2224 * Display a message to the console.
2225 */
2226#define ASC_PRINT(s) \
2227    { \
2228        printk("advansys: "); \
2229        printk(s); \
2230    }
2231
2232#define ASC_PRINT1(s, a1) \
2233    { \
2234        printk("advansys: "); \
2235        printk((s), (a1)); \
2236    }
2237
2238#define ASC_PRINT2(s, a1, a2) \
2239    { \
2240        printk("advansys: "); \
2241        printk((s), (a1), (a2)); \
2242    }
2243
2244#define ASC_PRINT3(s, a1, a2, a3) \
2245    { \
2246        printk("advansys: "); \
2247        printk((s), (a1), (a2), (a3)); \
2248    }
2249
2250#define ASC_PRINT4(s, a1, a2, a3, a4) \
2251    { \
2252        printk("advansys: "); \
2253        printk((s), (a1), (a2), (a3), (a4)); \
2254    }
2255
2256#ifndef ADVANSYS_DEBUG
2257
2258#define ASC_DBG(lvl, s...)
2259#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
2260#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
2261#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2262#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
2263#define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
2264#define ASC_DBG_PRT_HEX(lvl, name, start, length)
2265#define ASC_DBG_PRT_CDB(lvl, cdb, len)
2266#define ASC_DBG_PRT_SENSE(lvl, sense, len)
2267#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
2268
2269#else /* ADVANSYS_DEBUG */
2270
2271/*
2272 * Debugging Message Levels:
2273 * 0: Errors Only
2274 * 1: High-Level Tracing
2275 * 2-N: Verbose Tracing
2276 */
2277
2278#define ASC_DBG(lvl, format, arg...) {                                  \
2279        if (asc_dbglvl >= (lvl))                                        \
2280                printk(KERN_DEBUG "%s: %s: " format, DRV_NAME,          \
2281                        __FUNCTION__ , ## arg);                         \
2282}
2283
2284#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
2285    { \
2286        if (asc_dbglvl >= (lvl)) { \
2287            asc_prt_scsi_host(s); \
2288        } \
2289    }
2290
2291#define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
2292    { \
2293        if (asc_dbglvl >= (lvl)) { \
2294            asc_prt_asc_scsi_q(scsiqp); \
2295        } \
2296    }
2297
2298#define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
2299    { \
2300        if (asc_dbglvl >= (lvl)) { \
2301            asc_prt_asc_qdone_info(qdone); \
2302        } \
2303    }
2304
2305#define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
2306    { \
2307        if (asc_dbglvl >= (lvl)) { \
2308            asc_prt_adv_scsi_req_q(scsiqp); \
2309        } \
2310    }
2311
2312#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
2313    { \
2314        if (asc_dbglvl >= (lvl)) { \
2315            asc_prt_hex((name), (start), (length)); \
2316        } \
2317    }
2318
2319#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
2320        ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
2321
2322#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
2323        ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
2324
2325#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
2326        ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
2327#endif /* ADVANSYS_DEBUG */
2328
2329#ifdef ADVANSYS_STATS
2330
2331/* Per board statistics structure */
2332struct asc_stats {
2333        /* Driver Entrypoint Statistics */
2334        ADV_DCNT queuecommand;  /* # calls to advansys_queuecommand() */
2335        ADV_DCNT reset;         /* # calls to advansys_eh_bus_reset() */
2336        ADV_DCNT biosparam;     /* # calls to advansys_biosparam() */
2337        ADV_DCNT interrupt;     /* # advansys_interrupt() calls */
2338        ADV_DCNT callback;      /* # calls to asc/adv_isr_callback() */
2339        ADV_DCNT done;          /* # calls to request's scsi_done function */
2340        ADV_DCNT build_error;   /* # asc/adv_build_req() ASC_ERROR returns. */
2341        ADV_DCNT adv_build_noreq;       /* # adv_build_req() adv_req_t alloc. fail. */
2342        ADV_DCNT adv_build_nosg;        /* # adv_build_req() adv_sgblk_t alloc. fail. */
2343        /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
2344        ADV_DCNT exe_noerror;   /* # ASC_NOERROR returns. */
2345        ADV_DCNT exe_busy;      /* # ASC_BUSY returns. */
2346        ADV_DCNT exe_error;     /* # ASC_ERROR returns. */
2347        ADV_DCNT exe_unknown;   /* # unknown returns. */
2348        /* Data Transfer Statistics */
2349        ADV_DCNT xfer_cnt;      /* # I/O requests received */
2350        ADV_DCNT xfer_elem;     /* # scatter-gather elements */
2351        ADV_DCNT xfer_sect;     /* # 512-byte blocks */
2352};
2353#endif /* ADVANSYS_STATS */
2354
2355/*
2356 * Structure allocated for each board.
2357 *
2358 * This structure is allocated by scsi_host_alloc() at the end
2359 * of the 'Scsi_Host' structure starting at the 'hostdata'
2360 * field. It is guaranteed to be allocated from DMA-able memory.
2361 */
2362struct asc_board {
2363        struct device *dev;
2364        uint flags;             /* Board flags */
2365        unsigned int irq;
2366        union {
2367                ASC_DVC_VAR asc_dvc_var;        /* Narrow board */
2368                ADV_DVC_VAR adv_dvc_var;        /* Wide board */
2369        } dvc_var;
2370        union {
2371                ASC_DVC_CFG asc_dvc_cfg;        /* Narrow board */
2372                ADV_DVC_CFG adv_dvc_cfg;        /* Wide board */
2373        } dvc_cfg;
2374        ushort asc_n_io_port;   /* Number I/O ports. */
2375        ADV_SCSI_BIT_ID_TYPE init_tidmask;      /* Target init./valid mask */
2376        ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
2377        ADV_SCSI_BIT_ID_TYPE queue_full;        /* Queue full mask */
2378        ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
2379        union {
2380                ASCEEP_CONFIG asc_eep;  /* Narrow EEPROM config. */
2381                ADVEEP_3550_CONFIG adv_3550_eep;        /* 3550 EEPROM config. */
2382                ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
2383                ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
2384        } eep_config;
2385        ulong last_reset;       /* Saved last reset time */
2386        /* /proc/scsi/advansys/[0...] */
2387        char *prtbuf;           /* /proc print buffer */
2388#ifdef ADVANSYS_STATS
2389        struct asc_stats asc_stats;     /* Board statistics */
2390#endif                          /* ADVANSYS_STATS */
2391        /*
2392         * The following fields are used only for Narrow Boards.
2393         */
2394        uchar sdtr_data[ASC_MAX_TID + 1];       /* SDTR information */
2395        /*
2396         * The following fields are used only for Wide Boards.
2397         */
2398        void __iomem *ioremap_addr;     /* I/O Memory remap address. */
2399        ushort ioport;          /* I/O Port address. */
2400        adv_req_t *adv_reqp;    /* Request structures. */
2401        adv_sgblk_t *adv_sgblkp;        /* Scatter-gather structures. */
2402        ushort bios_signature;  /* BIOS Signature. */
2403        ushort bios_version;    /* BIOS Version. */
2404        ushort bios_codeseg;    /* BIOS Code Segment. */
2405        ushort bios_codelen;    /* BIOS Code Segment Length. */
2406};
2407
2408#define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \
2409                                                        dvc_var.asc_dvc_var)
2410#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
2411                                                        dvc_var.adv_dvc_var)
2412#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
2413
2414#ifdef ADVANSYS_DEBUG
2415static int asc_dbglvl = 3;
2416
2417/*
2418 * asc_prt_asc_dvc_var()
2419 */
2420static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
2421{
2422        printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
2423
2424        printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
2425               "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
2426
2427        printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type,
2428                (unsigned)h->init_sdtr);
2429
2430        printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
2431               "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
2432               (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
2433               (unsigned)h->chip_no);
2434
2435        printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
2436               "%u,\n", (unsigned)h->queue_full_or_busy,
2437               (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2438
2439        printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
2440               "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
2441               (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
2442               (unsigned)h->in_critical_cnt);
2443
2444        printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
2445               "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
2446               (unsigned)h->init_state, (unsigned)h->no_scam,
2447               (unsigned)h->pci_fix_asyn_xfer);
2448
2449        printk(" cfg 0x%lx\n", (ulong)h->cfg);
2450}
2451
2452/*
2453 * asc_prt_asc_dvc_cfg()
2454 */
2455static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
2456{
2457        printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
2458
2459        printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
2460               h->can_tagged_qng, h->cmd_qng_enabled);
2461        printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
2462               h->disc_enable, h->sdtr_enable);
2463
2464        printk(" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, "
2465                "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed,
2466                h->isa_dma_channel, h->chip_version);
2467
2468        printk(" mcode_date 0x%x, mcode_version %d\n",
2469                h->mcode_date, h->mcode_version);
2470}
2471
2472/*
2473 * asc_prt_adv_dvc_var()
2474 *
2475 * Display an ADV_DVC_VAR structure.
2476 */
2477static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
2478{
2479        printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
2480
2481        printk("  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
2482               (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
2483
2484        printk("  sdtr_able 0x%x, wdtr_able 0x%x\n",
2485               (unsigned)h->sdtr_able, (unsigned)h->wdtr_able);
2486
2487        printk("  start_motor 0x%x, scsi_reset_wait 0x%x\n",
2488               (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
2489
2490        printk("  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
2491               (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
2492               (ulong)h->carr_freelist);
2493
2494        printk("  icq_sp 0x%lx, irq_sp 0x%lx\n",
2495               (ulong)h->icq_sp, (ulong)h->irq_sp);
2496
2497        printk("  no_scam 0x%x, tagqng_able 0x%x\n",
2498               (unsigned)h->no_scam, (unsigned)h->tagqng_able);
2499
2500        printk("  chip_scsi_id 0x%x, cfg 0x%lx\n",
2501               (unsigned)h->chip_scsi_id, (ulong)h->cfg);
2502}
2503
2504/*
2505 * asc_prt_adv_dvc_cfg()
2506 *
2507 * Display an ADV_DVC_CFG structure.
2508 */
2509static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
2510{
2511        printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
2512
2513        printk("  disc_enable 0x%x, termination 0x%x\n",
2514               h->disc_enable, h->termination);
2515
2516        printk("  chip_version 0x%x, mcode_date 0x%x\n",
2517               h->chip_version, h->mcode_date);
2518
2519        printk("  mcode_version 0x%x, control_flag 0x%x\n",
2520               h->mcode_version, h->control_flag);
2521}
2522
2523/*
2524 * asc_prt_scsi_host()
2525 */
2526static void asc_prt_scsi_host(struct Scsi_Host *s)
2527{
2528        struct asc_board *boardp = shost_priv(s);
2529
2530        printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id);
2531        printk(" host_busy %u, host_no %d, last_reset %d,\n",
2532               s->host_busy, s->host_no, (unsigned)s->last_reset);
2533
2534        printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
2535               (ulong)s->base, (ulong)s->io_port, boardp->irq);
2536
2537        printk(" dma_channel %d, this_id %d, can_queue %d,\n",
2538               s->dma_channel, s->this_id, s->can_queue);
2539
2540        printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
2541               s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
2542
2543        if (ASC_NARROW_BOARD(boardp)) {
2544                asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var);
2545                asc_prt_asc_dvc_cfg(&boardp->dvc_cfg.asc_dvc_cfg);
2546        } else {
2547                asc_prt_adv_dvc_var(&boardp->dvc_var.adv_dvc_var);
2548                asc_prt_adv_dvc_cfg(&boardp->dvc_cfg.adv_dvc_cfg);
2549        }
2550}
2551
2552/*
2553 * asc_prt_hex()
2554 *
2555 * Print hexadecimal output in 4 byte groupings 32 bytes
2556 * or 8 double-words per line.
2557 */
2558static void asc_prt_hex(char *f, uchar *s, int l)
2559{
2560        int i;
2561        int j;
2562        int k;
2563        int m;
2564
2565        printk("%s: (%d bytes)\n", f, l);
2566
2567        for (i = 0; i < l; i += 32) {
2568
2569                /* Display a maximum of 8 double-words per line. */
2570                if ((k = (l - i) / 4) >= 8) {
2571                        k = 8;
2572                        m = 0;
2573                } else {
2574                        m = (l - i) % 4;
2575                }
2576
2577                for (j = 0; j < k; j++) {
2578                        printk(" %2.2X%2.2X%2.2X%2.2X",
2579                               (unsigned)s[i + (j * 4)],
2580                               (unsigned)s[i + (j * 4) + 1],
2581                               (unsigned)s[i + (j * 4) + 2],
2582                               (unsigned)s[i + (j * 4) + 3]);
2583                }
2584
2585                switch (m) {
2586                case 0:
2587                default:
2588                        break;
2589                case 1:
2590                        printk(" %2.2X", (unsigned)s[i + (j * 4)]);
2591                        break;
2592                case 2:
2593                        printk(" %2.2X%2.2X",
2594                               (unsigned)s[i + (j * 4)],
2595                               (unsigned)s[i + (j * 4) + 1]);
2596                        break;
2597                case 3:
2598                        printk(" %2.2X%2.2X%2.2X",
2599                               (unsigned)s[i + (j * 4) + 1],
2600                               (unsigned)s[i + (j * 4) + 2],
2601                               (unsigned)s[i + (j * 4) + 3]);
2602                        break;
2603                }
2604
2605                printk("\n");
2606        }
2607}
2608
2609/*
2610 * asc_prt_asc_scsi_q()
2611 */
2612static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
2613{
2614        ASC_SG_HEAD *sgp;
2615        int i;
2616
2617        printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
2618
2619        printk
2620            (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
2621             q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
2622             q->q2.tag_code);
2623
2624        printk
2625            (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2626             (ulong)le32_to_cpu(q->q1.data_addr),
2627             (ulong)le32_to_cpu(q->q1.data_cnt),
2628             (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
2629
2630        printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
2631               (ulong)q->cdbptr, q->q2.cdb_len,
2632               (ulong)q->sg_head, q->q1.sg_queue_cnt);
2633
2634        if (q->sg_head) {
2635                sgp = q->sg_head;
2636                printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
2637                printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
2638                       sgp->queue_cnt);
2639                for (i = 0; i < sgp->entry_cnt; i++) {
2640                        printk(" [%u]: addr 0x%lx, bytes %lu\n",
2641                               i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
2642                               (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
2643                }
2644
2645        }
2646}
2647
2648/*
2649 * asc_prt_asc_qdone_info()
2650 */
2651static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
2652{
2653        printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
2654        printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
2655               (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
2656               q->d2.tag_code);
2657        printk
2658            (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
2659             q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
2660}
2661
2662/*
2663 * asc_prt_adv_sgblock()
2664 *
2665 * Display an ADV_SG_BLOCK structure.
2666 */
2667static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
2668{
2669        int i;
2670
2671        printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
2672               (ulong)b, sgblockno);
2673        printk("  sg_cnt %u, sg_ptr 0x%lx\n",
2674               b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
2675        BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK);
2676        if (b->sg_ptr != 0)
2677                BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK);
2678        for (i = 0; i < b->sg_cnt; i++) {
2679                printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
2680                       i, (ulong)b->sg_list[i].sg_addr,
2681                       (ulong)b->sg_list[i].sg_count);
2682        }
2683}
2684
2685/*
2686 * asc_prt_adv_scsi_req_q()
2687 *
2688 * Display an ADV_SCSI_REQ_Q structure.
2689 */
2690static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
2691{
2692        int sg_blk_cnt;
2693        struct asc_sg_block *sg_ptr;
2694
2695        printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
2696
2697        printk("  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
2698               q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
2699
2700        printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
2701               q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
2702
2703        printk("  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
2704               (ulong)le32_to_cpu(q->data_cnt),
2705               (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
2706
2707        printk
2708            ("  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
2709             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
2710
2711        printk("  sg_working_ix 0x%x, target_cmd %u\n",
2712               q->sg_working_ix, q->target_cmd);
2713
2714        printk("  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
2715               (ulong)le32_to_cpu(q->scsiq_rptr),
2716               (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
2717
2718        /* Display the request's ADV_SG_BLOCK structures. */
2719        if (q->sg_list_ptr != NULL) {
2720                sg_blk_cnt = 0;
2721                while (1) {
2722                        /*
2723                         * 'sg_ptr' is a physical address. Convert it to a virtual
2724                         * address by indexing 'sg_blk_cnt' into the virtual address
2725                         * array 'sg_list_ptr'.
2726                         *
2727                         * XXX - Assumes all SG physical blocks are virtually contiguous.
2728                         */
2729                        sg_ptr =
2730                            &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
2731                        asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
2732                        if (sg_ptr->sg_ptr == 0) {
2733                                break;
2734                        }
2735                        sg_blk_cnt++;
2736                }
2737        }
2738}
2739#endif /* ADVANSYS_DEBUG */
2740
2741/*
2742 * The advansys chip/microcode contains a 32-bit identifier for each command
2743 * known as the 'srb'.  I don't know what it stands for.  The driver used
2744 * to encode the scsi_cmnd pointer by calling virt_to_bus and retrieve it
2745 * with bus_to_virt.  Now the driver keeps a per-host map of integers to
2746 * pointers.  It auto-expands when full, unless it can't allocate memory.
2747 * Note that an srb of 0 is treated specially by the chip/firmware, hence
2748 * the return of i+1 in this routine, and the corresponding subtraction in
2749 * the inverse routine.
2750 */
2751#define BAD_SRB 0
2752static u32 advansys_ptr_to_srb(struct asc_dvc_var *asc_dvc, void *ptr)
2753{
2754        int i;
2755        void **new_ptr;
2756
2757        for (i = 0; i < asc_dvc->ptr_map_count; i++) {
2758                if (!asc_dvc->ptr_map[i])
2759                        goto out;
2760        }
2761
2762        if (asc_dvc->ptr_map_count == 0)
2763                asc_dvc->ptr_map_count = 1;
2764        else
2765                asc_dvc->ptr_map_count *= 2;
2766
2767        new_ptr = krealloc(asc_dvc->ptr_map,
2768                        asc_dvc->ptr_map_count * sizeof(void *), GFP_ATOMIC);
2769        if (!new_ptr)
2770                return BAD_SRB;
2771        asc_dvc->ptr_map = new_ptr;
2772 out:
2773        ASC_DBG(3, "Putting ptr %p into array offset %d\n", ptr, i);
2774        asc_dvc->ptr_map[i] = ptr;
2775        return i + 1;
2776}
2777
2778static void * advansys_srb_to_ptr(struct asc_dvc_var *asc_dvc, u32 srb)
2779{
2780        void *ptr;
2781
2782        srb--;
2783        if (srb >= asc_dvc->ptr_map_count) {
2784                printk("advansys: bad SRB %u, max %u\n", srb,
2785                                                        asc_dvc->ptr_map_count);
2786                return NULL;
2787        }
2788        ptr = asc_dvc->ptr_map[srb];
2789        asc_dvc->ptr_map[srb] = NULL;
2790        ASC_DBG(3, "Returning ptr %p from array offset %d\n", ptr, srb);
2791        return ptr;
2792}
2793
2794/*
2795 * advansys_info()
2796 *
2797 * Return suitable for printing on the console with the argument
2798 * adapter's configuration information.
2799 *
2800 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
2801 * otherwise the static 'info' array will be overrun.
2802 */
2803static const char *advansys_info(struct Scsi_Host *shost)
2804{
2805        static char info[ASC_INFO_SIZE];
2806        struct asc_board *boardp = shost_priv(shost);
2807        ASC_DVC_VAR *asc_dvc_varp;
2808        ADV_DVC_VAR *adv_dvc_varp;
2809        char *busname;
2810        char *widename = NULL;
2811
2812        if (ASC_NARROW_BOARD(boardp)) {
2813                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
2814                ASC_DBG(1, "begin\n");
2815                if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
2816                        if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
2817                            ASC_IS_ISAPNP) {
2818                                busname = "ISA PnP";
2819                        } else {
2820                                busname = "ISA";
2821                        }
2822                        sprintf(info,
2823                                "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
2824                                ASC_VERSION, busname,
2825                                (ulong)shost->io_port,
2826                                (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2827                                boardp->irq, shost->dma_channel);
2828                } else {
2829                        if (asc_dvc_varp->bus_type & ASC_IS_VL) {
2830                                busname = "VL";
2831                        } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
2832                                busname = "EISA";
2833                        } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
2834                                if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
2835                                    == ASC_IS_PCI_ULTRA) {
2836                                        busname = "PCI Ultra";
2837                                } else {
2838                                        busname = "PCI";
2839                                }
2840                        } else {
2841                                busname = "?";
2842                                shost_printk(KERN_ERR, shost, "unknown bus "
2843                                        "type %d\n", asc_dvc_varp->bus_type);
2844                        }
2845                        sprintf(info,
2846                                "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
2847                                ASC_VERSION, busname, (ulong)shost->io_port,
2848                                (ulong)shost->io_port + ASC_IOADR_GAP - 1,
2849                                boardp->irq);
2850                }
2851        } else {
2852                /*
2853                 * Wide Adapter Information
2854                 *
2855                 * Memory-mapped I/O is used instead of I/O space to access
2856                 * the adapter, but display the I/O Port range. The Memory
2857                 * I/O address is displayed through the driver /proc file.
2858                 */
2859                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
2860                if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
2861                        widename = "Ultra-Wide";
2862                } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
2863                        widename = "Ultra2-Wide";
2864                } else {
2865                        widename = "Ultra3-Wide";
2866                }
2867                sprintf(info,
2868                        "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
2869                        ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
2870                        (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
2871        }
2872        BUG_ON(strlen(info) >= ASC_INFO_SIZE);
2873        ASC_DBG(1, "end\n");
2874        return info;
2875}
2876
2877#ifdef CONFIG_PROC_FS
2878/*
2879 * asc_prt_line()
2880 *
2881 * If 'cp' is NULL print to the console, otherwise print to a buffer.
2882 *
2883 * Return 0 if printing to the console, otherwise return the number of
2884 * bytes written to the buffer.
2885 *
2886 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
2887 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
2888 */
2889static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
2890{
2891        va_list args;
2892        int ret;
2893        char s[ASC_PRTLINE_SIZE];
2894
2895        va_start(args, fmt);
2896        ret = vsprintf(s, fmt, args);
2897        BUG_ON(ret >= ASC_PRTLINE_SIZE);
2898        if (buf == NULL) {
2899                (void)printk(s);
2900                ret = 0;
2901        } else {
2902                ret = min(buflen, ret);
2903                memcpy(buf, s, ret);
2904        }
2905        va_end(args);
2906        return ret;
2907}
2908
2909/*
2910 * asc_prt_board_devices()
2911 *
2912 * Print driver information for devices attached to the board.
2913 *
2914 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
2915 * cf. asc_prt_line().
2916 *
2917 * Return the number of characters copied into 'cp'. No more than
2918 * 'cplen' characters will be copied to 'cp'.
2919 */
2920static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
2921{
2922        struct asc_board *boardp = shost_priv(shost);
2923        int leftlen;
2924        int totlen;
2925        int len;
2926        int chip_scsi_id;
2927        int i;
2928
2929        leftlen = cplen;
2930        totlen = len = 0;
2931
2932        len = asc_prt_line(cp, leftlen,
2933                           "\nDevice Information for AdvanSys SCSI Host %d:\n",
2934                           shost->host_no);
2935        ASC_PRT_NEXT();
2936
2937        if (ASC_NARROW_BOARD(boardp)) {
2938                chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
2939        } else {
2940                chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
2941        }
2942
2943        len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
2944        ASC_PRT_NEXT();
2945        for (i = 0; i <= ADV_MAX_TID; i++) {
2946                if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
2947                        len = asc_prt_line(cp, leftlen, " %X,", i);
2948                        ASC_PRT_NEXT();
2949                }
2950        }
2951        len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
2952        ASC_PRT_NEXT();
2953
2954        return totlen;
2955}
2956
2957/*
2958 * Display Wide Board BIOS Information.
2959 */
2960static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
2961{
2962        struct asc_board *boardp = shost_priv(shost);
2963        int leftlen;
2964        int totlen;
2965        int len;
2966        ushort major, minor, letter;
2967
2968        leftlen = cplen;
2969        totlen = len = 0;
2970
2971        len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
2972        ASC_PRT_NEXT();
2973
2974        /*
2975         * If the BIOS saved a valid signature, then fill in
2976         * the BIOS code segment base address.
2977         */
2978        if (boardp->bios_signature != 0x55AA) {
2979                len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
2980                ASC_PRT_NEXT();
2981                len = asc_prt_line(cp, leftlen,
2982                                   "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
2983                ASC_PRT_NEXT();
2984                len = asc_prt_line(cp, leftlen,
2985                                   "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
2986                ASC_PRT_NEXT();
2987        } else {
2988                major = (boardp->bios_version >> 12) & 0xF;
2989                minor = (boardp->bios_version >> 8) & 0xF;
2990                letter = (boardp->bios_version & 0xFF);
2991
2992                len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
2993                                   major, minor,
2994                                   letter >= 26 ? '?' : letter + 'A');
2995                ASC_PRT_NEXT();
2996
2997                /*
2998                 * Current available ROM BIOS release is 3.1I for UW
2999                 * and 3.2I for U2W. This code doesn't differentiate
3000                 * UW and U2W boards.
3001                 */
3002                if (major < 3 || (major <= 3 && minor < 1) ||
3003                    (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
3004                        len = asc_prt_line(cp, leftlen,
3005                                           "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
3006                        ASC_PRT_NEXT();
3007                        len = asc_prt_line(cp, leftlen,
3008                                           "ftp://ftp.connectcom.net/pub\n");
3009                        ASC_PRT_NEXT();
3010                }
3011        }
3012
3013        return totlen;
3014}
3015
3016/*
3017 * Add serial number to information bar if signature AAh
3018 * is found in at bit 15-9 (7 bits) of word 1.
3019 *
3020 * Serial Number consists fo 12 alpha-numeric digits.
3021 *
3022 *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
3023 *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
3024 *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
3025 *       5 - Product revision (A-J)    Word0:  "         "
3026 *
3027 *           Signature                 Word1: 15-9 (7 bits)
3028 *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
3029 *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
3030 *
3031 *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
3032 *
3033 * Note 1: Only production cards will have a serial number.
3034 *
3035 * Note 2: Signature is most significant 7 bits (0xFE).
3036 *
3037 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
3038 */
3039static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
3040{
3041        ushort w, num;
3042
3043        if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
3044                return ASC_FALSE;
3045        } else {
3046                /*
3047                 * First word - 6 digits.
3048                 */
3049                w = serialnum[0];
3050
3051                /* Product type - 1st digit. */
3052                if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
3053                        /* Product type is P=Prototype */
3054                        *cp += 0x8;
3055                }
3056                cp++;
3057
3058                /* Manufacturing location - 2nd digit. */
3059                *cp++ = 'A' + ((w & 0x1C00) >> 10);
3060
3061                /* Product ID - 3rd, 4th digits. */
3062                num = w & 0x3FF;
3063                *cp++ = '0' + (num / 100);
3064                num %= 100;
3065                *cp++ = '0' + (num / 10);
3066
3067                /* Product revision - 5th digit. */
3068                *cp++ = 'A' + (num % 10);
3069
3070                /*
3071                 * Second word
3072                 */
3073                w = serialnum[1];
3074
3075                /*
3076                 * Year - 6th digit.
3077                 *
3078                 * If bit 15 of third word is set, then the
3079                 * last digit of the year is greater than 7.
3080                 */
3081                if (serialnum[2] & 0x8000) {
3082                        *cp++ = '8' + ((w & 0x1C0) >> 6);
3083                } else {
3084                        *cp++ = '0' + ((w & 0x1C0) >> 6);
3085                }
3086
3087                /* Week of year - 7th, 8th digits. */
3088                num = w & 0x003F;
3089                *cp++ = '0' + num / 10;
3090                num %= 10;
3091                *cp++ = '0' + num;
3092
3093                /*
3094                 * Third word
3095                 */
3096                w = serialnum[2] & 0x7FFF;
3097
3098                /* Serial number - 9th digit. */
3099                *cp++ = 'A' + (w / 1000);
3100
3101                /* 10th, 11th, 12th digits. */
3102                num = w % 1000;
3103                *cp++ = '0' + num / 100;
3104                num %= 100;
3105                *cp++ = '0' + num / 10;
3106                num %= 10;
3107                *cp++ = '0' + num;
3108
3109                *cp = '\0';     /* Null Terminate the string. */
3110                return ASC_TRUE;
3111        }
3112}
3113
3114/*
3115 * asc_prt_asc_board_eeprom()
3116 *
3117 * Print board EEPROM configuration.
3118 *
3119 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3120 * cf. asc_prt_line().
3121 *
3122 * Return the number of characters copied into 'cp'. No more than
3123 * 'cplen' characters will be copied to 'cp'.
3124 */
3125static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3126{
3127        struct asc_board *boardp = shost_priv(shost);
3128        ASC_DVC_VAR *asc_dvc_varp;
3129        int leftlen;
3130        int totlen;
3131        int len;
3132        ASCEEP_CONFIG *ep;
3133        int i;
3134#ifdef CONFIG_ISA
3135        int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
3136#endif /* CONFIG_ISA */
3137        uchar serialstr[13];
3138
3139        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
3140        ep = &boardp->eep_config.asc_eep;
3141
3142        leftlen = cplen;
3143        totlen = len = 0;
3144
3145        len = asc_prt_line(cp, leftlen,
3146                           "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3147                           shost->host_no);
3148        ASC_PRT_NEXT();
3149
3150        if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
3151            == ASC_TRUE) {
3152                len =
3153                    asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3154                                 serialstr);
3155                ASC_PRT_NEXT();
3156        } else {
3157                if (ep->adapter_info[5] == 0xBB) {
3158                        len = asc_prt_line(cp, leftlen,
3159                                           " Default Settings Used for EEPROM-less Adapter.\n");
3160                        ASC_PRT_NEXT();
3161                } else {
3162                        len = asc_prt_line(cp, leftlen,
3163                                           " Serial Number Signature Not Present.\n");
3164                        ASC_PRT_NEXT();
3165                }
3166        }
3167
3168        len = asc_prt_line(cp, leftlen,
3169                           " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3170                           ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
3171                           ep->max_tag_qng);
3172        ASC_PRT_NEXT();
3173
3174        len = asc_prt_line(cp, leftlen,
3175                           " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
3176        ASC_PRT_NEXT();
3177
3178        len = asc_prt_line(cp, leftlen, " Target ID:           ");
3179        ASC_PRT_NEXT();
3180        for (i = 0; i <= ASC_MAX_TID; i++) {
3181                len = asc_prt_line(cp, leftlen, " %d", i);
3182                ASC_PRT_NEXT();
3183        }
3184        len = asc_prt_line(cp, leftlen, "\n");
3185        ASC_PRT_NEXT();
3186
3187        len = asc_prt_line(cp, leftlen, " Disconnects:         ");
3188        ASC_PRT_NEXT();
3189        for (i = 0; i <= ASC_MAX_TID; i++) {
3190                len = asc_prt_line(cp, leftlen, " %c",
3191                                   (ep->
3192                                    disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3193                                   'N');
3194                ASC_PRT_NEXT();
3195        }
3196        len = asc_prt_line(cp, leftlen, "\n");
3197        ASC_PRT_NEXT();
3198
3199        len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
3200        ASC_PRT_NEXT();
3201        for (i = 0; i <= ASC_MAX_TID; i++) {
3202                len = asc_prt_line(cp, leftlen, " %c",
3203                                   (ep->
3204                                    use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3205                                   'N');
3206                ASC_PRT_NEXT();
3207        }
3208        len = asc_prt_line(cp, leftlen, "\n");
3209        ASC_PRT_NEXT();
3210
3211        len = asc_prt_line(cp, leftlen, " Start Motor:         ");
3212        ASC_PRT_NEXT();
3213        for (i = 0; i <= ASC_MAX_TID; i++) {
3214                len = asc_prt_line(cp, leftlen, " %c",
3215                                   (ep->
3216                                    start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3217                                   'N');
3218                ASC_PRT_NEXT();
3219        }
3220        len = asc_prt_line(cp, leftlen, "\n");
3221        ASC_PRT_NEXT();
3222
3223        len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3224        ASC_PRT_NEXT();
3225        for (i = 0; i <= ASC_MAX_TID; i++) {
3226                len = asc_prt_line(cp, leftlen, " %c",
3227                                   (ep->
3228                                    init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3229                                   'N');
3230                ASC_PRT_NEXT();
3231        }
3232        len = asc_prt_line(cp, leftlen, "\n");
3233        ASC_PRT_NEXT();
3234
3235#ifdef CONFIG_ISA
3236        if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
3237                len = asc_prt_line(cp, leftlen,
3238                                   " Host ISA DMA speed:   %d MB/S\n",
3239                                   isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
3240                ASC_PRT_NEXT();
3241        }
3242#endif /* CONFIG_ISA */
3243
3244        return totlen;
3245}
3246
3247/*
3248 * asc_prt_adv_board_eeprom()
3249 *
3250 * Print board EEPROM configuration.
3251 *
3252 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3253 * cf. asc_prt_line().
3254 *
3255 * Return the number of characters copied into 'cp'. No more than
3256 * 'cplen' characters will be copied to 'cp'.
3257 */
3258static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
3259{
3260        struct asc_board *boardp = shost_priv(shost);
3261        ADV_DVC_VAR *adv_dvc_varp;
3262        int leftlen;
3263        int totlen;
3264        int len;
3265        int i;
3266        char *termstr;
3267        uchar serialstr[13];
3268        ADVEEP_3550_CONFIG *ep_3550 = NULL;
3269        ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
3270        ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
3271        ushort word;
3272        ushort *wordp;
3273        ushort sdtr_speed = 0;
3274
3275        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
3276        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3277                ep_3550 = &boardp->eep_config.adv_3550_eep;
3278        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3279                ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
3280        } else {
3281                ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
3282        }
3283
3284        leftlen = cplen;
3285        totlen = len = 0;
3286
3287        len = asc_prt_line(cp, leftlen,
3288                           "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
3289                           shost->host_no);
3290        ASC_PRT_NEXT();
3291
3292        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3293                wordp = &ep_3550->serial_number_word1;
3294        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3295                wordp = &ep_38C0800->serial_number_word1;
3296        } else {
3297                wordp = &ep_38C1600->serial_number_word1;
3298        }
3299
3300        if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
3301                len =
3302                    asc_prt_line(cp, leftlen, " Serial Number: %s\n",
3303                                 serialstr);
3304                ASC_PRT_NEXT();
3305        } else {
3306                len = asc_prt_line(cp, leftlen,
3307                                   " Serial Number Signature Not Present.\n");
3308                ASC_PRT_NEXT();
3309        }
3310
3311        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3312                len = asc_prt_line(cp, leftlen,
3313                                   " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3314                                   ep_3550->adapter_scsi_id,
3315                                   ep_3550->max_host_qng, ep_3550->max_dvc_qng);
3316                ASC_PRT_NEXT();
3317        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3318                len = asc_prt_line(cp, leftlen,
3319                                   " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3320                                   ep_38C0800->adapter_scsi_id,
3321                                   ep_38C0800->max_host_qng,
3322                                   ep_38C0800->max_dvc_qng);
3323                ASC_PRT_NEXT();
3324        } else {
3325                len = asc_prt_line(cp, leftlen,
3326                                   " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
3327                                   ep_38C1600->adapter_scsi_id,
3328                                   ep_38C1600->max_host_qng,
3329                                   ep_38C1600->max_dvc_qng);
3330                ASC_PRT_NEXT();
3331        }
3332        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3333                word = ep_3550->termination;
3334        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3335                word = ep_38C0800->termination_lvd;
3336        } else {
3337                word = ep_38C1600->termination_lvd;
3338        }
3339        switch (word) {
3340        case 1:
3341                termstr = "Low Off/High Off";
3342                break;
3343        case 2:
3344                termstr = "Low Off/High On";
3345                break;
3346        case 3:
3347                termstr = "Low On/High On";
3348                break;
3349        default:
3350        case 0:
3351                termstr = "Automatic";
3352                break;
3353        }
3354
3355        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3356                len = asc_prt_line(cp, leftlen,
3357                                   " termination: %u (%s), bios_ctrl: 0x%x\n",
3358                                   ep_3550->termination, termstr,
3359                                   ep_3550->bios_ctrl);
3360                ASC_PRT_NEXT();
3361        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3362                len = asc_prt_line(cp, leftlen,
3363                                   " termination: %u (%s), bios_ctrl: 0x%x\n",
3364                                   ep_38C0800->termination_lvd, termstr,
3365                                   ep_38C0800->bios_ctrl);
3366                ASC_PRT_NEXT();
3367        } else {
3368                len = asc_prt_line(cp, leftlen,
3369                                   " termination: %u (%s), bios_ctrl: 0x%x\n",
3370                                   ep_38C1600->termination_lvd, termstr,
3371                                   ep_38C1600->bios_ctrl);
3372                ASC_PRT_NEXT();
3373        }
3374
3375        len = asc_prt_line(cp, leftlen, " Target ID:           ");
3376        ASC_PRT_NEXT();
3377        for (i = 0; i <= ADV_MAX_TID; i++) {
3378                len = asc_prt_line(cp, leftlen, " %X", i);
3379                ASC_PRT_NEXT();
3380        }
3381        len = asc_prt_line(cp, leftlen, "\n");
3382        ASC_PRT_NEXT();
3383
3384        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3385                word = ep_3550->disc_enable;
3386        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3387                word = ep_38C0800->disc_enable;
3388        } else {
3389                word = ep_38C1600->disc_enable;
3390        }
3391        len = asc_prt_line(cp, leftlen, " Disconnects:         ");
3392        ASC_PRT_NEXT();
3393        for (i = 0; i <= ADV_MAX_TID; i++) {
3394                len = asc_prt_line(cp, leftlen, " %c",
3395                                   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3396                ASC_PRT_NEXT();
3397        }
3398        len = asc_prt_line(cp, leftlen, "\n");
3399        ASC_PRT_NEXT();
3400
3401        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3402                word = ep_3550->tagqng_able;
3403        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3404                word = ep_38C0800->tagqng_able;
3405        } else {
3406                word = ep_38C1600->tagqng_able;
3407        }
3408        len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
3409        ASC_PRT_NEXT();
3410        for (i = 0; i <= ADV_MAX_TID; i++) {
3411                len = asc_prt_line(cp, leftlen, " %c",
3412                                   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3413                ASC_PRT_NEXT();
3414        }
3415        len = asc_prt_line(cp, leftlen, "\n");
3416        ASC_PRT_NEXT();
3417
3418        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3419                word = ep_3550->start_motor;
3420        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3421                word = ep_38C0800->start_motor;
3422        } else {
3423                word = ep_38C1600->start_motor;
3424        }
3425        len = asc_prt_line(cp, leftlen, " Start Motor:         ");
3426        ASC_PRT_NEXT();
3427        for (i = 0; i <= ADV_MAX_TID; i++) {
3428                len = asc_prt_line(cp, leftlen, " %c",
3429                                   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3430                ASC_PRT_NEXT();
3431        }
3432        len = asc_prt_line(cp, leftlen, "\n");
3433        ASC_PRT_NEXT();
3434
3435        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3436                len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3437                ASC_PRT_NEXT();
3438                for (i = 0; i <= ADV_MAX_TID; i++) {
3439                        len = asc_prt_line(cp, leftlen, " %c",
3440                                           (ep_3550->
3441                                            sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
3442                                           'Y' : 'N');
3443                        ASC_PRT_NEXT();
3444                }
3445                len = asc_prt_line(cp, leftlen, "\n");
3446                ASC_PRT_NEXT();
3447        }
3448
3449        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3450                len = asc_prt_line(cp, leftlen, " Ultra Transfer:      ");
3451                ASC_PRT_NEXT();
3452                for (i = 0; i <= ADV_MAX_TID; i++) {
3453                        len = asc_prt_line(cp, leftlen, " %c",
3454                                           (ep_3550->
3455                                            ultra_able & ADV_TID_TO_TIDMASK(i))
3456                                           ? 'Y' : 'N');
3457                        ASC_PRT_NEXT();
3458                }
3459                len = asc_prt_line(cp, leftlen, "\n");
3460                ASC_PRT_NEXT();
3461        }
3462
3463        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
3464                word = ep_3550->wdtr_able;
3465        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
3466                word = ep_38C0800->wdtr_able;
3467        } else {
3468                word = ep_38C1600->wdtr_able;
3469        }
3470        len = asc_prt_line(cp, leftlen, " Wide Transfer:       ");
3471        ASC_PRT_NEXT();
3472        for (i = 0; i <= ADV_MAX_TID; i++) {
3473                len = asc_prt_line(cp, leftlen, " %c",
3474                                   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
3475                ASC_PRT_NEXT();
3476        }
3477        len = asc_prt_line(cp, leftlen, "\n");
3478        ASC_PRT_NEXT();
3479
3480        if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
3481            adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
3482                len = asc_prt_line(cp, leftlen,
3483                                   " Synchronous Transfer Speed (Mhz):\n  ");
3484                ASC_PRT_NEXT();
3485                for (i = 0; i <= ADV_MAX_TID; i++) {
3486                        char *speed_str;
3487
3488                        if (i == 0) {
3489                                sdtr_speed = adv_dvc_varp->sdtr_speed1;
3490                        } else if (i == 4) {
3491                                sdtr_speed = adv_dvc_varp->sdtr_speed2;
3492                        } else if (i == 8) {
3493                                sdtr_speed = adv_dvc_varp->sdtr_speed3;
3494                        } else if (i == 12) {
3495                                sdtr_speed = adv_dvc_varp->sdtr_speed4;
3496                        }
3497                        switch (sdtr_speed & ADV_MAX_TID) {
3498                        case 0:
3499                                speed_str = "Off";
3500                                break;
3501                        case 1:
3502                                speed_str = "  5";
3503                                break;
3504                        case 2:
3505                                speed_str = " 10";
3506                                break;
3507                        case 3:
3508                                speed_str = " 20";
3509                                break;
3510                        case 4:
3511                                speed_str = " 40";
3512                                break;
3513                        case 5:
3514                                speed_str = " 80";
3515                                break;
3516                        default:
3517                                speed_str = "Unk";
3518                                break;
3519                        }
3520                        len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
3521                        ASC_PRT_NEXT();
3522                        if (i == 7) {
3523                                len = asc_prt_line(cp, leftlen, "\n  ");
3524                                ASC_PRT_NEXT();
3525                        }
3526                        sdtr_speed >>= 4;
3527                }
3528                len = asc_prt_line(cp, leftlen, "\n");
3529                ASC_PRT_NEXT();
3530        }
3531
3532        return totlen;
3533}
3534
3535/*
3536 * asc_prt_driver_conf()
3537 *
3538 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3539 * cf. asc_prt_line().
3540 *
3541 * Return the number of characters copied into 'cp'. No more than
3542 * 'cplen' characters will be copied to 'cp'.
3543 */
3544static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
3545{
3546        struct asc_board *boardp = shost_priv(shost);
3547        int leftlen;
3548        int totlen;
3549        int len;
3550        int chip_scsi_id;
3551
3552        leftlen = cplen;
3553        totlen = len = 0;
3554
3555        len = asc_prt_line(cp, leftlen,
3556                           "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
3557                           shost->host_no);
3558        ASC_PRT_NEXT();
3559
3560        len = asc_prt_line(cp, leftlen,
3561                           " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
3562                           shost->host_busy, shost->last_reset, shost->max_id,
3563                           shost->max_lun, shost->max_channel);
3564        ASC_PRT_NEXT();
3565
3566        len = asc_prt_line(cp, leftlen,
3567                           " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
3568                           shost->unique_id, shost->can_queue, shost->this_id,
3569                           shost->sg_tablesize, shost->cmd_per_lun);
3570        ASC_PRT_NEXT();
3571
3572        len = asc_prt_line(cp, leftlen,
3573                           " unchecked_isa_dma %d, use_clustering %d\n",
3574                           shost->unchecked_isa_dma, shost->use_clustering);
3575        ASC_PRT_NEXT();
3576
3577        len = asc_prt_line(cp, leftlen,
3578                           " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
3579                           boardp->flags, boardp->last_reset, jiffies,
3580                           boardp->asc_n_io_port);
3581        ASC_PRT_NEXT();
3582
3583        len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
3584        ASC_PRT_NEXT();
3585
3586        if (ASC_NARROW_BOARD(boardp)) {
3587                chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
3588        } else {
3589                chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
3590        }
3591
3592        return totlen;
3593}
3594
3595/*
3596 * asc_prt_asc_board_info()
3597 *
3598 * Print dynamic board configuration information.
3599 *
3600 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3601 * cf. asc_prt_line().
3602 *
3603 * Return the number of characters copied into 'cp'. No more than
3604 * 'cplen' characters will be copied to 'cp'.
3605 */
3606static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3607{
3608        struct asc_board *boardp = shost_priv(shost);
3609        int chip_scsi_id;
3610        int leftlen;
3611        int totlen;
3612        int len;
3613        ASC_DVC_VAR *v;
3614        ASC_DVC_CFG *c;
3615        int i;
3616        int renegotiate = 0;
3617
3618        v = &boardp->dvc_var.asc_dvc_var;
3619        c = &boardp->dvc_cfg.asc_dvc_cfg;
3620        chip_scsi_id = c->chip_scsi_id;
3621
3622        leftlen = cplen;
3623        totlen = len = 0;
3624
3625        len = asc_prt_line(cp, leftlen,
3626                           "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3627                           shost->host_no);
3628        ASC_PRT_NEXT();
3629
3630        len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3631                           "mcode_version 0x%x, err_code %u\n",
3632                           c->chip_version, c->mcode_date, c->mcode_version,
3633                           v->err_code);
3634        ASC_PRT_NEXT();
3635
3636        /* Current number of commands waiting for the host. */
3637        len = asc_prt_line(cp, leftlen,
3638                           " Total Command Pending: %d\n", v->cur_total_qng);
3639        ASC_PRT_NEXT();
3640
3641        len = asc_prt_line(cp, leftlen, " Command Queuing:");
3642        ASC_PRT_NEXT();
3643        for (i = 0; i <= ASC_MAX_TID; i++) {
3644                if ((chip_scsi_id == i) ||
3645                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3646                        continue;
3647                }
3648                len = asc_prt_line(cp, leftlen, " %X:%c",
3649                                   i,
3650                                   (v->
3651                                    use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
3652                                   'Y' : 'N');
3653                ASC_PRT_NEXT();
3654        }
3655        len = asc_prt_line(cp, leftlen, "\n");
3656        ASC_PRT_NEXT();
3657
3658        /* Current number of commands waiting for a device. */
3659        len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
3660        ASC_PRT_NEXT();
3661        for (i = 0; i <= ASC_MAX_TID; i++) {
3662                if ((chip_scsi_id == i) ||
3663                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3664                        continue;
3665                }
3666                len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
3667                ASC_PRT_NEXT();
3668        }
3669        len = asc_prt_line(cp, leftlen, "\n");
3670        ASC_PRT_NEXT();
3671
3672        /* Current limit on number of commands that can be sent to a device. */
3673        len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
3674        ASC_PRT_NEXT();
3675        for (i = 0; i <= ASC_MAX_TID; i++) {
3676                if ((chip_scsi_id == i) ||
3677                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3678                        continue;
3679                }
3680                len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
3681                ASC_PRT_NEXT();
3682        }
3683        len = asc_prt_line(cp, leftlen, "\n");
3684        ASC_PRT_NEXT();
3685
3686        /* Indicate whether the device has returned queue full status. */
3687        len = asc_prt_line(cp, leftlen, " Command Queue Full:");
3688        ASC_PRT_NEXT();
3689        for (i = 0; i <= ASC_MAX_TID; i++) {
3690                if ((chip_scsi_id == i) ||
3691                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3692                        continue;
3693                }
3694                if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
3695                        len = asc_prt_line(cp, leftlen, " %X:Y-%d",
3696                                           i, boardp->queue_full_cnt[i]);
3697                } else {
3698                        len = asc_prt_line(cp, leftlen, " %X:N", i);
3699                }
3700                ASC_PRT_NEXT();
3701        }
3702        len = asc_prt_line(cp, leftlen, "\n");
3703        ASC_PRT_NEXT();
3704
3705        len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
3706        ASC_PRT_NEXT();
3707        for (i = 0; i <= ASC_MAX_TID; i++) {
3708                if ((chip_scsi_id == i) ||
3709                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3710                        continue;
3711                }
3712                len = asc_prt_line(cp, leftlen, " %X:%c",
3713                                   i,
3714                                   (v->
3715                                    sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3716                                   'N');
3717                ASC_PRT_NEXT();
3718        }
3719        len = asc_prt_line(cp, leftlen, "\n");
3720        ASC_PRT_NEXT();
3721
3722        for (i = 0; i <= ASC_MAX_TID; i++) {
3723                uchar syn_period_ix;
3724
3725                if ((chip_scsi_id == i) ||
3726                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3727                    ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
3728                        continue;
3729                }
3730
3731                len = asc_prt_line(cp, leftlen, "  %X:", i);
3732                ASC_PRT_NEXT();
3733
3734                if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
3735                        len = asc_prt_line(cp, leftlen, " Asynchronous");
3736                        ASC_PRT_NEXT();
3737                } else {
3738                        syn_period_ix =
3739                            (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
3740                                                           1);
3741
3742                        len = asc_prt_line(cp, leftlen,
3743                                           " Transfer Period Factor: %d (%d.%d Mhz),",
3744                                           v->sdtr_period_tbl[syn_period_ix],
3745                                           250 /
3746                                           v->sdtr_period_tbl[syn_period_ix],
3747                                           ASC_TENTHS(250,
3748                                                      v->
3749                                                      sdtr_period_tbl
3750                                                      [syn_period_ix]));
3751                        ASC_PRT_NEXT();
3752
3753                        len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
3754                                           boardp->
3755                                           sdtr_data[i] & ASC_SYN_MAX_OFFSET);
3756                        ASC_PRT_NEXT();
3757                }
3758
3759                if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3760                        len = asc_prt_line(cp, leftlen, "*\n");
3761                        renegotiate = 1;
3762                } else {
3763                        len = asc_prt_line(cp, leftlen, "\n");
3764                }
3765                ASC_PRT_NEXT();
3766        }
3767
3768        if (renegotiate) {
3769                len = asc_prt_line(cp, leftlen,
3770                                   " * = Re-negotiation pending before next command.\n");
3771                ASC_PRT_NEXT();
3772        }
3773
3774        return totlen;
3775}
3776
3777/*
3778 * asc_prt_adv_board_info()
3779 *
3780 * Print dynamic board configuration information.
3781 *
3782 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
3783 * cf. asc_prt_line().
3784 *
3785 * Return the number of characters copied into 'cp'. No more than
3786 * 'cplen' characters will be copied to 'cp'.
3787 */
3788static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
3789{
3790        struct asc_board *boardp = shost_priv(shost);
3791        int leftlen;
3792        int totlen;
3793        int len;
3794        int i;
3795        ADV_DVC_VAR *v;
3796        ADV_DVC_CFG *c;
3797        AdvPortAddr iop_base;
3798        ushort chip_scsi_id;
3799        ushort lramword;
3800        uchar lrambyte;
3801        ushort tagqng_able;
3802        ushort sdtr_able, wdtr_able;
3803        ushort wdtr_done, sdtr_done;
3804        ushort period = 0;
3805        int renegotiate = 0;
3806
3807        v = &boardp->dvc_var.adv_dvc_var;
3808        c = &boardp->dvc_cfg.adv_dvc_cfg;
3809        iop_base = v->iop_base;
3810        chip_scsi_id = v->chip_scsi_id;
3811
3812        leftlen = cplen;
3813        totlen = len = 0;
3814
3815        len = asc_prt_line(cp, leftlen,
3816                           "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
3817                           shost->host_no);
3818        ASC_PRT_NEXT();
3819
3820        len = asc_prt_line(cp, leftlen,
3821                           " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
3822                           v->iop_base,
3823                           AdvReadWordRegister(iop_base,
3824                                               IOPW_SCSI_CFG1) & CABLE_DETECT,
3825                           v->err_code);
3826        ASC_PRT_NEXT();
3827
3828        len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, "
3829                           "mcode_version 0x%x\n", c->chip_version,
3830                           c->mcode_date, c->mcode_version);
3831        ASC_PRT_NEXT();
3832
3833        AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
3834        len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
3835        ASC_PRT_NEXT();
3836        for (i = 0; i <= ADV_MAX_TID; i++) {
3837                if ((chip_scsi_id == i) ||
3838                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3839                        continue;
3840                }
3841
3842                len = asc_prt_line(cp, leftlen, " %X:%c",
3843                                   i,
3844                                   (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3845                                   'N');
3846                ASC_PRT_NEXT();
3847        }
3848        len = asc_prt_line(cp, leftlen, "\n");
3849        ASC_PRT_NEXT();
3850
3851        len = asc_prt_line(cp, leftlen, " Queue Limit:");
3852        ASC_PRT_NEXT();
3853        for (i = 0; i <= ADV_MAX_TID; i++) {
3854                if ((chip_scsi_id == i) ||
3855                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3856                        continue;
3857                }
3858
3859                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
3860                                lrambyte);
3861
3862                len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3863                ASC_PRT_NEXT();
3864        }
3865        len = asc_prt_line(cp, leftlen, "\n");
3866        ASC_PRT_NEXT();
3867
3868        len = asc_prt_line(cp, leftlen, " Command Pending:");
3869        ASC_PRT_NEXT();
3870        for (i = 0; i <= ADV_MAX_TID; i++) {
3871                if ((chip_scsi_id == i) ||
3872                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3873                        continue;
3874                }
3875
3876                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
3877                                lrambyte);
3878
3879                len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
3880                ASC_PRT_NEXT();
3881        }
3882        len = asc_prt_line(cp, leftlen, "\n");
3883        ASC_PRT_NEXT();
3884
3885        AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
3886        len = asc_prt_line(cp, leftlen, " Wide Enabled:");
3887        ASC_PRT_NEXT();
3888        for (i = 0; i <= ADV_MAX_TID; i++) {
3889                if ((chip_scsi_id == i) ||
3890                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3891                        continue;
3892                }
3893
3894                len = asc_prt_line(cp, leftlen, " %X:%c",
3895                                   i,
3896                                   (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3897                                   'N');
3898                ASC_PRT_NEXT();
3899        }
3900        len = asc_prt_line(cp, leftlen, "\n");
3901        ASC_PRT_NEXT();
3902
3903        AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
3904        len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
3905        ASC_PRT_NEXT();
3906        for (i = 0; i <= ADV_MAX_TID; i++) {
3907                if ((chip_scsi_id == i) ||
3908                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3909                        continue;
3910                }
3911
3912                AdvReadWordLram(iop_base,
3913                                ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3914                                lramword);
3915
3916                len = asc_prt_line(cp, leftlen, " %X:%d",
3917                                   i, (lramword & 0x8000) ? 16 : 8);
3918                ASC_PRT_NEXT();
3919
3920                if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
3921                    (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
3922                        len = asc_prt_line(cp, leftlen, "*");
3923                        ASC_PRT_NEXT();
3924                        renegotiate = 1;
3925                }
3926        }
3927        len = asc_prt_line(cp, leftlen, "\n");
3928        ASC_PRT_NEXT();
3929
3930        AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
3931        len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
3932        ASC_PRT_NEXT();
3933        for (i = 0; i <= ADV_MAX_TID; i++) {
3934                if ((chip_scsi_id == i) ||
3935                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
3936                        continue;
3937                }
3938
3939                len = asc_prt_line(cp, leftlen, " %X:%c",
3940                                   i,
3941                                   (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
3942                                   'N');
3943                ASC_PRT_NEXT();
3944        }
3945        len = asc_prt_line(cp, leftlen, "\n");
3946        ASC_PRT_NEXT();
3947
3948        AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
3949        for (i = 0; i <= ADV_MAX_TID; i++) {
3950
3951                AdvReadWordLram(iop_base,
3952                                ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
3953                                lramword);
3954                lramword &= ~0x8000;
3955
3956                if ((chip_scsi_id == i) ||
3957                    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
3958                    ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
3959                        continue;
3960                }
3961
3962                len = asc_prt_line(cp, leftlen, "  %X:", i);
3963                ASC_PRT_NEXT();
3964
3965                if ((lramword & 0x1F) == 0) {   /* Check for REQ/ACK Offset 0. */
3966                        len = asc_prt_line(cp, leftlen, " Asynchronous");
3967                        ASC_PRT_NEXT();
3968                } else {
3969                        len =
3970                            asc_prt_line(cp, leftlen,
3971                                         " Transfer Period Factor: ");
3972                        ASC_PRT_NEXT();
3973
3974                        if ((lramword & 0x1F00) == 0x1100) {    /* 80 Mhz */
3975                                len =
3976                                    asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
3977                                ASC_PRT_NEXT();
3978                        } else if ((lramword & 0x1F00) == 0x1000) {     /* 40 Mhz */
3979                                len =
3980                                    asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
3981                                ASC_PRT_NEXT();
3982                        } else {        /* 20 Mhz or below. */
3983
3984                                period = (((lramword >> 8) * 25) + 50) / 4;
3985
3986                                if (period == 0) {      /* Should never happen. */
3987                                        len =
3988                                            asc_prt_line(cp, leftlen,
3989                                                         "%d (? Mhz), ");
3990                                        ASC_PRT_NEXT();
3991                                } else {
3992                                        len = asc_prt_line(cp, leftlen,
3993                                                           "%d (%d.%d Mhz),",
3994                                                           period, 250 / period,
3995                                                           ASC_TENTHS(250,
3996                                                                      period));
3997                                        ASC_PRT_NEXT();
3998                                }
3999                        }
4000
4001                        len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
4002                                           lramword & 0x1F);
4003                        ASC_PRT_NEXT();
4004                }
4005
4006                if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
4007                        len = asc_prt_line(cp, leftlen, "*\n");
4008                        renegotiate = 1;
4009                } else {
4010                        len = asc_prt_line(cp, leftlen, "\n");
4011                }
4012                ASC_PRT_NEXT();
4013        }
4014
4015        if (renegotiate) {
4016                len = asc_prt_line(cp, leftlen,
4017                                   " * = Re-negotiation pending before next command.\n");
4018                ASC_PRT_NEXT();
4019        }
4020
4021        return totlen;
4022}
4023
4024/*
4025 * asc_proc_copy()
4026 *
4027 * Copy proc information to a read buffer taking into account the current
4028 * read offset in the file and the remaining space in the read buffer.
4029 */
4030static int
4031asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
4032              char *cp, int cplen)
4033{
4034        int cnt = 0;
4035
4036        ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n",
4037                 (unsigned)offset, (unsigned)advoffset, cplen);
4038        if (offset <= advoffset) {
4039                /* Read offset below current offset, copy everything. */
4040                cnt = min(cplen, leftlen);
4041                ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4042                         (ulong)curbuf, (ulong)cp, cnt);
4043                memcpy(curbuf, cp, cnt);
4044        } else if (offset < advoffset + cplen) {
4045                /* Read offset within current range, partial copy. */
4046                cnt = (advoffset + cplen) - offset;
4047                cp = (cp + cplen) - cnt;
4048                cnt = min(cnt, leftlen);
4049                ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n",
4050                         (ulong)curbuf, (ulong)cp, cnt);
4051                memcpy(curbuf, cp, cnt);
4052        }
4053        return cnt;
4054}
4055
4056#ifdef ADVANSYS_STATS
4057/*
4058 * asc_prt_board_stats()
4059 *
4060 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
4061 * cf. asc_prt_line().
4062 *
4063 * Return the number of characters copied into 'cp'. No more than
4064 * 'cplen' characters will be copied to 'cp'.
4065 */
4066static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
4067{
4068        struct asc_board *boardp = shost_priv(shost);
4069        struct asc_stats *s = &boardp->asc_stats;
4070
4071        int leftlen = cplen;
4072        int len, totlen = 0;
4073
4074        len = asc_prt_line(cp, leftlen,
4075                           "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
4076                           shost->host_no);
4077        ASC_PRT_NEXT();
4078
4079        len = asc_prt_line(cp, leftlen,
4080                           " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
4081                           s->queuecommand, s->reset, s->biosparam,
4082                           s->interrupt);
4083        ASC_PRT_NEXT();
4084
4085        len = asc_prt_line(cp, leftlen,
4086                           " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
4087                           s->callback, s->done, s->build_error,
4088                           s->adv_build_noreq, s->adv_build_nosg);
4089        ASC_PRT_NEXT();
4090
4091        len = asc_prt_line(cp, leftlen,
4092                           " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
4093                           s->exe_noerror, s->exe_busy, s->exe_error,
4094                           s->exe_unknown);
4095        ASC_PRT_NEXT();
4096
4097        /*
4098         * Display data transfer statistics.
4099         */
4100        if (s->xfer_cnt > 0) {
4101                len = asc_prt_line(cp, leftlen, " xfer_cnt %lu, xfer_elem %lu, ",
4102                                   s->xfer_cnt, s->xfer_elem);
4103                ASC_PRT_NEXT();
4104
4105                len = asc_prt_line(cp, leftlen, "xfer_bytes %lu.%01lu kb\n",
4106                                   s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2));
4107                ASC_PRT_NEXT();
4108
4109                /* Scatter gather transfer statistics */
4110                len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
4111                                   s->xfer_elem / s->xfer_cnt,
4112                                   ASC_TENTHS(s->xfer_elem, s->xfer_cnt));
4113                ASC_PRT_NEXT();
4114
4115                len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
4116                                   (s->xfer_sect / 2) / s->xfer_elem,
4117                                   ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem));
4118                ASC_PRT_NEXT();
4119
4120                len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
4121                                   (s->xfer_sect / 2) / s->xfer_cnt,
4122                                   ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt));
4123                ASC_PRT_NEXT();
4124        }
4125
4126        return totlen;
4127}
4128#endif /* ADVANSYS_STATS */
4129
4130/*
4131 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
4132 *
4133 * *buffer: I/O buffer
4134 * **start: if inout == FALSE pointer into buffer where user read should start
4135 * offset: current offset into a /proc/scsi/advansys/[0...] file
4136 * length: length of buffer
4137 * hostno: Scsi_Host host_no
4138 * inout: TRUE - user is writing; FALSE - user is reading
4139 *
4140 * Return the number of bytes read from or written to a
4141 * /proc/scsi/advansys/[0...] file.
4142 *
4143 * Note: This function uses the per board buffer 'prtbuf' which is
4144 * allocated when the board is initialized in advansys_detect(). The
4145 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4146 * used to write to the buffer. The way asc_proc_copy() is written
4147 * if 'prtbuf' is too small it will not be overwritten. Instead the
4148 * user just won't get all the available statistics.
4149 */
4150static int
4151advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4152                   off_t offset, int length, int inout)
4153{
4154        struct asc_board *boardp = shost_priv(shost);
4155        char *cp;
4156        int cplen;
4157        int cnt;
4158        int totcnt;
4159        int leftlen;
4160        char *curbuf;
4161        off_t advoffset;
4162
4163        ASC_DBG(1, "begin\n");
4164
4165        /*
4166         * User write not supported.
4167         */
4168        if (inout == TRUE)
4169                return -ENOSYS;
4170
4171        /*
4172         * User read of /proc/scsi/advansys/[0...] file.
4173         */
4174
4175        /* Copy read data starting at the beginning of the buffer. */
4176        *start = buffer;
4177        curbuf = buffer;
4178        advoffset = 0;
4179        totcnt = 0;
4180        leftlen = length;
4181
4182        /*
4183         * Get board configuration information.
4184         *
4185         * advansys_info() returns the board string from its own static buffer.
4186         */
4187        cp = (char *)advansys_info(shost);
4188        strcat(cp, "\n");
4189        cplen = strlen(cp);
4190        /* Copy board information. */
4191        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4192        totcnt += cnt;
4193        leftlen -= cnt;
4194        if (leftlen == 0) {
4195                ASC_DBG(1, "totcnt %d\n", totcnt);
4196                return totcnt;
4197        }
4198        advoffset += cplen;
4199        curbuf += cnt;
4200
4201        /*
4202         * Display Wide Board BIOS Information.
4203         */
4204        if (!ASC_NARROW_BOARD(boardp)) {
4205                cp = boardp->prtbuf;
4206                cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4207                BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4208                cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4209                                  cplen);
4210                totcnt += cnt;
4211                leftlen -= cnt;
4212                if (leftlen == 0) {
4213                        ASC_DBG(1, "totcnt %d\n", totcnt);
4214                        return totcnt;
4215                }
4216                advoffset += cplen;
4217                curbuf += cnt;
4218        }
4219
4220        /*
4221         * Display driver information for each device attached to the board.
4222         */
4223        cp = boardp->prtbuf;
4224        cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4225        BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4226        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4227        totcnt += cnt;
4228        leftlen -= cnt;
4229        if (leftlen == 0) {
4230                ASC_DBG(1, "totcnt %d\n", totcnt);
4231                return totcnt;
4232        }
4233        advoffset += cplen;
4234        curbuf += cnt;
4235
4236        /*
4237         * Display EEPROM configuration for the board.
4238         */
4239        cp = boardp->prtbuf;
4240        if (ASC_NARROW_BOARD(boardp)) {
4241                cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4242        } else {
4243                cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4244        }
4245        BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4246        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4247        totcnt += cnt;
4248        leftlen -= cnt;
4249        if (leftlen == 0) {
4250                ASC_DBG(1, "totcnt %d\n", totcnt);
4251                return totcnt;
4252        }
4253        advoffset += cplen;
4254        curbuf += cnt;
4255
4256        /*
4257         * Display driver configuration and information for the board.
4258         */
4259        cp = boardp->prtbuf;
4260        cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4261        BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4262        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4263        totcnt += cnt;
4264        leftlen -= cnt;
4265        if (leftlen == 0) {
4266                ASC_DBG(1, "totcnt %d\n", totcnt);
4267                return totcnt;
4268        }
4269        advoffset += cplen;
4270        curbuf += cnt;
4271
4272#ifdef ADVANSYS_STATS
4273        /*
4274         * Display driver statistics for the board.
4275         */
4276        cp = boardp->prtbuf;
4277        cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4278        BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4279        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4280        totcnt += cnt;
4281        leftlen -= cnt;
4282        if (leftlen == 0) {
4283                ASC_DBG(1, "totcnt %d\n", totcnt);
4284                return totcnt;
4285        }
4286        advoffset += cplen;
4287        curbuf += cnt;
4288#endif /* ADVANSYS_STATS */
4289
4290        /*
4291         * Display Asc Library dynamic configuration information
4292         * for the board.
4293         */
4294        cp = boardp->prtbuf;
4295        if (ASC_NARROW_BOARD(boardp)) {
4296                cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4297        } else {
4298                cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4299        }
4300        BUG_ON(cplen >= ASC_PRTBUF_SIZE);
4301        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4302        totcnt += cnt;
4303        leftlen -= cnt;
4304        if (leftlen == 0) {
4305                ASC_DBG(1, "totcnt %d\n", totcnt);
4306                return totcnt;
4307        }
4308        advoffset += cplen;
4309        curbuf += cnt;
4310
4311        ASC_DBG(1, "totcnt %d\n", totcnt);
4312
4313        return totcnt;
4314}
4315#endif /* CONFIG_PROC_FS */
4316
4317static void asc_scsi_done(struct scsi_cmnd *scp)
4318{
4319        scsi_dma_unmap(scp);
4320        ASC_STATS(scp->device->host, done);
4321        scp->scsi_done(scp);
4322}
4323
4324static void AscSetBank(PortAddr iop_base, uchar bank)
4325{
4326        uchar val;
4327
4328        val = AscGetChipControl(iop_base) &
4329            (~
4330             (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
4331              CC_CHIP_RESET));
4332        if (bank == 1) {
4333                val |= CC_BANK_ONE;
4334        } else if (bank == 2) {
4335                val |= CC_DIAG | CC_BANK_ONE;
4336        } else {
4337                val &= ~CC_BANK_ONE;
4338        }
4339        AscSetChipControl(iop_base, val);
4340}
4341
4342static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
4343{
4344        AscSetBank(iop_base, 1);
4345        AscWriteChipIH(iop_base, ins_code);
4346        AscSetBank(iop_base, 0);
4347}
4348
4349static int AscStartChip(PortAddr iop_base)
4350{
4351        AscSetChipControl(iop_base, 0);
4352        if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4353                return (0);
4354        }
4355        return (1);
4356}
4357
4358static int AscStopChip(PortAddr iop_base)
4359{
4360        uchar cc_val;
4361
4362        cc_val =
4363            AscGetChipControl(iop_base) &
4364            (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
4365        AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
4366        AscSetChipIH(iop_base, INS_HALT);
4367        AscSetChipIH(iop_base, INS_RFLAG_WTM);
4368        if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
4369                return (0);
4370        }
4371        return (1);
4372}
4373
4374static int AscIsChipHalted(PortAddr iop_base)
4375{
4376        if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
4377                if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
4378                        return (1);
4379                }
4380        }
4381        return (0);
4382}
4383
4384static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
4385{
4386        PortAddr iop_base;
4387        int i = 10;
4388
4389        iop_base = asc_dvc->iop_base;
4390        while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
4391               && (i-- > 0)) {
4392                mdelay(100);
4393        }
4394        AscStopChip(iop_base);
4395        AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
4396        udelay(60);
4397        AscSetChipIH(iop_base, INS_RFLAG_WTM);
4398        AscSetChipIH(iop_base, INS_HALT);
4399        AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
4400        AscSetChipControl(iop_base, CC_HALT);
4401        mdelay(200);
4402        AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
4403        AscSetChipStatus(iop_base, 0);
4404        return (AscIsChipHalted(iop_base));
4405}
4406
4407static int AscFindSignature(PortAddr iop_base)
4408{
4409        ushort sig_word;
4410
4411        ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n",
4412                 iop_base, AscGetChipSignatureByte(iop_base));
4413        if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
4414                ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n",
4415                         iop_base, AscGetChipSignatureWord(iop_base));
4416                sig_word = AscGetChipSignatureWord(iop_base);
4417                if ((sig_word == (ushort)ASC_1000_ID0W) ||
4418                    (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
4419                        return (1);
4420                }
4421        }
4422        return (0);
4423}
4424
4425static void AscEnableInterrupt(PortAddr iop_base)
4426{
4427        ushort cfg;
4428
4429        cfg = AscGetChipCfgLsw(iop_base);
4430        AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
4431}
4432
4433static void AscDisableInterrupt(PortAddr iop_base)
4434{
4435        ushort cfg;
4436
4437        cfg = AscGetChipCfgLsw(iop_base);
4438        AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
4439}
4440
4441static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
4442{
4443        unsigned char byte_data;
4444        unsigned short word_data;
4445
4446        if (isodd_word(addr)) {
4447                AscSetChipLramAddr(iop_base, addr - 1);
4448                word_data = AscGetChipLramData(iop_base);
4449                byte_data = (word_data >> 8) & 0xFF;
4450        } else {
4451                AscSetChipLramAddr(iop_base, addr);
4452                word_data = AscGetChipLramData(iop_base);
4453                byte_data = word_data & 0xFF;
4454        }
4455        return byte_data;
4456}
4457
4458static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
4459{
4460        ushort word_data;
4461
4462        AscSetChipLramAddr(iop_base, addr);
4463        word_data = AscGetChipLramData(iop_base);
4464        return (word_data);
4465}
4466
4467#if CC_VERY_LONG_SG_LIST
4468static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
4469{
4470        ushort val_low, val_high;
4471        ASC_DCNT dword_data;
4472
4473        AscSetChipLramAddr(iop_base, addr);
4474        val_low = AscGetChipLramData(iop_base);
4475        val_high = AscGetChipLramData(iop_base);
4476        dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
4477        return (dword_data);
4478}
4479#endif /* CC_VERY_LONG_SG_LIST */
4480
4481static void
4482AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
4483{
4484        int i;
4485
4486        AscSetChipLramAddr(iop_base, s_addr);
4487        for (i = 0; i < words; i++) {
4488                AscSetChipLramData(iop_base, set_wval);
4489        }
4490}
4491
4492static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
4493{
4494        AscSetChipLramAddr(iop_base, addr);
4495        AscSetChipLramData(iop_base, word_val);
4496}
4497
4498static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
4499{
4500        ushort word_data;
4501
4502        if (isodd_word(addr)) {
4503                addr--;
4504                word_data = AscReadLramWord(iop_base, addr);
4505                word_data &= 0x00FF;
4506                word_data |= (((ushort)byte_val << 8) & 0xFF00);
4507        } else {
4508                word_data = AscReadLramWord(iop_base, addr);
4509                word_data &= 0xFF00;
4510                word_data |= ((ushort)byte_val & 0x00FF);
4511        }
4512        AscWriteLramWord(iop_base, addr, word_data);
4513}
4514
4515/*
4516 * Copy 2 bytes to LRAM.
4517 *
4518 * The source data is assumed to be in little-endian order in memory
4519 * and is maintained in little-endian order when written to LRAM.
4520 */
4521static void
4522AscMemWordCopyPtrToLram(PortAddr iop_base,
4523                        ushort s_addr, uchar *s_buffer, int words)
4524{
4525        int i;
4526
4527        AscSetChipLramAddr(iop_base, s_addr);
4528        for (i = 0; i < 2 * words; i += 2) {
4529                /*
4530                 * On a little-endian system the second argument below
4531                 * produces a little-endian ushort which is written to
4532                 * LRAM in little-endian order. On a big-endian system
4533                 * the second argument produces a big-endian ushort which
4534                 * is "transparently" byte-swapped by outpw() and written
4535                 * in little-endian order to LRAM.
4536                 */
4537                outpw(iop_base + IOP_RAM_DATA,
4538                      ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
4539        }
4540}
4541
4542/*
4543 * Copy 4 bytes to LRAM.
4544 *
4545 * The source data is assumed to be in little-endian order in memory
4546 * and is maintained in little-endian order when writen to LRAM.
4547 */
4548static void
4549AscMemDWordCopyPtrToLram(PortAddr iop_base,
4550                         ushort s_addr, uchar *s_buffer, int dwords)
4551{
4552        int i;
4553
4554        AscSetChipLramAddr(iop_base, s_addr);
4555        for (i = 0; i < 4 * dwords; i += 4) {
4556                outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);   /* LSW */
4557                outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);       /* MSW */
4558        }
4559}
4560
4561/*
4562 * Copy 2 bytes from LRAM.
4563 *
4564 * The source data is assumed to be in little-endian order in LRAM
4565 * and is maintained in little-endian order when written to memory.
4566 */
4567static void
4568AscMemWordCopyPtrFromLram(PortAddr iop_base,
4569                          ushort s_addr, uchar *d_buffer, int words)
4570{
4571        int i;
4572        ushort word;
4573
4574        AscSetChipLramAddr(iop_base, s_addr);
4575        for (i = 0; i < 2 * words; i += 2) {
4576                word = inpw(iop_base + IOP_RAM_DATA);
4577                d_buffer[i] = word & 0xff;
4578                d_buffer[i + 1] = (word >> 8) & 0xff;
4579        }
4580}
4581
4582static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
4583{
4584        ASC_DCNT sum;
4585        int i;
4586
4587        sum = 0L;
4588        for (i = 0; i < words; i++, s_addr += 2) {
4589                sum += AscReadLramWord(iop_base, s_addr);
4590        }
4591        return (sum);
4592}
4593
4594static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
4595{
4596        uchar i;
4597        ushort s_addr;
4598        PortAddr iop_base;
4599        ushort warn_code;
4600
4601        iop_base = asc_dvc->iop_base;
4602        warn_code = 0;
4603        AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
4604                          (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
4605                                    64) >> 1));
4606        i = ASC_MIN_ACTIVE_QNO;
4607        s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
4608        AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4609                         (uchar)(i + 1));
4610        AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4611                         (uchar)(asc_dvc->max_total_qng));
4612        AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4613                         (uchar)i);
4614        i++;
4615        s_addr += ASC_QBLK_SIZE;
4616        for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
4617                AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4618                                 (uchar)(i + 1));
4619                AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4620                                 (uchar)(i - 1));
4621                AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4622                                 (uchar)i);
4623        }
4624        AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
4625                         (uchar)ASC_QLINK_END);
4626        AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
4627                         (uchar)(asc_dvc->max_total_qng - 1));
4628        AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
4629                         (uchar)asc_dvc->max_total_qng);
4630        i++;
4631        s_addr += ASC_QBLK_SIZE;
4632        for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
4633             i++, s_addr += ASC_QBLK_SIZE) {
4634                AscWriteLramByte(iop_base,
4635                                 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
4636                AscWriteLramByte(iop_base,
4637                                 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
4638                AscWriteLramByte(iop_base,
4639                                 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
4640        }
4641        return warn_code;
4642}
4643
4644static ASC_DCNT
4645AscLoadMicroCode(PortAddr iop_base,
4646                 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
4647{
4648        ASC_DCNT chksum;
4649        ushort mcode_word_size;
4650        ushort mcode_chksum;
4651
4652        /* Write the microcode buffer starting at LRAM address 0. */
4653        mcode_word_size = (ushort)(mcode_size >> 1);
4654        AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
4655        AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
4656
4657        chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
4658        ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum);
4659        mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
4660                                                 (ushort)ASC_CODE_SEC_BEG,
4661                                                 (ushort)((mcode_size -
4662                                                           s_addr - (ushort)
4663                                                           ASC_CODE_SEC_BEG) /
4664                                                          2));
4665        ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum);
4666        AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
4667        AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
4668        return chksum;
4669}
4670
4671/* Microcode buffer is kept after initialization for error recovery. */
4672static uchar _asc_mcode_buf[] = {
4673        0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4674        0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
4675        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4676        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4677        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4678        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
4679        0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680        0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4681        0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
4682        0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
4683        0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
4684        0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
4685        0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
4686        0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
4687        0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
4688        0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
4689        0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
4690        0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
4691        0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
4692        0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
4693        0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
4694        0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
4695        0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
4696        0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
4697        0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
4698        0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
4699        0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
4700        0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
4701        0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
4702        0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
4703        0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
4704        0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
4705        0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
4706        0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
4707        0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
4708        0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
4709        0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
4710        0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
4711        0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
4712        0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
4713        0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
4714        0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
4715        0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
4716        0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
4717        0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
4718        0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
4719        0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
4720        0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
4721        0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
4722        0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
4723        0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
4724        0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
4725        0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
4726        0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
4727        0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
4728        0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
4729        0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
4730        0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
4731        0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
4732        0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
4733        0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
4734        0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
4735        0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
4736        0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
4737        0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
4738        0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
4739        0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
4740        0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
4741        0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
4742        0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
4743        0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
4744        0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
4745        0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
4746        0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
4747        0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
4748        0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
4749        0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
4750        0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
4751        0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4752        0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
4753        0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
4754        0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
4755        0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
4756        0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
4757        0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
4758        0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
4759        0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
4760        0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
4761        0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
4762        0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
4763        0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
4764        0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
4765        0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
4766        0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
4767        0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
4768        0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
4769        0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
4770        0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
4771        0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
4772        0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
4773        0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
4774        0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
4775        0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
4776        0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
4777        0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
4778        0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
4779        0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
4780        0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
4781        0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
4782        0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
4783        0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
4784        0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
4785        0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
4786        0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
4787        0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
4788        0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
4789        0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
4790        0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
4791        0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
4792        0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
4793        0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
4794        0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
4795        0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
4796        0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
4797        0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
4798        0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
4799        0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
4800        0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
4801        0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
4802        0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
4803        0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
4804        0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
4805        0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
4806        0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
4807        0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
4808        0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
4809        0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
4810        0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
4811        0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
4812        0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
4813        0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
4814        0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
4815        0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
4816        0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
4817        0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
4818        0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
4819        0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
4820        0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
4821        0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
4822        0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
4823        0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
4824        0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
4825        0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
4826        0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
4827        0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
4828        0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
4829        0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
4830        0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
4831        0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
4832        0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
4833        0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
4834        0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
4835        0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
4836        0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
4837        0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
4838        0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
4839        0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
4840        0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
4841        0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
4842        0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
4843        0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
4844        0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
4845        0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
4846        0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
4847        0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
4848        0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
4849        0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
4850        0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
4851        0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
4852        0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
4853        0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
4854        0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
4855        0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
4856        0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
4857        0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
4858        0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
4859        0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
4860        0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
4861        0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
4862        0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
4863        0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
4864        0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
4865};
4866
4867static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
4868static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
4869
4870/* Microcode buffer is kept after initialization for error recovery. */
4871static unsigned char _adv_asc3550_buf[] = {
4872        0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
4873        0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
4874        0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
4875        0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
4876        0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
4877        0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
4878        0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
4879        0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
4880        0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
4881        0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
4882        0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
4883        0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
4884        0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
4885        0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
4886        0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
4887        0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
4888        0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
4889        0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
4890        0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
4891        0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
4892        0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
4893        0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
4894        0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
4895        0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
4896        0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
4897        0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
4898        0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
4899        0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
4900        0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
4901        0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
4902        0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
4903        0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
4904        0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
4905        0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
4906        0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
4907        0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
4908        0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
4909        0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
4910        0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
4911        0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
4912        0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
4913        0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
4914        0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
4915        0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
4916        0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
4917        0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
4918        0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
4919        0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
4920        0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
4921        0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
4922        0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
4923        0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
4924        0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
4925        0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
4926        0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
4927        0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
4928        0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
4929        0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
4930        0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
4931        0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
4932        0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
4933        0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
4934        0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
4935        0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
4936        0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
4937        0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
4938        0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
4939        0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
4940        0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
4941        0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
4942        0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
4943        0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
4944        0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
4945        0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
4946        0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
4947        0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
4948        0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
4949        0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
4950        0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
4951        0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
4952        0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
4953        0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
4954        0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
4955        0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
4956        0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
4957        0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
4958        0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
4959        0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
4960        0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
4961        0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
4962        0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
4963        0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
4964        0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
4965        0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
4966        0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
4967        0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
4968        0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
4969        0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
4970        0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
4971        0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
4972        0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
4973        0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
4974        0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
4975        0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
4976        0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
4977        0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
4978        0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
4979        0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
4980        0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
4981        0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
4982        0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
4983        0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
4984        0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
4985        0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
4986        0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
4987        0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
4988        0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
4989        0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
4990        0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
4991        0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
4992        0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
4993        0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
4994        0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
4995        0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
4996        0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
4997        0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
4998        0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
4999        0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
5000        0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
5001        0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
5002        0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
5003        0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
5004        0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
5005        0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
5006        0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
5007        0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
5008        0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
5009        0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
5010        0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
5011        0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
5012        0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
5013        0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
5014        0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
5015        0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
5016        0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
5017        0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5018        0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
5019        0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
5020        0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
5021        0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
5022        0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
5023        0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
5024        0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
5025        0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
5026        0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
5027        0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
5028        0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
5029        0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
5030        0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
5031        0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
5032        0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
5033        0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
5034        0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
5035        0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
5036        0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
5037        0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5038        0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
5039        0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
5040        0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
5041        0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
5042        0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
5043        0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
5044        0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
5045        0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
5046        0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
5047        0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
5048        0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
5049        0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
5050        0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
5051        0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
5052        0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
5053        0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
5054        0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
5055        0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
5056        0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
5057        0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
5058        0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
5059        0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
5060        0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
5061        0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
5062        0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
5063        0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
5064        0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
5065        0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
5066        0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
5067        0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
5068        0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
5069        0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
5070        0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
5071        0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
5072        0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
5073        0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
5074        0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
5075        0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
5076        0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
5077        0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
5078        0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
5079        0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
5080        0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
5081        0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
5082        0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
5083        0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
5084        0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
5085        0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
5086        0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
5087        0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
5088        0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
5089        0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
5090        0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
5091        0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
5092        0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
5093        0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
5094        0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
5095        0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
5096        0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
5097        0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
5098        0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
5099        0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
5100        0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
5101        0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
5102        0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
5103        0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
5104        0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
5105        0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
5106        0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
5107        0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
5108        0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
5109        0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
5110        0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
5111        0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
5112        0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
5113        0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
5114        0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
5115        0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
5116        0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
5117        0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
5118        0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
5119        0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5120        0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
5121        0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
5122        0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
5123        0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
5124        0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5125        0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
5126        0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5127        0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
5128        0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
5129        0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
5130        0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5131        0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
5132        0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5133        0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
5134        0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5135        0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
5136        0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5137        0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
5138        0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
5139        0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
5140        0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
5141        0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
5142        0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5143        0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
5144        0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
5145        0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
5146        0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
5147        0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
5148        0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
5149        0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
5150        0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
5151        0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
5152        0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
5153        0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
5154        0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
5155        0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
5156        0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
5157        0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
5158        0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
5159        0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
5160        0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
5161        0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
5162        0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
5163        0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
5164        0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
5165        0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
5166        0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
5167        0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
5168        0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
5169        0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
5170        0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
5171        0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
5172        0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
5173        0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
5174        0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
5175        0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
5176        0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
5177        0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
5178        0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
5179        0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
5180        0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
5181        0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
5182        0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
5183        0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
5184        0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
5185        0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
5186        0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
5187        0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
5188        0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
5189        0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
5190        0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
5191        0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
5192        0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
5193        0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
5194        0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
5195        0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
5196        0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5197        0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
5198        0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
5199        0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
5200        0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
5201        0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
5202        0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
5203        0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
5204        0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
5205        0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
5206        0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
5207        0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
5208        0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
5209        0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
5210        0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
5211        0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
5212        0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
5213        0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
5214        0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
5215        0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
5216        0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
5217        0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
5218        0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
5219        0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
5220        0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
5221        0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
5222        0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
5223        0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
5224        0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
5225        0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
5226        0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
5227        0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
5228        0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
5229        0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
5230        0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
5231        0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
5232        0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
5233        0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
5234        0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
5235        0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
5236        0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
5237        0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
5238        0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
5239        0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
5240        0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
5241        0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
5242        0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
5243        0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
5244        0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
5245        0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
5246        0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
5247        0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
5248        0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
5249        0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
5250        0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
5251        0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
5252        0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
5253        0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
5254        0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
5255        0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
5256        0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
5257        0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
5258        0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
5259        0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
5260        0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
5261        0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
5262        0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
5263        0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
5264        0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
5265        0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
5266        0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
5267        0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
5268        0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
5269        0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
5270        0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
5271        0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
5272        0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
5273        0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
5274        0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
5275        0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
5276        0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
5277        0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
5278        0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
5279        0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
5280        0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
5281        0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
5282        0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
5283        0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
5284        0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
5285        0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
5286        0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
5287        0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
5288        0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
5289        0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
5290        0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
5291};
5292
5293static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf);     /* 0x13AD */
5294static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL;     /* Expanded little-endian checksum. */
5295
5296/* Microcode buffer is kept after initialization for error recovery. */
5297static unsigned char _adv_asc38C0800_buf[] = {
5298        0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
5299        0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
5300        0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
5301        0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
5302        0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
5303        0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
5304        0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
5305        0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
5306        0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
5307        0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
5308        0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
5309        0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
5310        0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
5311        0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
5312        0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
5313        0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
5314        0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
5315        0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
5316        0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
5317        0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
5318        0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
5319        0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
5320        0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
5321        0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
5322        0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
5323        0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
5324        0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
5325        0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
5326        0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
5327        0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
5328        0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
5329        0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
5330        0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
5331        0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
5332        0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
5333        0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
5334        0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
5335        0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
5336        0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
5337        0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
5338        0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
5339        0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
5340        0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
5341        0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
5342        0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5343        0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
5344        0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5345        0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
5346        0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5347        0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
5348        0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
5349        0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
5350        0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
5351        0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
5352        0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
5353        0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
5354        0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
5355        0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
5356        0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
5357        0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
5358        0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
5359        0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
5360        0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
5361        0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
5362        0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
5363        0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
5364        0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
5365        0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
5366        0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
5367        0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
5368        0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
5369        0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
5370        0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
5371        0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
5372        0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
5373        0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
5374        0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
5375        0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
5376        0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
5377        0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
5378        0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
5379        0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
5380        0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
5381        0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
5382        0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
5383        0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
5384        0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
5385        0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
5386        0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
5387        0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
5388        0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
5389        0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
5390        0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
5391        0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
5392        0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
5393        0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
5394        0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
5395        0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
5396        0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
5397        0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
5398        0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5399        0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
5400        0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
5401        0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
5402        0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
5403        0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
5404        0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
5405        0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
5406        0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
5407        0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
5408        0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
5409        0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
5410        0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
5411        0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
5412        0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
5413        0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
5414        0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
5415        0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
5416        0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
5417        0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
5418        0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
5419        0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
5420        0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
5421        0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
5422        0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
5423        0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
5424        0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
5425        0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
5426        0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
5427        0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
5428        0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
5429        0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
5430        0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
5431        0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
5432        0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
5433        0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
5434        0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
5435        0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
5436        0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
5437        0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
5438        0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
5439        0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
5440        0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
5441        0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
5442        0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
5443        0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
5444        0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
5445        0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
5446        0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
5447        0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
5448        0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
5449        0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
5450        0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
5451        0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
5452        0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
5453        0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
5454        0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
5455        0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
5456        0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
5457        0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
5458        0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
5459        0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
5460        0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
5461        0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
5462        0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
5463        0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
5464        0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
5465        0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
5466        0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
5467        0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
5468        0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
5469        0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
5470        0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
5471        0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
5472        0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
5473        0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
5474        0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
5475        0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
5476        0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
5477        0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
5478        0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
5479        0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
5480        0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
5481        0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
5482        0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
5483        0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
5484        0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
5485        0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
5486        0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
5487        0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
5488        0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
5489        0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
5490        0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
5491        0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
5492        0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
5493        0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
5494        0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
5495        0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
5496        0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
5497        0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
5498        0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
5499        0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
5500        0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
5501        0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
5502        0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
5503        0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
5504        0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
5505        0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
5506        0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
5507        0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
5508        0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
5509        0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
5510        0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
5511        0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
5512        0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
5513        0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
5514        0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
5515        0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
5516        0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
5517        0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
5518        0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
5519        0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
5520        0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
5521        0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
5522        0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
5523        0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
5524        0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
5525        0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
5526        0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
5527        0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
5528        0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
5529        0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
5530        0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
5531        0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
5532        0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
5533        0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
5534        0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
5535        0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
5536        0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
5537        0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
5538        0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
5539        0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
5540        0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
5541        0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
5542        0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
5543        0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
5544        0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
5545        0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
5546        0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
5547        0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
5548        0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
5549        0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
5550        0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
5551        0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
5552        0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
5553        0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
5554        0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
5555        0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
5556        0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
5557        0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
5558        0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
5559        0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
5560        0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
5561        0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
5562        0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
5563        0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
5564        0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
5565        0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
5566        0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
5567        0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
5568        0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
5569        0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
5570        0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
5571        0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
5572        0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
5573        0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
5574        0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
5575        0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
5576        0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
5577        0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
5578        0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
5579        0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
5580        0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
5581        0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
5582        0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
5583        0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
5584        0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
5585        0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
5586        0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
5587        0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
5588        0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
5589        0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
5590        0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
5591        0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
5592        0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
5593        0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
5594        0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
5595        0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
5596        0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
5597        0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
5598        0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
5599        0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
5600        0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
5601        0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
5602        0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
5603        0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
5604        0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
5605        0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
5606        0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
5607        0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
5608        0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
5609        0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
5610        0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
5611        0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
5612        0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
5613        0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
5614        0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
5615        0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
5616        0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
5617        0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
5618        0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
5619        0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
5620        0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
5621        0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
5622        0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
5623        0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
5624        0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
5625        0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
5626        0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
5627        0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
5628        0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
5629        0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
5630        0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
5631        0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
5632        0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
5633        0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
5634        0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
5635        0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
5636        0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
5637        0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
5638        0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
5639        0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
5640        0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
5641        0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
5642        0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
5643        0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
5644        0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5645        0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
5646        0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
5647        0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
5648        0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
5649        0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
5650        0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
5651        0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
5652        0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
5653        0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
5654        0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
5655        0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
5656        0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
5657        0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
5658        0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
5659        0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
5660        0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
5661        0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
5662        0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
5663        0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
5664        0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
5665        0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
5666        0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
5667        0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
5668        0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
5669        0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
5670        0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
5671        0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
5672        0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
5673        0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
5674        0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5675        0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
5676        0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
5677        0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
5678        0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
5679        0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
5680        0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
5681        0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
5682        0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
5683        0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
5684        0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
5685        0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
5686        0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
5687        0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
5688        0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
5689        0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
5690        0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
5691        0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
5692        0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
5693        0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
5694        0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
5695        0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
5696        0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
5697        0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
5698        0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
5699        0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
5700        0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
5701        0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
5702        0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
5703        0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
5704        0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
5705        0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
5706        0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
5707        0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
5708        0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
5709        0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
5710        0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
5711        0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
5712        0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
5713        0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
5714        0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
5715        0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
5716        0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
5717        0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
5718        0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
5719        0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
5720        0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
5721        0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
5722        0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
5723        0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
5724        0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
5725        0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
5726        0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
5727        0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
5728        0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
5729        0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
5730        0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
5731        0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
5732        0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
5733        0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
5734        0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
5735        0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
5736        0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
5737        0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
5738        0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
5739        0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
5740        0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
5741        0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
5742        0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
5743};
5744
5745static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf);       /* 0x14E1 */
5746static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL;  /* Expanded little-endian checksum. */
5747
5748/* Microcode buffer is kept after initialization for error recovery. */
5749static unsigned char _adv_asc38C1600_buf[] = {
5750        0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
5751        0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
5752        0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
5753        0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
5754        0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
5755        0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
5756        0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
5757        0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
5758        0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
5759        0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
5760        0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
5761        0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
5762        0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
5763        0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
5764        0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
5765        0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
5766        0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
5767        0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
5768        0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
5769        0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
5770        0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
5771        0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
5772        0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
5773        0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
5774        0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
5775        0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
5776        0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
5777        0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
5778        0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
5779        0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
5780        0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
5781        0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
5782        0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
5783        0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
5784        0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
5785        0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
5786        0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
5787        0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
5788        0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
5789        0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
5790        0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
5791        0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
5792        0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
5793        0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
5794        0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
5795        0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
5796        0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
5797        0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
5798        0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
5799        0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
5800        0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
5801        0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
5802        0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
5803        0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
5804        0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
5805        0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
5806        0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
5807        0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
5808        0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
5809        0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
5810        0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
5811        0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
5812        0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
5813        0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
5814        0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
5815        0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
5816        0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
5817        0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
5818        0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
5819        0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
5820        0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
5821        0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
5822        0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
5823        0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
5824        0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
5825        0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
5826        0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
5827        0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
5828        0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
5829        0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
5830        0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
5831        0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
5832        0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
5833        0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
5834        0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
5835        0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
5836        0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
5837        0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
5838        0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
5839        0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
5840        0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
5841        0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
5842        0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
5843        0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
5844        0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
5845        0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
5846        0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
5847        0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
5848        0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
5849        0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
5850        0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
5851        0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
5852        0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
5853        0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
5854        0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
5855        0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
5856        0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
5857        0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
5858        0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
5859        0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
5860        0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
5861        0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
5862        0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
5863        0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
5864        0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
5865        0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
5866        0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
5867        0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
5868        0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
5869        0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
5870        0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
5871        0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
5872        0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
5873        0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
5874        0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
5875        0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
5876        0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
5877        0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
5878        0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
5879        0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
5880        0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
5881        0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
5882        0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
5883        0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
5884        0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
5885        0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
5886        0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
5887        0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
5888        0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
5889        0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
5890        0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
5891        0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
5892        0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
5893        0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
5894        0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
5895        0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
5896        0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
5897        0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
5898        0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
5899        0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
5900        0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
5901        0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
5902        0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
5903        0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
5904        0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
5905        0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
5906        0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
5907        0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
5908        0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
5909        0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
5910        0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
5911        0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
5912        0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
5913        0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
5914        0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
5915        0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
5916        0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
5917        0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
5918        0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
5919        0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
5920        0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
5921        0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
5922        0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
5923        0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
5924        0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
5925        0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
5926        0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
5927        0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
5928        0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
5929        0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
5930        0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
5931        0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
5932        0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
5933        0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
5934        0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
5935        0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
5936        0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
5937        0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
5938        0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
5939        0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
5940        0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
5941        0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
5942        0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
5943        0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
5944        0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
5945        0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
5946        0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
5947        0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
5948        0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
5949        0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
5950        0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
5951        0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
5952        0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
5953        0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
5954        0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
5955        0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
5956        0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
5957        0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
5958        0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
5959        0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
5960        0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
5961        0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
5962        0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
5963        0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
5964        0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
5965        0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
5966        0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
5967        0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
5968        0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
5969        0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
5970        0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
5971        0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
5972        0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
5973        0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
5974        0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
5975        0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
5976        0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
5977        0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
5978        0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
5979        0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
5980        0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
5981        0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
5982        0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
5983        0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
5984        0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
5985        0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
5986        0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
5987        0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
5988        0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
5989        0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
5990        0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
5991        0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
5992        0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
5993        0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
5994        0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
5995        0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
5996        0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
5997        0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
5998        0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
5999        0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
6000        0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
6001        0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
6002        0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
6003        0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
6004        0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
6005        0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
6006        0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
6007        0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
6008        0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
6009        0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
6010        0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
6011        0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
6012        0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
6013        0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
6014        0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
6015        0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
6016        0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
6017        0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
6018        0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
6019        0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
6020        0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
6021        0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
6022        0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
6023        0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
6024        0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
6025        0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
6026        0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
6027        0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
6028        0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
6029        0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
6030        0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
6031        0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
6032        0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
6033        0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
6034        0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
6035        0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
6036        0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
6037        0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
6038        0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
6039        0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
6040        0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
6041        0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
6042        0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
6043        0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
6044        0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
6045        0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
6046        0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
6047        0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
6048        0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
6049        0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
6050        0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
6051        0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
6052        0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
6053        0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
6054        0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
6055        0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
6056        0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
6057        0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
6058        0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
6059        0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
6060        0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
6061        0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
6062        0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
6063        0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
6064        0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
6065        0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
6066        0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
6067        0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
6068        0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
6069        0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
6070        0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
6071        0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
6072        0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
6073        0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
6074        0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
6075        0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
6076        0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
6077        0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
6078        0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
6079        0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
6080        0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
6081        0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
6082        0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
6083        0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
6084        0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
6085        0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
6086        0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
6087        0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6088        0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
6089        0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
6090        0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
6091        0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
6092        0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
6093        0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
6094        0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
6095        0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
6096        0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
6097        0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
6098        0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
6099        0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
6100        0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
6101        0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
6102        0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
6103        0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
6104        0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
6105        0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
6106        0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
6107        0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
6108        0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
6109        0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
6110        0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
6111        0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
6112        0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
6113        0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
6114        0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
6115        0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
6116        0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
6117        0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
6118        0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
6119        0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
6120        0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
6121        0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
6122        0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
6123        0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
6124        0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
6125        0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
6126        0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6127        0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
6128        0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
6129        0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
6130        0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
6131        0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
6132        0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
6133        0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
6134        0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
6135        0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
6136        0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
6137        0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
6138        0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
6139        0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
6140        0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
6141        0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
6142        0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
6143        0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
6144        0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
6145        0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
6146        0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
6147        0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
6148        0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
6149        0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
6150        0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
6151        0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
6152        0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
6153        0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
6154        0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
6155        0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
6156        0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
6157        0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
6158        0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
6159        0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
6160        0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
6161        0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
6162        0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
6163        0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
6164        0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
6165        0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
6166        0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
6167        0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
6168        0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
6169        0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
6170        0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
6171        0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
6172        0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
6173        0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
6174        0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
6175        0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
6176        0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
6177        0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
6178        0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
6179        0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
6180        0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
6181        0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
6182        0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
6183        0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
6184        0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6185        0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
6186        0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
6187        0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
6188        0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
6189        0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
6190        0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
6191        0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
6192        0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
6193        0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
6194        0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
6195        0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
6196        0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
6197        0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
6198        0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
6199        0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
6200        0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
6201        0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
6202        0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
6203        0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
6204        0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
6205        0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
6206        0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
6207        0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
6208        0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
6209        0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
6210        0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
6211        0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
6212        0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
6213        0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
6214        0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
6215        0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
6216        0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
6217        0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
6218        0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
6219        0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
6220        0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
6221        0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
6222        0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
6223        0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
6224        0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
6225        0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
6226        0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
6227        0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
6228        0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
6229        0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
6230        0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
6231        0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
6232        0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
6233        0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
6234        0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
6235        0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
6236        0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
6237        0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
6238        0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
6239        0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
6240        0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
6241        0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
6242        0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
6243        0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
6244        0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
6245        0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
6246        0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
6247        0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
6248        0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
6249        0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
6250        0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
6251        0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
6252        0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
6253        0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
6254        0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
6255        0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
6256        0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
6257        0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
6258        0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
6259        0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
6260        0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
6261        0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
6262        0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
6263        0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
6264        0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
6265        0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
6266        0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
6267        0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
6268        0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
6269        0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6270        0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6271        0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6272        0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6273        0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
6274        0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
6275        0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
6276        0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
6277        0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
6278};
6279
6280static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf);       /* 0x1673 */
6281static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL;  /* Expanded little-endian checksum. */
6282
6283static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
6284{
6285        PortAddr iop_base;
6286        int i;
6287        ushort lram_addr;
6288
6289        iop_base = asc_dvc->iop_base;
6290        AscPutRiscVarFreeQHead(iop_base, 1);
6291        AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6292        AscPutVarFreeQHead(iop_base, 1);
6293        AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
6294        AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
6295                         (uchar)((int)asc_dvc->max_total_qng + 1));
6296        AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
6297                         (uchar)((int)asc_dvc->max_total_qng + 2));
6298        AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
6299                         asc_dvc->max_total_qng);
6300        AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
6301        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
6302        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
6303        AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
6304        AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
6305        AscPutQDoneInProgress(iop_base, 0);
6306        lram_addr = ASC_QADR_BEG;
6307        for (i = 0; i < 32; i++, lram_addr += 2) {
6308                AscWriteLramWord(iop_base, lram_addr, 0);
6309        }
6310}
6311
6312static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
6313{
6314        int i;
6315        ushort warn_code;
6316        PortAddr iop_base;
6317        ASC_PADDR phy_addr;
6318        ASC_DCNT phy_size;
6319        struct asc_board *board = asc_dvc_to_board(asc_dvc);
6320
6321        iop_base = asc_dvc->iop_base;
6322        warn_code = 0;
6323        for (i = 0; i <= ASC_MAX_TID; i++) {
6324                AscPutMCodeInitSDTRAtID(iop_base, i,
6325                                        asc_dvc->cfg->sdtr_period_offset[i]);
6326        }
6327
6328        AscInitQLinkVar(asc_dvc);
6329        AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
6330                         asc_dvc->cfg->disc_enable);
6331        AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
6332                         ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
6333
6334        /* Ensure overrun buffer is aligned on an 8 byte boundary. */
6335        BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
6336        asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
6337                                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
6338        phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
6339        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
6340                                 (uchar *)&phy_addr, 1);
6341        phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE);
6342        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
6343                                 (uchar *)&phy_size, 1);
6344
6345        asc_dvc->cfg->mcode_date =
6346            AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
6347        asc_dvc->cfg->mcode_version =
6348            AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
6349
6350        AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
6351        if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
6352                asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
6353                return warn_code;
6354        }
6355        if (AscStartChip(iop_base) != 1) {
6356                asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
6357                return warn_code;
6358        }
6359
6360        return warn_code;
6361}
6362
6363static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
6364{
6365        ushort warn_code;
6366        PortAddr iop_base;
6367
6368        iop_base = asc_dvc->iop_base;
6369        warn_code = 0;
6370        if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
6371            !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
6372                AscResetChipAndScsiBus(asc_dvc);
6373                mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
6374        }
6375        asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
6376        if (asc_dvc->err_code != 0)
6377                return UW_ERR;
6378        if (!AscFindSignature(asc_dvc->iop_base)) {
6379                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
6380                return warn_code;
6381        }
6382        AscDisableInterrupt(iop_base);
6383        warn_code |= AscInitLram(asc_dvc);
6384        if (asc_dvc->err_code != 0)
6385                return UW_ERR;
6386        ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
6387        if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
6388                             _asc_mcode_size) != _asc_mcode_chksum) {
6389                asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
6390                return warn_code;
6391        }
6392        warn_code |= AscInitMicroCodeVar(asc_dvc);
6393        asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
6394        AscEnableInterrupt(iop_base);
6395        return warn_code;
6396}
6397
6398/*
6399 * Load the Microcode
6400 *
6401 * Write the microcode image to RISC memory starting at address 0.
6402 *
6403 * The microcode is stored compressed in the following format:
6404 *
6405 *  254 word (508 byte) table indexed by byte code followed
6406 *  by the following byte codes:
6407 *
6408 *    1-Byte Code:
6409 *      00: Emit word 0 in table.
6410 *      01: Emit word 1 in table.
6411 *      .
6412 *      FD: Emit word 253 in table.
6413 *
6414 *    Multi-Byte Code:
6415 *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
6416 *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
6417 *
6418 * Returns 0 or an error if the checksum doesn't match
6419 */
6420static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
6421                            int memsize, int chksum)
6422{
6423        int i, j, end, len = 0;
6424        ADV_DCNT sum;
6425
6426        AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6427
6428        for (i = 253 * 2; i < size; i++) {
6429                if (buf[i] == 0xff) {
6430                        unsigned short word = (buf[i + 3] << 8) | buf[i + 2];
6431                        for (j = 0; j < buf[i + 1]; j++) {
6432                                AdvWriteWordAutoIncLram(iop_base, word);
6433                                len += 2;
6434                        }
6435                        i += 3;
6436                } else if (buf[i] == 0xfe) {
6437                        unsigned short word = (buf[i + 2] << 8) | buf[i + 1];
6438                        AdvWriteWordAutoIncLram(iop_base, word);
6439                        i += 2;
6440                        len += 2;
6441                } else {
6442                        unsigned char off = buf[i] * 2;
6443                        unsigned short word = (buf[off + 1] << 8) | buf[off];
6444                        AdvWriteWordAutoIncLram(iop_base, word);
6445                        len += 2;
6446                }
6447        }
6448
6449        end = len;
6450
6451        while (len < memsize) {
6452                AdvWriteWordAutoIncLram(iop_base, 0);
6453                len += 2;
6454        }
6455
6456        /* Verify the microcode checksum. */
6457        sum = 0;
6458        AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
6459
6460        for (len = 0; len < end; len += 2) {
6461                sum += AdvReadWordAutoIncLram(iop_base);
6462        }
6463
6464        if (sum != chksum)
6465                return ASC_IERR_MCODE_CHKSUM;
6466
6467        return 0;
6468}
6469
6470static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
6471{
6472        ADV_CARR_T *carrp;
6473        ADV_SDCNT buf_size;
6474        ADV_PADDR carr_paddr;
6475
6476        carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
6477        asc_dvc->carr_freelist = NULL;
6478        if (carrp == asc_dvc->carrier_buf) {
6479                buf_size = ADV_CARRIER_BUFSIZE;
6480        } else {
6481                buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
6482        }
6483
6484        do {
6485                /* Get physical address of the carrier 'carrp'. */
6486                carr_paddr = cpu_to_le32(virt_to_bus(carrp));
6487
6488                buf_size -= sizeof(ADV_CARR_T);
6489
6490                carrp->carr_pa = carr_paddr;
6491                carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
6492
6493                /*
6494                 * Insert the carrier at the beginning of the freelist.
6495                 */
6496                carrp->next_vpa =
6497                        cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
6498                asc_dvc->carr_freelist = carrp;
6499
6500                carrp++;
6501        } while (buf_size > 0);
6502}
6503
6504/*
6505 * Send an idle command to the chip and wait for completion.
6506 *
6507 * Command completion is polled for once per microsecond.
6508 *
6509 * The function can be called from anywhere including an interrupt handler.
6510 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
6511 * functions to prevent reentrancy.
6512 *
6513 * Return Values:
6514 *   ADV_TRUE - command completed successfully
6515 *   ADV_FALSE - command failed
6516 *   ADV_ERROR - command timed out
6517 */
6518static int
6519AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
6520               ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
6521{
6522        int result;
6523        ADV_DCNT i, j;
6524        AdvPortAddr iop_base;
6525
6526        iop_base = asc_dvc->iop_base;
6527
6528        /*
6529         * Clear the idle command status which is set by the microcode
6530         * to a non-zero value to indicate when the command is completed.
6531         * The non-zero result is one of the IDLE_CMD_STATUS_* values
6532         */
6533        AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
6534
6535        /*
6536         * Write the idle command value after the idle command parameter
6537         * has been written to avoid a race condition. If the order is not
6538         * followed, the microcode may process the idle command before the
6539         * parameters have been written to LRAM.
6540         */
6541        AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
6542                                cpu_to_le32(idle_cmd_parameter));
6543        AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
6544
6545        /*
6546         * Tickle the RISC to tell it to process the idle command.
6547         */
6548        AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
6549        if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
6550                /*
6551                 * Clear the tickle value. In the ASC-3550 the RISC flag
6552                 * command 'clr_tickle_b' does not work unless the host
6553                 * value is cleared.
6554                 */
6555                AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
6556        }
6557
6558        /* Wait for up to 100 millisecond for the idle command to timeout. */
6559        for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
6560                /* Poll once each microsecond for command completion. */
6561                for (j = 0; j < SCSI_US_PER_MSEC; j++) {
6562                        AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
6563                                        result);
6564                        if (result != 0)
6565                                return result;
6566                        udelay(1);
6567                }
6568        }
6569
6570        BUG();          /* The idle command should never timeout. */
6571        return ADV_ERROR;
6572}
6573
6574/*
6575 * Reset SCSI Bus and purge all outstanding requests.
6576 *
6577 * Return Value:
6578 *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
6579 *      ADV_FALSE(0) -  Microcode command failed.
6580 *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
6581 *                      may be hung which requires driver recovery.
6582 */
6583static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
6584{
6585        int status;
6586
6587        /*
6588         * Send the SCSI Bus Reset idle start idle command which asserts
6589         * the SCSI Bus Reset signal.
6590         */
6591        status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
6592        if (status != ADV_TRUE) {
6593                return status;
6594        }
6595
6596        /*
6597         * Delay for the specified SCSI Bus Reset hold time.
6598         *
6599         * The hold time delay is done on the host because the RISC has no
6600         * microsecond accurate timer.
6601         */
6602        udelay(ASC_SCSI_RESET_HOLD_TIME_US);
6603
6604        /*
6605         * Send the SCSI Bus Reset end idle command which de-asserts
6606         * the SCSI Bus Reset signal and purges any pending requests.
6607         */
6608        status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
6609        if (status != ADV_TRUE) {
6610                return status;
6611        }
6612
6613        mdelay(asc_dvc->scsi_reset_wait * 1000);        /* XXX: msleep? */
6614
6615        return status;
6616}
6617
6618/*
6619 * Initialize the ASC-3550.
6620 *
6621 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
6622 *
6623 * For a non-fatal error return a warning code. If there are no warnings
6624 * then 0 is returned.
6625 *
6626 * Needed after initialization for error recovery.
6627 */
6628static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
6629{
6630        AdvPortAddr iop_base;
6631        ushort warn_code;
6632        int begin_addr;
6633        int end_addr;
6634        ushort code_sum;
6635        int word;
6636        int i;
6637        ushort scsi_cfg1;
6638        uchar tid;
6639        ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
6640        ushort wdtr_able = 0, sdtr_able, tagqng_able;
6641        uchar max_cmd[ADV_MAX_TID + 1];
6642
6643        /* If there is already an error, don't continue. */
6644        if (asc_dvc->err_code != 0)
6645                return ADV_ERROR;
6646
6647        /*
6648         * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
6649         */
6650        if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
6651                asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
6652                return ADV_ERROR;
6653        }
6654
6655        warn_code = 0;
6656        iop_base = asc_dvc->iop_base;
6657
6658        /*
6659         * Save the RISC memory BIOS region before writing the microcode.
6660         * The BIOS may already be loaded and using its RISC LRAM region
6661         * so its region must be saved and restored.
6662         *
6663         * Note: This code makes the assumption, which is currently true,
6664         * that a chip reset does not clear RISC LRAM.
6665         */
6666        for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6667                AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6668                                bios_mem[i]);
6669        }
6670
6671        /*
6672         * Save current per TID negotiated values.
6673         */
6674        if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
6675                ushort bios_version, major, minor;
6676
6677                bios_version =
6678                    bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
6679                major = (bios_version >> 12) & 0xF;
6680                minor = (bios_version >> 8) & 0xF;
6681                if (major < 3 || (major == 3 && minor == 1)) {
6682                        /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
6683                        AdvReadWordLram(iop_base, 0x120, wdtr_able);
6684                } else {
6685                        AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
6686                }
6687        }
6688        AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
6689        AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6690        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6691                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
6692                                max_cmd[tid]);
6693        }
6694
6695        asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
6696                                        _adv_asc3550_size, ADV_3550_MEMSIZE,
6697                                        _adv_asc3550_chksum);
6698        if (asc_dvc->err_code)
6699                return ADV_ERROR;
6700
6701        /*
6702         * Restore the RISC memory BIOS region.
6703         */
6704        for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
6705                AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
6706                                 bios_mem[i]);
6707        }
6708
6709        /*
6710         * Calculate and write the microcode code checksum to the microcode
6711         * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
6712         */
6713        AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
6714        AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
6715        code_sum = 0;
6716        AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
6717        for (word = begin_addr; word < end_addr; word += 2) {
6718                code_sum += AdvReadWordAutoIncLram(iop_base);
6719        }
6720        AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
6721
6722        /*
6723         * Read and save microcode version and date.
6724         */
6725        AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
6726                        asc_dvc->cfg->mcode_date);
6727        AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
6728                        asc_dvc->cfg->mcode_version);
6729
6730        /*
6731         * Set the chip type to indicate the ASC3550.
6732         */
6733        AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
6734
6735        /*
6736         * If the PCI Configuration Command Register "Parity Error Response
6737         * Control" Bit was clear (0), then set the microcode variable
6738         * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
6739         * to ignore DMA parity errors.
6740         */
6741        if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
6742                AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6743                word |= CONTROL_FLAG_IGNORE_PERR;
6744                AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
6745        }
6746
6747        /*
6748         * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
6749         * threshold of 128 bytes. This register is only accessible to the host.
6750         */
6751        AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
6752                             START_CTL_EMFU | READ_CMD_MRM);
6753
6754        /*
6755         * Microcode operating variables for WDTR, SDTR, and command tag
6756         * queuing will be set in slave_configure() based on what a
6757         * device reports it is capable of in Inquiry byte 7.
6758         *
6759         * If SCSI Bus Resets have been disabled, then directly set
6760         * SDTR and WDTR from the EEPROM configuration. This will allow
6761         * the BIOS and warm boot to work without a SCSI bus hang on
6762         * the Inquiry caused by host and target mismatched DTR values.
6763         * Without the SCSI Bus Reset, before an Inquiry a device can't
6764         * be assumed to be in Asynchronous, Narrow mode.
6765         */
6766        if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
6767                AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
6768                                 asc_dvc->wdtr_able);
6769                AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
6770                                 asc_dvc->sdtr_able);
6771        }
6772
6773        /*
6774         * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
6775         * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
6776         * bitmask. These values determine the maximum SDTR speed negotiated
6777         * with a device.
6778         *
6779         * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
6780         * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
6781         * without determining here whether the device supports SDTR.
6782         *
6783         * 4-bit speed  SDTR speed name
6784         * ===========  ===============
6785         * 0000b (0x0)  SDTR disabled
6786         * 0001b (0x1)  5 Mhz
6787         * 0010b (0x2)  10 Mhz
6788         * 0011b (0x3)  20 Mhz (Ultra)
6789         * 0100b (0x4)  40 Mhz (LVD/Ultra2)
6790         * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
6791         * 0110b (0x6)  Undefined
6792         * .
6793         * 1111b (0xF)  Undefined
6794         */
6795        word = 0;
6796        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
6797                if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
6798                        /* Set Ultra speed for TID 'tid'. */
6799                        word |= (0x3 << (4 * (tid % 4)));
6800                } else {
6801                        /* Set Fast speed for TID 'tid'. */
6802                        word |= (0x2 << (4 * (tid % 4)));
6803                }
6804                if (tid == 3) { /* Check if done with sdtr_speed1. */
6805                        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
6806                        word = 0;
6807                } else if (tid == 7) {  /* Check if done with sdtr_speed2. */
6808                        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
6809                        word = 0;
6810                } else if (tid == 11) { /* Check if done with sdtr_speed3. */
6811                        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
6812                        word = 0;
6813                } else if (tid == 15) { /* Check if done with sdtr_speed4. */
6814                        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
6815                        /* End of loop. */
6816                }
6817        }
6818
6819        /*
6820         * Set microcode operating variable for the disconnect per TID bitmask.
6821         */
6822        AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
6823                         asc_dvc->cfg->disc_enable);
6824
6825        /*
6826         * Set SCSI_CFG0 Microcode Default Value.
6827         *
6828         * The microcode will set the SCSI_CFG0 register using this value
6829         * after it is started below.
6830         */
6831        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
6832                         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
6833                         asc_dvc->chip_scsi_id);
6834
6835        /*
6836         * Determine SCSI_CFG1 Microcode Default Value.
6837         *
6838         * The microcode will set the SCSI_CFG1 register using this value
6839         * after it is started below.
6840         */
6841
6842        /* Read current SCSI_CFG1 Register value. */
6843        scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
6844
6845        /*
6846         * If all three connectors are in use, return an error.
6847         */
6848        if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
6849            (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
6850                asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
6851                return ADV_ERROR;
6852        }
6853
6854        /*
6855         * If the internal narrow cable is reversed all of the SCSI_CTRL
6856         * register signals will be set. Check for and return an error if
6857         * this condition is found.
6858         */
6859        if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
6860                asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
6861                return ADV_ERROR;
6862        }
6863
6864        /*
6865         * If this is a differential board and a single-ended device
6866         * is attached to one of the connectors, return an error.
6867         */
6868        if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
6869                asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
6870                return ADV_ERROR;
6871        }
6872
6873        /*
6874         * If automatic termination control is enabled, then set the
6875         * termination value based on a table listed in a_condor.h.
6876         *
6877         * If manual termination was specified with an EEPROM setting
6878         * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
6879         * is ready to be 'ored' into SCSI_CFG1.
6880         */
6881        if (asc_dvc->cfg->termination == 0) {
6882                /*
6883                 * The software always controls termination by setting TERM_CTL_SEL.
6884                 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
6885                 */
6886                asc_dvc->cfg->termination |= TERM_CTL_SEL;
6887
6888                switch (scsi_cfg1 & CABLE_DETECT) {
6889                        /* TERM_CTL_H: on, TERM_CTL_L: on */
6890                case 0x3:
6891                case 0x7:
6892                case 0xB:
6893                case 0xD:
6894                case 0xE:
6895                case 0xF:
6896                        asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
6897                        break;
6898
6899                        /* TERM_CTL_H: on, TERM_CTL_L: off */
6900                case 0x1:
6901                case 0x5:
6902                case 0x9:
6903                case 0xA:
6904                case 0xC:
6905                        asc_dvc->cfg->termination |= TERM_CTL_H;
6906                        break;
6907
6908                        /* TERM_CTL_H: off, TERM_CTL_L: off */
6909                case 0x2:
6910                case 0x6:
6911                        break;
6912                }
6913        }
6914
6915        /*
6916         * Clear any set TERM_CTL_H and TERM_CTL_L bits.
6917         */
6918        scsi_cfg1 &= ~TERM_CTL;
6919
6920        /*
6921         * Invert the TERM_CTL_H and TERM_CTL_L bits and then
6922         * set 'scsi_cfg1'. The TERM_POL bit does not need to be
6923         * referenced, because the hardware internally inverts
6924         * the Termination High and Low bits if TERM_POL is set.
6925         */
6926        scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
6927
6928        /*
6929         * Set SCSI_CFG1 Microcode Default Value
6930         *
6931         * Set filter value and possibly modified termination control
6932         * bits in the Microcode SCSI_CFG1 Register Value.
6933         *
6934         * The microcode will set the SCSI_CFG1 register using this value
6935         * after it is started below.
6936         */
6937        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
6938                         FLTR_DISABLE | scsi_cfg1);
6939
6940        /*
6941         * Set MEM_CFG Microcode Default Value
6942         *
6943         * The microcode will set the MEM_CFG register using this value
6944         * after it is started below.
6945         *
6946         * MEM_CFG may be accessed as a word or byte, but only bits 0-7
6947         * are defined.
6948         *
6949         * ASC-3550 has 8KB internal memory.
6950         */
6951        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
6952                         BIOS_EN | RAM_SZ_8KB);
6953
6954        /*
6955         * Set SEL_MASK Microcode Default Value
6956         *
6957         * The microcode will set the SEL_MASK register using this value
6958         * after it is started below.
6959         */
6960        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
6961                         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
6962
6963        AdvBuildCarrierFreelist(asc_dvc);
6964
6965        /*
6966         * Set-up the Host->RISC Initiator Command Queue (ICQ).
6967         */
6968
6969        if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
6970                asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
6971                return ADV_ERROR;
6972        }
6973        asc_dvc->carr_freelist = (ADV_CARR_T *)
6974            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
6975
6976        /*
6977         * The first command issued will be placed in the stopper carrier.
6978         */
6979        asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
6980
6981        /*
6982         * Set RISC ICQ physical address start value.
6983         */
6984        AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
6985
6986        /*
6987         * Set-up the RISC->Host Initiator Response Queue (IRQ).
6988         */
6989        if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
6990                asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
6991                return ADV_ERROR;
6992        }
6993        asc_dvc->carr_freelist = (ADV_CARR_T *)
6994            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
6995
6996        /*
6997         * The first command completed by the RISC will be placed in
6998         * the stopper.
6999         *
7000         * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7001         * completed the RISC will set the ASC_RQ_STOPPER bit.
7002         */
7003        asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7004
7005        /*
7006         * Set RISC IRQ physical address start value.
7007         */
7008        AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7009        asc_dvc->carr_pending_cnt = 0;
7010
7011        AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7012                             (ADV_INTR_ENABLE_HOST_INTR |
7013                              ADV_INTR_ENABLE_GLOBAL_INTR));
7014
7015        AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7016        AdvWriteWordRegister(iop_base, IOPW_PC, word);
7017
7018        /* finally, finally, gentlemen, start your engine */
7019        AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7020
7021        /*
7022         * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7023         * Resets should be performed. The RISC has to be running
7024         * to issue a SCSI Bus Reset.
7025         */
7026        if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7027                /*
7028                 * If the BIOS Signature is present in memory, restore the
7029                 * BIOS Handshake Configuration Table and do not perform
7030                 * a SCSI Bus Reset.
7031                 */
7032                if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7033                    0x55AA) {
7034                        /*
7035                         * Restore per TID negotiated values.
7036                         */
7037                        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7038                        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7039                        AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7040                                         tagqng_able);
7041                        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7042                                AdvWriteByteLram(iop_base,
7043                                                 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7044                                                 max_cmd[tid]);
7045                        }
7046                } else {
7047                        if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7048                                warn_code = ASC_WARN_BUSRESET_ERROR;
7049                        }
7050                }
7051        }
7052
7053        return warn_code;
7054}
7055
7056/*
7057 * Initialize the ASC-38C0800.
7058 *
7059 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
7060 *
7061 * For a non-fatal error return a warning code. If there are no warnings
7062 * then 0 is returned.
7063 *
7064 * Needed after initialization for error recovery.
7065 */
7066static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
7067{
7068        AdvPortAddr iop_base;
7069        ushort warn_code;
7070        int begin_addr;
7071        int end_addr;
7072        ushort code_sum;
7073        int word;
7074        int i;
7075        ushort scsi_cfg1;
7076        uchar byte;
7077        uchar tid;
7078        ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
7079        ushort wdtr_able, sdtr_able, tagqng_able;
7080        uchar max_cmd[ADV_MAX_TID + 1];
7081
7082        /* If there is already an error, don't continue. */
7083        if (asc_dvc->err_code != 0)
7084                return ADV_ERROR;
7085
7086        /*
7087         * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
7088         */
7089        if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
7090                asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7091                return ADV_ERROR;
7092        }
7093
7094        warn_code = 0;
7095        iop_base = asc_dvc->iop_base;
7096
7097        /*
7098         * Save the RISC memory BIOS region before writing the microcode.
7099         * The BIOS may already be loaded and using its RISC LRAM region
7100         * so its region must be saved and restored.
7101         *
7102         * Note: This code makes the assumption, which is currently true,
7103         * that a chip reset does not clear RISC LRAM.
7104         */
7105        for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7106                AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7107                                bios_mem[i]);
7108        }
7109
7110        /*
7111         * Save current per TID negotiated values.
7112         */
7113        AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7114        AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7115        AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7116        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7117                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7118                                max_cmd[tid]);
7119        }
7120
7121        /*
7122         * RAM BIST (RAM Built-In Self Test)
7123         *
7124         * Address : I/O base + offset 0x38h register (byte).
7125         * Function: Bit 7-6(RW) : RAM mode
7126         *                          Normal Mode   : 0x00
7127         *                          Pre-test Mode : 0x40
7128         *                          RAM Test Mode : 0x80
7129         *           Bit 5       : unused
7130         *           Bit 4(RO)   : Done bit
7131         *           Bit 3-0(RO) : Status
7132         *                          Host Error    : 0x08
7133         *                          Int_RAM Error : 0x04
7134         *                          RISC Error    : 0x02
7135         *                          SCSI Error    : 0x01
7136         *                          No Error      : 0x00
7137         *
7138         * Note: RAM BIST code should be put right here, before loading the
7139         * microcode and after saving the RISC memory BIOS region.
7140         */
7141
7142        /*
7143         * LRAM Pre-test
7144         *
7145         * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7146         * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7147         * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7148         * to NORMAL_MODE, return an error too.
7149         */
7150        for (i = 0; i < 2; i++) {
7151                AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7152                mdelay(10);     /* Wait for 10ms before reading back. */
7153                byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7154                if ((byte & RAM_TEST_DONE) == 0
7155                    || (byte & 0x0F) != PRE_TEST_VALUE) {
7156                        asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7157                        return ADV_ERROR;
7158                }
7159
7160                AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7161                mdelay(10);     /* Wait for 10ms before reading back. */
7162                if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7163                    != NORMAL_VALUE) {
7164                        asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7165                        return ADV_ERROR;
7166                }
7167        }
7168
7169        /*
7170         * LRAM Test - It takes about 1.5 ms to run through the test.
7171         *
7172         * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7173         * If Done bit not set or Status not 0, save register byte, set the
7174         * err_code, and return an error.
7175         */
7176        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7177        mdelay(10);     /* Wait for 10ms before checking status. */
7178
7179        byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7180        if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7181                /* Get here if Done bit not set or Status not 0. */
7182                asc_dvc->bist_err_code = byte;  /* for BIOS display message */
7183                asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7184                return ADV_ERROR;
7185        }
7186
7187        /* We need to reset back to normal mode after LRAM test passes. */
7188        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7189
7190        asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
7191                                 _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
7192                                 _adv_asc38C0800_chksum);
7193        if (asc_dvc->err_code)
7194                return ADV_ERROR;
7195
7196        /*
7197         * Restore the RISC memory BIOS region.
7198         */
7199        for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7200                AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7201                                 bios_mem[i]);
7202        }
7203
7204        /*
7205         * Calculate and write the microcode code checksum to the microcode
7206         * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7207         */
7208        AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7209        AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7210        code_sum = 0;
7211        AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7212        for (word = begin_addr; word < end_addr; word += 2) {
7213                code_sum += AdvReadWordAutoIncLram(iop_base);
7214        }
7215        AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7216
7217        /*
7218         * Read microcode version and date.
7219         */
7220        AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7221                        asc_dvc->cfg->mcode_date);
7222        AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7223                        asc_dvc->cfg->mcode_version);
7224
7225        /*
7226         * Set the chip type to indicate the ASC38C0800.
7227         */
7228        AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
7229
7230        /*
7231         * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7232         * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7233         * cable detection and then we are able to read C_DET[3:0].
7234         *
7235         * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7236         * Microcode Default Value' section below.
7237         */
7238        scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7239        AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7240                             scsi_cfg1 | DIS_TERM_DRV);
7241
7242        /*
7243         * If the PCI Configuration Command Register "Parity Error Response
7244         * Control" Bit was clear (0), then set the microcode variable
7245         * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7246         * to ignore DMA parity errors.
7247         */
7248        if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7249                AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7250                word |= CONTROL_FLAG_IGNORE_PERR;
7251                AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7252        }
7253
7254        /*
7255         * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
7256         * bits for the default FIFO threshold.
7257         *
7258         * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
7259         *
7260         * For DMA Errata #4 set the BC_THRESH_ENB bit.
7261         */
7262        AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7263                             BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
7264                             READ_CMD_MRM);
7265
7266        /*
7267         * Microcode operating variables for WDTR, SDTR, and command tag
7268         * queuing will be set in slave_configure() based on what a
7269         * device reports it is capable of in Inquiry byte 7.
7270         *
7271         * If SCSI Bus Resets have been disabled, then directly set
7272         * SDTR and WDTR from the EEPROM configuration. This will allow
7273         * the BIOS and warm boot to work without a SCSI bus hang on
7274         * the Inquiry caused by host and target mismatched DTR values.
7275         * Without the SCSI Bus Reset, before an Inquiry a device can't
7276         * be assumed to be in Asynchronous, Narrow mode.
7277         */
7278        if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7279                AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7280                                 asc_dvc->wdtr_able);
7281                AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7282                                 asc_dvc->sdtr_able);
7283        }
7284
7285        /*
7286         * Set microcode operating variables for DISC and SDTR_SPEED1,
7287         * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7288         * configuration values.
7289         *
7290         * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7291         * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7292         * without determining here whether the device supports SDTR.
7293         */
7294        AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7295                         asc_dvc->cfg->disc_enable);
7296        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7297        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7298        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7299        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7300
7301        /*
7302         * Set SCSI_CFG0 Microcode Default Value.
7303         *
7304         * The microcode will set the SCSI_CFG0 register using this value
7305         * after it is started below.
7306         */
7307        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7308                         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7309                         asc_dvc->chip_scsi_id);
7310
7311        /*
7312         * Determine SCSI_CFG1 Microcode Default Value.
7313         *
7314         * The microcode will set the SCSI_CFG1 register using this value
7315         * after it is started below.
7316         */
7317
7318        /* Read current SCSI_CFG1 Register value. */
7319        scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7320
7321        /*
7322         * If the internal narrow cable is reversed all of the SCSI_CTRL
7323         * register signals will be set. Check for and return an error if
7324         * this condition is found.
7325         */
7326        if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7327                asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7328                return ADV_ERROR;
7329        }
7330
7331        /*
7332         * All kind of combinations of devices attached to one of four
7333         * connectors are acceptable except HVD device attached. For example,
7334         * LVD device can be attached to SE connector while SE device attached
7335         * to LVD connector.  If LVD device attached to SE connector, it only
7336         * runs up to Ultra speed.
7337         *
7338         * If an HVD device is attached to one of LVD connectors, return an
7339         * error.  However, there is no way to detect HVD device attached to
7340         * SE connectors.
7341         */
7342        if (scsi_cfg1 & HVD) {
7343                asc_dvc->err_code = ASC_IERR_HVD_DEVICE;
7344                return ADV_ERROR;
7345        }
7346
7347        /*
7348         * If either SE or LVD automatic termination control is enabled, then
7349         * set the termination value based on a table listed in a_condor.h.
7350         *
7351         * If manual termination was specified with an EEPROM setting then
7352         * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready
7353         * to be 'ored' into SCSI_CFG1.
7354         */
7355        if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7356                /* SE automatic termination control is enabled. */
7357                switch (scsi_cfg1 & C_DET_SE) {
7358                        /* TERM_SE_HI: on, TERM_SE_LO: on */
7359                case 0x1:
7360                case 0x2:
7361                case 0x3:
7362                        asc_dvc->cfg->termination |= TERM_SE;
7363                        break;
7364
7365                        /* TERM_SE_HI: on, TERM_SE_LO: off */
7366                case 0x0:
7367                        asc_dvc->cfg->termination |= TERM_SE_HI;
7368                        break;
7369                }
7370        }
7371
7372        if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
7373                /* LVD automatic termination control is enabled. */
7374                switch (scsi_cfg1 & C_DET_LVD) {
7375                        /* TERM_LVD_HI: on, TERM_LVD_LO: on */
7376                case 0x4:
7377                case 0x8:
7378                case 0xC:
7379                        asc_dvc->cfg->termination |= TERM_LVD;
7380                        break;
7381
7382                        /* TERM_LVD_HI: off, TERM_LVD_LO: off */
7383                case 0x0:
7384                        break;
7385                }
7386        }
7387
7388        /*
7389         * Clear any set TERM_SE and TERM_LVD bits.
7390         */
7391        scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
7392
7393        /*
7394         * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
7395         */
7396        scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
7397
7398        /*
7399         * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE
7400         * bits and set possibly modified termination control bits in the
7401         * Microcode SCSI_CFG1 Register Value.
7402         */
7403        scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
7404
7405        /*
7406         * Set SCSI_CFG1 Microcode Default Value
7407         *
7408         * Set possibly modified termination control and reset DIS_TERM_DRV
7409         * bits in the Microcode SCSI_CFG1 Register Value.
7410         *
7411         * The microcode will set the SCSI_CFG1 register using this value
7412         * after it is started below.
7413         */
7414        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7415
7416        /*
7417         * Set MEM_CFG Microcode Default Value
7418         *
7419         * The microcode will set the MEM_CFG register using this value
7420         * after it is started below.
7421         *
7422         * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7423         * are defined.
7424         *
7425         * ASC-38C0800 has 16KB internal memory.
7426         */
7427        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7428                         BIOS_EN | RAM_SZ_16KB);
7429
7430        /*
7431         * Set SEL_MASK Microcode Default Value
7432         *
7433         * The microcode will set the SEL_MASK register using this value
7434         * after it is started below.
7435         */
7436        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7437                         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7438
7439        AdvBuildCarrierFreelist(asc_dvc);
7440
7441        /*
7442         * Set-up the Host->RISC Initiator Command Queue (ICQ).
7443         */
7444
7445        if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7446                asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7447                return ADV_ERROR;
7448        }
7449        asc_dvc->carr_freelist = (ADV_CARR_T *)
7450            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7451
7452        /*
7453         * The first command issued will be placed in the stopper carrier.
7454         */
7455        asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7456
7457        /*
7458         * Set RISC ICQ physical address start value.
7459         * carr_pa is LE, must be native before write
7460         */
7461        AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7462
7463        /*
7464         * Set-up the RISC->Host Initiator Response Queue (IRQ).
7465         */
7466        if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7467                asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7468                return ADV_ERROR;
7469        }
7470        asc_dvc->carr_freelist = (ADV_CARR_T *)
7471            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7472
7473        /*
7474         * The first command completed by the RISC will be placed in
7475         * the stopper.
7476         *
7477         * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7478         * completed the RISC will set the ASC_RQ_STOPPER bit.
7479         */
7480        asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7481
7482        /*
7483         * Set RISC IRQ physical address start value.
7484         *
7485         * carr_pa is LE, must be native before write *
7486         */
7487        AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7488        asc_dvc->carr_pending_cnt = 0;
7489
7490        AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7491                             (ADV_INTR_ENABLE_HOST_INTR |
7492                              ADV_INTR_ENABLE_GLOBAL_INTR));
7493
7494        AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7495        AdvWriteWordRegister(iop_base, IOPW_PC, word);
7496
7497        /* finally, finally, gentlemen, start your engine */
7498        AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7499
7500        /*
7501         * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7502         * Resets should be performed. The RISC has to be running
7503         * to issue a SCSI Bus Reset.
7504         */
7505        if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7506                /*
7507                 * If the BIOS Signature is present in memory, restore the
7508                 * BIOS Handshake Configuration Table and do not perform
7509                 * a SCSI Bus Reset.
7510                 */
7511                if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
7512                    0x55AA) {
7513                        /*
7514                         * Restore per TID negotiated values.
7515                         */
7516                        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7517                        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7518                        AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
7519                                         tagqng_able);
7520                        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
7521                                AdvWriteByteLram(iop_base,
7522                                                 ASC_MC_NUMBER_OF_MAX_CMD + tid,
7523                                                 max_cmd[tid]);
7524                        }
7525                } else {
7526                        if (AdvResetSB(asc_dvc) != ADV_TRUE) {
7527                                warn_code = ASC_WARN_BUSRESET_ERROR;
7528                        }
7529                }
7530        }
7531
7532        return warn_code;
7533}
7534
7535/*
7536 * Initialize the ASC-38C1600.
7537 *
7538 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
7539 *
7540 * For a non-fatal error return a warning code. If there are no warnings
7541 * then 0 is returned.
7542 *
7543 * Needed after initialization for error recovery.
7544 */
7545static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
7546{
7547        AdvPortAddr iop_base;
7548        ushort warn_code;
7549        int begin_addr;
7550        int end_addr;
7551        ushort code_sum;
7552        long word;
7553        int i;
7554        ushort scsi_cfg1;
7555        uchar byte;
7556        uchar tid;
7557        ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
7558        ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
7559        uchar max_cmd[ASC_MAX_TID + 1];
7560
7561        /* If there is already an error, don't continue. */
7562        if (asc_dvc->err_code != 0) {
7563                return ADV_ERROR;
7564        }
7565
7566        /*
7567         * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
7568         */
7569        if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
7570                asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
7571                return ADV_ERROR;
7572        }
7573
7574        warn_code = 0;
7575        iop_base = asc_dvc->iop_base;
7576
7577        /*
7578         * Save the RISC memory BIOS region before writing the microcode.
7579         * The BIOS may already be loaded and using its RISC LRAM region
7580         * so its region must be saved and restored.
7581         *
7582         * Note: This code makes the assumption, which is currently true,
7583         * that a chip reset does not clear RISC LRAM.
7584         */
7585        for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7586                AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7587                                bios_mem[i]);
7588        }
7589
7590        /*
7591         * Save current per TID negotiated values.
7592         */
7593        AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7594        AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7595        AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
7596        AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7597        for (tid = 0; tid <= ASC_MAX_TID; tid++) {
7598                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
7599                                max_cmd[tid]);
7600        }
7601
7602        /*
7603         * RAM BIST (Built-In Self Test)
7604         *
7605         * Address : I/O base + offset 0x38h register (byte).
7606         * Function: Bit 7-6(RW) : RAM mode
7607         *                          Normal Mode   : 0x00
7608         *                          Pre-test Mode : 0x40
7609         *                          RAM Test Mode : 0x80
7610         *           Bit 5       : unused
7611         *           Bit 4(RO)   : Done bit
7612         *           Bit 3-0(RO) : Status
7613         *                          Host Error    : 0x08
7614         *                          Int_RAM Error : 0x04
7615         *                          RISC Error    : 0x02
7616         *                          SCSI Error    : 0x01
7617         *                          No Error      : 0x00
7618         *
7619         * Note: RAM BIST code should be put right here, before loading the
7620         * microcode and after saving the RISC memory BIOS region.
7621         */
7622
7623        /*
7624         * LRAM Pre-test
7625         *
7626         * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
7627         * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
7628         * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
7629         * to NORMAL_MODE, return an error too.
7630         */
7631        for (i = 0; i < 2; i++) {
7632                AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
7633                mdelay(10);     /* Wait for 10ms before reading back. */
7634                byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7635                if ((byte & RAM_TEST_DONE) == 0
7636                    || (byte & 0x0F) != PRE_TEST_VALUE) {
7637                        asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7638                        return ADV_ERROR;
7639                }
7640
7641                AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7642                mdelay(10);     /* Wait for 10ms before reading back. */
7643                if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
7644                    != NORMAL_VALUE) {
7645                        asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST;
7646                        return ADV_ERROR;
7647                }
7648        }
7649
7650        /*
7651         * LRAM Test - It takes about 1.5 ms to run through the test.
7652         *
7653         * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
7654         * If Done bit not set or Status not 0, save register byte, set the
7655         * err_code, and return an error.
7656         */
7657        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
7658        mdelay(10);     /* Wait for 10ms before checking status. */
7659
7660        byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
7661        if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
7662                /* Get here if Done bit not set or Status not 0. */
7663                asc_dvc->bist_err_code = byte;  /* for BIOS display message */
7664                asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST;
7665                return ADV_ERROR;
7666        }
7667
7668        /* We need to reset back to normal mode after LRAM test passes. */
7669        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
7670
7671        asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
7672                                 _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
7673                                 _adv_asc38C1600_chksum);
7674        if (asc_dvc->err_code)
7675                return ADV_ERROR;
7676
7677        /*
7678         * Restore the RISC memory BIOS region.
7679         */
7680        for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
7681                AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
7682                                 bios_mem[i]);
7683        }
7684
7685        /*
7686         * Calculate and write the microcode code checksum to the microcode
7687         * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
7688         */
7689        AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
7690        AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
7691        code_sum = 0;
7692        AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
7693        for (word = begin_addr; word < end_addr; word += 2) {
7694                code_sum += AdvReadWordAutoIncLram(iop_base);
7695        }
7696        AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
7697
7698        /*
7699         * Read microcode version and date.
7700         */
7701        AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
7702                        asc_dvc->cfg->mcode_date);
7703        AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
7704                        asc_dvc->cfg->mcode_version);
7705
7706        /*
7707         * Set the chip type to indicate the ASC38C1600.
7708         */
7709        AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
7710
7711        /*
7712         * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
7713         * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
7714         * cable detection and then we are able to read C_DET[3:0].
7715         *
7716         * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
7717         * Microcode Default Value' section below.
7718         */
7719        scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7720        AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
7721                             scsi_cfg1 | DIS_TERM_DRV);
7722
7723        /*
7724         * If the PCI Configuration Command Register "Parity Error Response
7725         * Control" Bit was clear (0), then set the microcode variable
7726         * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
7727         * to ignore DMA parity errors.
7728         */
7729        if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
7730                AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7731                word |= CONTROL_FLAG_IGNORE_PERR;
7732                AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7733        }
7734
7735        /*
7736         * If the BIOS control flag AIPP (Asynchronous Information
7737         * Phase Protection) disable bit is not set, then set the firmware
7738         * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
7739         * AIPP checking and encoding.
7740         */
7741        if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
7742                AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7743                word |= CONTROL_FLAG_ENABLE_AIPP;
7744                AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
7745        }
7746
7747        /*
7748         * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
7749         * and START_CTL_TH [3:2].
7750         */
7751        AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
7752                             FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
7753
7754        /*
7755         * Microcode operating variables for WDTR, SDTR, and command tag
7756         * queuing will be set in slave_configure() based on what a
7757         * device reports it is capable of in Inquiry byte 7.
7758         *
7759         * If SCSI Bus Resets have been disabled, then directly set
7760         * SDTR and WDTR from the EEPROM configuration. This will allow
7761         * the BIOS and warm boot to work without a SCSI bus hang on
7762         * the Inquiry caused by host and target mismatched DTR values.
7763         * Without the SCSI Bus Reset, before an Inquiry a device can't
7764         * be assumed to be in Asynchronous, Narrow mode.
7765         */
7766        if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
7767                AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
7768                                 asc_dvc->wdtr_able);
7769                AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
7770                                 asc_dvc->sdtr_able);
7771        }
7772
7773        /*
7774         * Set microcode operating variables for DISC and SDTR_SPEED1,
7775         * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
7776         * configuration values.
7777         *
7778         * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
7779         * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
7780         * without determining here whether the device supports SDTR.
7781         */
7782        AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
7783                         asc_dvc->cfg->disc_enable);
7784        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
7785        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
7786        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
7787        AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
7788
7789        /*
7790         * Set SCSI_CFG0 Microcode Default Value.
7791         *
7792         * The microcode will set the SCSI_CFG0 register using this value
7793         * after it is started below.
7794         */
7795        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
7796                         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
7797                         asc_dvc->chip_scsi_id);
7798
7799        /*
7800         * Calculate SCSI_CFG1 Microcode Default Value.
7801         *
7802         * The microcode will set the SCSI_CFG1 register using this value
7803         * after it is started below.
7804         *
7805         * Each ASC-38C1600 function has only two cable detect bits.
7806         * The bus mode override bits are in IOPB_SOFT_OVER_WR.
7807         */
7808        scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
7809
7810        /*
7811         * If the cable is reversed all of the SCSI_CTRL register signals
7812         * will be set. Check for and return an error if this condition is
7813         * found.
7814         */
7815        if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
7816                asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
7817                return ADV_ERROR;
7818        }
7819
7820        /*
7821         * Each ASC-38C1600 function has two connectors. Only an HVD device
7822         * can not be connected to either connector. An LVD device or SE device
7823         * may be connected to either connecor. If an SE device is connected,
7824         * then at most Ultra speed (20 Mhz) can be used on both connectors.
7825         *
7826         * If an HVD device is attached, return an error.
7827         */
7828        if (scsi_cfg1 & HVD) {
7829                asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
7830                return ADV_ERROR;
7831        }
7832
7833        /*
7834         * Each function in the ASC-38C1600 uses only the SE cable detect and
7835         * termination because there are two connectors for each function. Each
7836         * function may use either LVD or SE mode. Corresponding the SE automatic
7837         * termination control EEPROM bits are used for each function. Each
7838         * function has its own EEPROM. If SE automatic control is enabled for
7839         * the function, then set the termination value based on a table listed
7840         * in a_condor.h.
7841         *
7842         * If manual termination is specified in the EEPROM for the function,
7843         * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
7844         * ready to be 'ored' into SCSI_CFG1.
7845         */
7846        if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
7847                struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
7848                /* SE automatic termination control is enabled. */
7849                switch (scsi_cfg1 & C_DET_SE) {
7850                        /* TERM_SE_HI: on, TERM_SE_LO: on */
7851                case 0x1:
7852                case 0x2:
7853                case 0x3:
7854                        asc_dvc->cfg->termination |= TERM_SE;
7855                        break;
7856
7857                case 0x0:
7858                        if (PCI_FUNC(pdev->devfn) == 0) {
7859                                /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
7860                        } else {
7861                                /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
7862                                asc_dvc->cfg->termination |= TERM_SE_HI;
7863                        }
7864                        break;
7865                }
7866        }
7867
7868        /*
7869         * Clear any set TERM_SE bits.
7870         */
7871        scsi_cfg1 &= ~TERM_SE;
7872
7873        /*
7874         * Invert the TERM_SE bits and then set 'scsi_cfg1'.
7875         */
7876        scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
7877
7878        /*
7879         * Clear Big Endian and Terminator Polarity bits and set possibly
7880         * modified termination control bits in the Microcode SCSI_CFG1
7881         * Register Value.
7882         *
7883         * Big Endian bit is not used even on big endian machines.
7884         */
7885        scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
7886
7887        /*
7888         * Set SCSI_CFG1 Microcode Default Value
7889         *
7890         * Set possibly modified termination control bits in the Microcode
7891         * SCSI_CFG1 Register Value.
7892         *
7893         * The microcode will set the SCSI_CFG1 register using this value
7894         * after it is started below.
7895         */
7896        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
7897
7898        /*
7899         * Set MEM_CFG Microcode Default Value
7900         *
7901         * The microcode will set the MEM_CFG register using this value
7902         * after it is started below.
7903         *
7904         * MEM_CFG may be accessed as a word or byte, but only bits 0-7
7905         * are defined.
7906         *
7907         * ASC-38C1600 has 32KB internal memory.
7908         *
7909         * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
7910         * out a special 16K Adv Library and Microcode version. After the issue
7911         * resolved, we should turn back to the 32K support. Both a_condor.h and
7912         * mcode.sas files also need to be updated.
7913         *
7914         * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7915         *  BIOS_EN | RAM_SZ_32KB);
7916         */
7917        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
7918                         BIOS_EN | RAM_SZ_16KB);
7919
7920        /*
7921         * Set SEL_MASK Microcode Default Value
7922         *
7923         * The microcode will set the SEL_MASK register using this value
7924         * after it is started below.
7925         */
7926        AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
7927                         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
7928
7929        AdvBuildCarrierFreelist(asc_dvc);
7930
7931        /*
7932         * Set-up the Host->RISC Initiator Command Queue (ICQ).
7933         */
7934        if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
7935                asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7936                return ADV_ERROR;
7937        }
7938        asc_dvc->carr_freelist = (ADV_CARR_T *)
7939            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
7940
7941        /*
7942         * The first command issued will be placed in the stopper carrier.
7943         */
7944        asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7945
7946        /*
7947         * Set RISC ICQ physical address start value. Initialize the
7948         * COMMA register to the same value otherwise the RISC will
7949         * prematurely detect a command is available.
7950         */
7951        AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
7952        AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
7953                              le32_to_cpu(asc_dvc->icq_sp->carr_pa));
7954
7955        /*
7956         * Set-up the RISC->Host Initiator Response Queue (IRQ).
7957         */
7958        if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
7959                asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
7960                return ADV_ERROR;
7961        }
7962        asc_dvc->carr_freelist = (ADV_CARR_T *)
7963            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
7964
7965        /*
7966         * The first command completed by the RISC will be placed in
7967         * the stopper.
7968         *
7969         * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
7970         * completed the RISC will set the ASC_RQ_STOPPER bit.
7971         */
7972        asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
7973
7974        /*
7975         * Set RISC IRQ physical address start value.
7976         */
7977        AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
7978        asc_dvc->carr_pending_cnt = 0;
7979
7980        AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
7981                             (ADV_INTR_ENABLE_HOST_INTR |
7982                              ADV_INTR_ENABLE_GLOBAL_INTR));
7983        AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
7984        AdvWriteWordRegister(iop_base, IOPW_PC, word);
7985
7986        /* finally, finally, gentlemen, start your engine */
7987        AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
7988
7989        /*
7990         * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
7991         * Resets should be performed. The RISC has to be running
7992         * to issue a SCSI Bus Reset.
7993         */
7994        if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
7995                /*
7996                 * If the BIOS Signature is present in memory, restore the
7997                 * per TID microcode operating variables.
7998                 */
7999                if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
8000                    0x55AA) {
8001                        /*
8002                         * Restore per TID negotiated values.
8003                         */
8004                        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8005                        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8006                        AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8007                        AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
8008                                         tagqng_able);
8009                        for (tid = 0; tid <= ASC_MAX_TID; tid++) {
8010                                AdvWriteByteLram(iop_base,
8011                                                 ASC_MC_NUMBER_OF_MAX_CMD + tid,
8012                                                 max_cmd[tid]);
8013                        }
8014                } else {
8015                        if (AdvResetSB(asc_dvc) != ADV_TRUE) {
8016                                warn_code = ASC_WARN_BUSRESET_ERROR;
8017                        }
8018                }
8019        }
8020
8021        return warn_code;
8022}
8023
8024/*
8025 * Reset chip and SCSI Bus.
8026 *
8027 * Return Value:
8028 *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
8029 *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
8030 */
8031static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
8032{
8033        int status;
8034        ushort wdtr_able, sdtr_able, tagqng_able;
8035        ushort ppr_able = 0;
8036        uchar tid, max_cmd[ADV_MAX_TID + 1];
8037        AdvPortAddr iop_base;
8038        ushort bios_sig;
8039
8040        iop_base = asc_dvc->iop_base;
8041
8042        /*
8043         * Save current per TID negotiated values.
8044         */
8045        AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8046        AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8047        if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8048                AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8049        }
8050        AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8051        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8052                AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8053                                max_cmd[tid]);
8054        }
8055
8056        /*
8057         * Force the AdvInitAsc3550/38C0800Driver() function to
8058         * perform a SCSI Bus Reset by clearing the BIOS signature word.
8059         * The initialization functions assumes a SCSI Bus Reset is not
8060         * needed if the BIOS signature word is present.
8061         */
8062        AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8063        AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
8064
8065        /*
8066         * Stop chip and reset it.
8067         */
8068        AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
8069        AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
8070        mdelay(100);
8071        AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
8072                             ADV_CTRL_REG_CMD_WR_IO_REG);
8073
8074        /*
8075         * Reset Adv Library error code, if any, and try
8076         * re-initializing the chip.
8077         */
8078        asc_dvc->err_code = 0;
8079        if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8080                status = AdvInitAsc38C1600Driver(asc_dvc);
8081        } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8082                status = AdvInitAsc38C0800Driver(asc_dvc);
8083        } else {
8084                status = AdvInitAsc3550Driver(asc_dvc);
8085        }
8086
8087        /* Translate initialization return value to status value. */
8088        if (status == 0) {
8089                status = ADV_TRUE;
8090        } else {
8091                status = ADV_FALSE;
8092        }
8093
8094        /*
8095         * Restore the BIOS signature word.
8096         */
8097        AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
8098
8099        /*
8100         * Restore per TID negotiated values.
8101         */
8102        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8103        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8104        if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
8105                AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
8106        }
8107        AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8108        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
8109                AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
8110                                 max_cmd[tid]);
8111        }
8112
8113        return status;
8114}
8115
8116/*
8117 * adv_async_callback() - Adv Library asynchronous event callback function.
8118 */
8119static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
8120{
8121        switch (code) {
8122        case ADV_ASYNC_SCSI_BUS_RESET_DET:
8123                /*
8124                 * The firmware detected a SCSI Bus reset.
8125                 */
8126                ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n");
8127                break;
8128
8129        case ADV_ASYNC_RDMA_FAILURE:
8130                /*
8131                 * Handle RDMA failure by resetting the SCSI Bus and
8132                 * possibly the chip if it is unresponsive. Log the error
8133                 * with a unique code.
8134                 */
8135                ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n");
8136                AdvResetChipAndSB(adv_dvc_varp);
8137                break;
8138
8139        case ADV_HOST_SCSI_BUS_RESET:
8140                /*
8141                 * Host generated SCSI bus reset occurred.
8142                 */
8143                ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n");
8144                break;
8145
8146        default:
8147                ASC_DBG(0, "unknown code 0x%x\n", code);
8148                break;
8149        }
8150}
8151
8152/*
8153 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
8154 *
8155 * Callback function for the Wide SCSI Adv Library.
8156 */
8157static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
8158{
8159        struct asc_board *boardp;
8160        adv_req_t *reqp;
8161        adv_sgblk_t *sgblkp;
8162        struct scsi_cmnd *scp;
8163        struct Scsi_Host *shost;
8164        ADV_DCNT resid_cnt;
8165
8166        ASC_DBG(1, "adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
8167                 (ulong)adv_dvc_varp, (ulong)scsiqp);
8168        ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
8169
8170        /*
8171         * Get the adv_req_t structure for the command that has been
8172         * completed. The adv_req_t structure actually contains the
8173         * completed ADV_SCSI_REQ_Q structure.
8174         */
8175        reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
8176        ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp);
8177        if (reqp == NULL) {
8178                ASC_PRINT("adv_isr_callback: reqp is NULL\n");
8179                return;
8180        }
8181
8182        /*
8183         * Get the struct scsi_cmnd structure and Scsi_Host structure for the
8184         * command that has been completed.
8185         *
8186         * Note: The adv_req_t request structure and adv_sgblk_t structure,
8187         * if any, are dropped, because a board structure pointer can not be
8188         * determined.
8189         */
8190        scp = reqp->cmndp;
8191        ASC_DBG(1, "scp 0x%p\n", scp);
8192        if (scp == NULL) {
8193                ASC_PRINT
8194                    ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
8195                return;
8196        }
8197        ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
8198
8199        shost = scp->device->host;
8200        ASC_STATS(shost, callback);
8201        ASC_DBG(1, "shost 0x%p\n", shost);
8202
8203        boardp = shost_priv(shost);
8204        BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var);
8205
8206        /*
8207         * 'done_status' contains the command's ending status.
8208         */
8209        switch (scsiqp->done_status) {
8210        case QD_NO_ERROR:
8211                ASC_DBG(2, "QD_NO_ERROR\n");
8212                scp->result = 0;
8213
8214                /*
8215                 * Check for an underrun condition.
8216                 *
8217                 * If there was no error and an underrun condition, then
8218                 * then return the number of underrun bytes.
8219                 */
8220                resid_cnt = le32_to_cpu(scsiqp->data_cnt);
8221                if (scsi_bufflen(scp) != 0 && resid_cnt != 0 &&
8222                    resid_cnt <= scsi_bufflen(scp)) {
8223                        ASC_DBG(1, "underrun condition %lu bytes\n",
8224                                 (ulong)resid_cnt);
8225                        scsi_set_resid(scp, resid_cnt);
8226                }
8227                break;
8228
8229        case QD_WITH_ERROR:
8230                ASC_DBG(2, "QD_WITH_ERROR\n");
8231                switch (scsiqp->host_status) {
8232                case QHSTA_NO_ERROR:
8233                        if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
8234                                ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
8235                                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
8236                                                  sizeof(scp->sense_buffer));
8237                                /*
8238                                 * Note: The 'status_byte()' macro used by
8239                                 * target drivers defined in scsi.h shifts the
8240                                 * status byte returned by host drivers right
8241                                 * by 1 bit.  This is why target drivers also
8242                                 * use right shifted status byte definitions.
8243                                 * For instance target drivers use
8244                                 * CHECK_CONDITION, defined to 0x1, instead of
8245                                 * the SCSI defined check condition value of
8246                                 * 0x2. Host drivers are supposed to return
8247                                 * the status byte as it is defined by SCSI.
8248                                 */
8249                                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
8250                                    STATUS_BYTE(scsiqp->scsi_status);
8251                        } else {
8252                                scp->result = STATUS_BYTE(scsiqp->scsi_status);
8253                        }
8254                        break;
8255
8256                default:
8257                        /* Some other QHSTA error occurred. */
8258                        ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
8259                        scp->result = HOST_BYTE(DID_BAD_TARGET);
8260                        break;
8261                }
8262                break;
8263
8264        case QD_ABORTED_BY_HOST:
8265                ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
8266                scp->result =
8267                    HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
8268                break;
8269
8270        default:
8271                ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
8272                scp->result =
8273                    HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
8274                break;
8275        }
8276
8277        /*
8278         * If the 'init_tidmask' bit isn't already set for the target and the
8279         * current request finished normally, then set the bit for the target
8280         * to indicate that a device is present.
8281         */
8282        if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
8283            scsiqp->done_status == QD_NO_ERROR &&
8284            scsiqp->host_status == QHSTA_NO_ERROR) {
8285                boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
8286        }
8287
8288        asc_scsi_done(scp);
8289
8290        /*
8291         * Free all 'adv_sgblk_t' structures allocated for the request.
8292         */
8293        while ((sgblkp = reqp->sgblkp) != NULL) {
8294                /* Remove 'sgblkp' from the request list. */
8295                reqp->sgblkp = sgblkp->next_sgblkp;
8296
8297                /* Add 'sgblkp' to the board free list. */
8298                sgblkp->next_sgblkp = boardp->adv_sgblkp;
8299                boardp->adv_sgblkp = sgblkp;
8300        }
8301
8302        /*
8303         * Free the adv_req_t structure used with the command by adding
8304         * it back to the board free list.
8305         */
8306        reqp->next_reqp = boardp->adv_reqp;
8307        boardp->adv_reqp = reqp;
8308
8309        ASC_DBG(1, "done\n");
8310}
8311
8312/*
8313 * Adv Library Interrupt Service Routine
8314 *
8315 *  This function is called by a driver's interrupt service routine.
8316 *  The function disables and re-enables interrupts.
8317 *
8318 *  When a microcode idle command is completed, the ADV_DVC_VAR
8319 *  'idle_cmd_done' field is set to ADV_TRUE.
8320 *
8321 *  Note: AdvISR() can be called when interrupts are disabled or even
8322 *  when there is no hardware interrupt condition present. It will
8323 *  always check for completed idle commands and microcode requests.
8324 *  This is an important feature that shouldn't be changed because it
8325 *  allows commands to be completed from polling mode loops.
8326 *
8327 * Return:
8328 *   ADV_TRUE(1) - interrupt was pending
8329 *   ADV_FALSE(0) - no interrupt was pending
8330 */
8331static int AdvISR(ADV_DVC_VAR *asc_dvc)
8332{
8333        AdvPortAddr iop_base;
8334        uchar int_stat;
8335        ushort target_bit;
8336        ADV_CARR_T *free_carrp;
8337        ADV_VADDR irq_next_vpa;
8338        ADV_SCSI_REQ_Q *scsiq;
8339
8340        iop_base = asc_dvc->iop_base;
8341
8342        /* Reading the register clears the interrupt. */
8343        int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
8344
8345        if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
8346                         ADV_INTR_STATUS_INTRC)) == 0) {
8347                return ADV_FALSE;
8348        }
8349
8350        /*
8351         * Notify the driver of an asynchronous microcode condition by
8352         * calling the adv_async_callback function. The function
8353         * is passed the microcode ASC_MC_INTRB_CODE byte value.
8354         */
8355        if (int_stat & ADV_INTR_STATUS_INTRB) {
8356                uchar intrb_code;
8357
8358                AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
8359
8360                if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
8361                    asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
8362                        if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
8363                            asc_dvc->carr_pending_cnt != 0) {
8364                                AdvWriteByteRegister(iop_base, IOPB_TICKLE,
8365                                                     ADV_TICKLE_A);
8366                                if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
8367                                        AdvWriteByteRegister(iop_base,
8368                                                             IOPB_TICKLE,
8369                                                             ADV_TICKLE_NOP);
8370                                }
8371                        }
8372                }
8373
8374                adv_async_callback(asc_dvc, intrb_code);
8375        }
8376
8377        /*
8378         * Check if the IRQ stopper carrier contains a completed request.
8379         */
8380        while (((irq_next_vpa =
8381                 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
8382                /*
8383                 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
8384                 * The RISC will have set 'areq_vpa' to a virtual address.
8385                 *
8386                 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
8387                 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
8388                 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
8389                 * in AdvExeScsiQueue().
8390                 */
8391                scsiq = (ADV_SCSI_REQ_Q *)
8392                    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
8393
8394                /*
8395                 * Request finished with good status and the queue was not
8396                 * DMAed to host memory by the firmware. Set all status fields
8397                 * to indicate good status.
8398                 */
8399                if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
8400                        scsiq->done_status = QD_NO_ERROR;
8401                        scsiq->host_status = scsiq->scsi_status = 0;
8402                        scsiq->data_cnt = 0L;
8403                }
8404
8405                /*
8406                 * Advance the stopper pointer to the next carrier
8407                 * ignoring the lower four bits. Free the previous
8408                 * stopper carrier.
8409                 */
8410                free_carrp = asc_dvc->irq_sp;
8411                asc_dvc->irq_sp = (ADV_CARR_T *)
8412                    ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
8413
8414                free_carrp->next_vpa =
8415                    cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
8416                asc_dvc->carr_freelist = free_carrp;
8417                asc_dvc->carr_pending_cnt--;
8418
8419                target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
8420
8421                /*
8422                 * Clear request microcode control flag.
8423                 */
8424                scsiq->cntl = 0;
8425
8426                /*
8427                 * Notify the driver of the completed request by passing
8428                 * the ADV_SCSI_REQ_Q pointer to its callback function.
8429                 */
8430                scsiq->a_flag |= ADV_SCSIQ_DONE;
8431                adv_isr_callback(asc_dvc, scsiq);
8432                /*
8433                 * Note: After the driver callback function is called, 'scsiq'
8434                 * can no longer be referenced.
8435                 *
8436                 * Fall through and continue processing other completed
8437                 * requests...
8438                 */
8439        }
8440        return ADV_TRUE;
8441}
8442
8443static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
8444{
8445        if (asc_dvc->err_code == 0) {
8446                asc_dvc->err_code = err_code;
8447                AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
8448                                 err_code);
8449        }
8450        return err_code;
8451}
8452
8453static void AscAckInterrupt(PortAddr iop_base)
8454{
8455        uchar host_flag;
8456        uchar risc_flag;
8457        ushort loop;
8458
8459        loop = 0;
8460        do {
8461                risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
8462                if (loop++ > 0x7FFF) {
8463                        break;
8464                }
8465        } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
8466        host_flag =
8467            AscReadLramByte(iop_base,
8468                            ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
8469        AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8470                         (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
8471        AscSetChipStatus(iop_base, CIW_INT_ACK);
8472        loop = 0;
8473        while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
8474                AscSetChipStatus(iop_base, CIW_INT_ACK);
8475                if (loop++ > 3) {
8476                        break;
8477                }
8478        }
8479        AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
8480}
8481
8482static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
8483{
8484        const uchar *period_table;
8485        int max_index;
8486        int min_index;
8487        int i;
8488
8489        period_table = asc_dvc->sdtr_period_tbl;
8490        max_index = (int)asc_dvc->max_sdtr_index;
8491        min_index = (int)asc_dvc->min_sdtr_index;
8492        if ((syn_time <= period_table[max_index])) {
8493                for (i = min_index; i < (max_index - 1); i++) {
8494                        if (syn_time <= period_table[i]) {
8495                                return (uchar)i;
8496                        }
8497                }
8498                return (uchar)max_index;
8499        } else {
8500                return (uchar)(max_index + 1);
8501        }
8502}
8503
8504static uchar
8505AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
8506{
8507        EXT_MSG sdtr_buf;
8508        uchar sdtr_period_index;
8509        PortAddr iop_base;
8510
8511        iop_base = asc_dvc->iop_base;
8512        sdtr_buf.msg_type = EXTENDED_MESSAGE;
8513        sdtr_buf.msg_len = MS_SDTR_LEN;
8514        sdtr_buf.msg_req = EXTENDED_SDTR;
8515        sdtr_buf.xfer_period = sdtr_period;
8516        sdtr_offset &= ASC_SYN_MAX_OFFSET;
8517        sdtr_buf.req_ack_offset = sdtr_offset;
8518        sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8519        if (sdtr_period_index <= asc_dvc->max_sdtr_index) {
8520                AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8521                                        (uchar *)&sdtr_buf,
8522                                        sizeof(EXT_MSG) >> 1);
8523                return ((sdtr_period_index << 4) | sdtr_offset);
8524        } else {
8525                sdtr_buf.req_ack_offset = 0;
8526                AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG,
8527                                        (uchar *)&sdtr_buf,
8528                                        sizeof(EXT_MSG) >> 1);
8529                return 0;
8530        }
8531}
8532
8533static uchar
8534AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
8535{
8536        uchar byte;
8537        uchar sdtr_period_ix;
8538
8539        sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
8540        if (sdtr_period_ix > asc_dvc->max_sdtr_index)
8541                return 0xFF;
8542        byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
8543        return byte;
8544}
8545
8546static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
8547{
8548        ASC_SCSI_BIT_ID_TYPE org_id;
8549        int i;
8550        int sta = TRUE;
8551
8552        AscSetBank(iop_base, 1);
8553        org_id = AscReadChipDvcID(iop_base);
8554        for (i = 0; i <= ASC_MAX_TID; i++) {
8555                if (org_id == (0x01 << i))
8556                        break;
8557        }
8558        org_id = (ASC_SCSI_BIT_ID_TYPE) i;
8559        AscWriteChipDvcID(iop_base, id);
8560        if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
8561                AscSetBank(iop_base, 0);
8562                AscSetChipSyn(iop_base, sdtr_data);
8563                if (AscGetChipSyn(iop_base) != sdtr_data) {
8564                        sta = FALSE;
8565                }
8566        } else {
8567                sta = FALSE;
8568        }
8569        AscSetBank(iop_base, 1);
8570        AscWriteChipDvcID(iop_base, org_id);
8571        AscSetBank(iop_base, 0);
8572        return (sta);
8573}
8574
8575static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
8576{
8577        AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
8578        AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
8579}
8580
8581static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8582{
8583        EXT_MSG ext_msg;
8584        EXT_MSG out_msg;
8585        ushort halt_q_addr;
8586        int sdtr_accept;
8587        ushort int_halt_code;
8588        ASC_SCSI_BIT_ID_TYPE scsi_busy;
8589        ASC_SCSI_BIT_ID_TYPE target_id;
8590        PortAddr iop_base;
8591        uchar tag_code;
8592        uchar q_status;
8593        uchar halt_qp;
8594        uchar sdtr_data;
8595        uchar target_ix;
8596        uchar q_cntl, tid_no;
8597        uchar cur_dvc_qng;
8598        uchar asyn_sdtr;
8599        uchar scsi_status;
8600        struct asc_board *boardp;
8601
8602        BUG_ON(!asc_dvc->drv_ptr);
8603        boardp = asc_dvc->drv_ptr;
8604
8605        iop_base = asc_dvc->iop_base;
8606        int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8607
8608        halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8609        halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8610        target_ix = AscReadLramByte(iop_base,
8611                                    (ushort)(halt_q_addr +
8612                                             (ushort)ASC_SCSIQ_B_TARGET_IX));
8613        q_cntl = AscReadLramByte(iop_base,
8614                            (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8615        tid_no = ASC_TIX_TO_TID(target_ix);
8616        target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8617        if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8618                asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8619        } else {
8620                asyn_sdtr = 0;
8621        }
8622        if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8623                if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8624                        AscSetChipSDTR(iop_base, 0, tid_no);
8625                        boardp->sdtr_data[tid_no] = 0;
8626                }
8627                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8628                return (0);
8629        } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8630                if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8631                        AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8632                        boardp->sdtr_data[tid_no] = asyn_sdtr;
8633                }
8634                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8635                return (0);
8636        } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8637                AscMemWordCopyPtrFromLram(iop_base,
8638                                          ASCV_MSGIN_BEG,
8639                                          (uchar *)&ext_msg,
8640                                          sizeof(EXT_MSG) >> 1);
8641
8642                if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8643                    ext_msg.msg_req == EXTENDED_SDTR &&
8644                    ext_msg.msg_len == MS_SDTR_LEN) {
8645                        sdtr_accept = TRUE;
8646                        if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8647
8648                                sdtr_accept = FALSE;
8649                                ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8650                        }
8651                        if ((ext_msg.xfer_period <
8652                             asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index])
8653                            || (ext_msg.xfer_period >
8654                                asc_dvc->sdtr_period_tbl[asc_dvc->
8655                                                         max_sdtr_index])) {
8656                                sdtr_accept = FALSE;
8657                                ext_msg.xfer_period =
8658                                    asc_dvc->sdtr_period_tbl[asc_dvc->
8659                                                             min_sdtr_index];
8660                        }
8661                        if (sdtr_accept) {
8662                                sdtr_data =
8663                                    AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8664                                                   ext_msg.req_ack_offset);
8665                                if ((sdtr_data == 0xFF)) {
8666
8667                                        q_cntl |= QC_MSG_OUT;
8668                                        asc_dvc->init_sdtr &= ~target_id;
8669                                        asc_dvc->sdtr_done &= ~target_id;
8670                                        AscSetChipSDTR(iop_base, asyn_sdtr,
8671                                                       tid_no);
8672                                        boardp->sdtr_data[tid_no] = asyn_sdtr;
8673                                }
8674                        }
8675                        if (ext_msg.req_ack_offset == 0) {
8676
8677                                q_cntl &= ~QC_MSG_OUT;
8678                                asc_dvc->init_sdtr &= ~target_id;
8679                                asc_dvc->sdtr_done &= ~target_id;
8680                                AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8681                        } else {
8682                                if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8683                                        q_cntl &= ~QC_MSG_OUT;
8684                                        asc_dvc->sdtr_done |= target_id;
8685                                        asc_dvc->init_sdtr |= target_id;
8686                                        asc_dvc->pci_fix_asyn_xfer &=
8687                                            ~target_id;
8688                                        sdtr_data =
8689                                            AscCalSDTRData(asc_dvc,
8690                                                           ext_msg.xfer_period,
8691                                                           ext_msg.
8692                                                           req_ack_offset);
8693                                        AscSetChipSDTR(iop_base, sdtr_data,
8694                                                       tid_no);
8695                                        boardp->sdtr_data[tid_no] = sdtr_data;
8696                                } else {
8697                                        q_cntl |= QC_MSG_OUT;
8698                                        AscMsgOutSDTR(asc_dvc,
8699                                                      ext_msg.xfer_period,
8700                                                      ext_msg.req_ack_offset);
8701                                        asc_dvc->pci_fix_asyn_xfer &=
8702                                            ~target_id;
8703                                        sdtr_data =
8704                                            AscCalSDTRData(asc_dvc,
8705                                                           ext_msg.xfer_period,
8706                                                           ext_msg.
8707                                                           req_ack_offset);
8708                                        AscSetChipSDTR(iop_base, sdtr_data,
8709                                                       tid_no);
8710                                        boardp->sdtr_data[tid_no] = sdtr_data;
8711                                        asc_dvc->sdtr_done |= target_id;
8712                                        asc_dvc->init_sdtr |= target_id;
8713                                }
8714                        }
8715
8716                        AscWriteLramByte(iop_base,
8717                                         (ushort)(halt_q_addr +
8718                                                  (ushort)ASC_SCSIQ_B_CNTL),
8719                                         q_cntl);
8720                        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8721                        return (0);
8722                } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
8723                           ext_msg.msg_req == EXTENDED_WDTR &&
8724                           ext_msg.msg_len == MS_WDTR_LEN) {
8725
8726                        ext_msg.wdtr_width = 0;
8727                        AscMemWordCopyPtrToLram(iop_base,
8728                                                ASCV_MSGOUT_BEG,
8729                                                (uchar *)&ext_msg,
8730                                                sizeof(EXT_MSG) >> 1);
8731                        q_cntl |= QC_MSG_OUT;
8732                        AscWriteLramByte(iop_base,
8733                                         (ushort)(halt_q_addr +
8734                                                  (ushort)ASC_SCSIQ_B_CNTL),
8735                                         q_cntl);
8736                        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8737                        return (0);
8738                } else {
8739
8740                        ext_msg.msg_type = MESSAGE_REJECT;
8741                        AscMemWordCopyPtrToLram(iop_base,
8742                                                ASCV_MSGOUT_BEG,
8743                                                (uchar *)&ext_msg,
8744                                                sizeof(EXT_MSG) >> 1);
8745                        q_cntl |= QC_MSG_OUT;
8746                        AscWriteLramByte(iop_base,
8747                                         (ushort)(halt_q_addr +
8748                                                  (ushort)ASC_SCSIQ_B_CNTL),
8749                                         q_cntl);
8750                        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8751                        return (0);
8752                }
8753        } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8754
8755                q_cntl |= QC_REQ_SENSE;
8756
8757                if ((asc_dvc->init_sdtr & target_id) != 0) {
8758
8759                        asc_dvc->sdtr_done &= ~target_id;
8760
8761                        sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8762                        q_cntl |= QC_MSG_OUT;
8763                        AscMsgOutSDTR(asc_dvc,
8764                                      asc_dvc->
8765                                      sdtr_period_tbl[(sdtr_data >> 4) &
8766                                                      (uchar)(asc_dvc->
8767                                                              max_sdtr_index -
8768                                                              1)],
8769                                      (uchar)(sdtr_data & (uchar)
8770                                              ASC_SYN_MAX_OFFSET));
8771                }
8772
8773                AscWriteLramByte(iop_base,
8774                                 (ushort)(halt_q_addr +
8775                                          (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8776
8777                tag_code = AscReadLramByte(iop_base,
8778                                           (ushort)(halt_q_addr + (ushort)
8779                                                    ASC_SCSIQ_B_TAG_CODE));
8780                tag_code &= 0xDC;
8781                if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8782                    && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8783                    ) {
8784
8785                        tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8786                                     | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8787
8788                }
8789                AscWriteLramByte(iop_base,
8790                                 (ushort)(halt_q_addr +
8791                                          (ushort)ASC_SCSIQ_B_TAG_CODE),
8792                                 tag_code);
8793
8794                q_status = AscReadLramByte(iop_base,
8795                                           (ushort)(halt_q_addr + (ushort)
8796                                                    ASC_SCSIQ_B_STATUS));
8797                q_status |= (QS_READY | QS_BUSY);
8798                AscWriteLramByte(iop_base,
8799                                 (ushort)(halt_q_addr +
8800                                          (ushort)ASC_SCSIQ_B_STATUS),
8801                                 q_status);
8802
8803                scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8804                scsi_busy &= ~target_id;
8805                AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8806
8807                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8808                return (0);
8809        } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8810
8811                AscMemWordCopyPtrFromLram(iop_base,
8812                                          ASCV_MSGOUT_BEG,
8813                                          (uchar *)&out_msg,
8814                                          sizeof(EXT_MSG) >> 1);
8815
8816                if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
8817                    (out_msg.msg_len == MS_SDTR_LEN) &&
8818                    (out_msg.msg_req == EXTENDED_SDTR)) {
8819
8820                        asc_dvc->init_sdtr &= ~target_id;
8821                        asc_dvc->sdtr_done &= ~target_id;
8822                        AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8823                        boardp->sdtr_data[tid_no] = asyn_sdtr;
8824                }
8825                q_cntl &= ~QC_MSG_OUT;
8826                AscWriteLramByte(iop_base,
8827                                 (ushort)(halt_q_addr +
8828                                          (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8829                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8830                return (0);
8831        } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8832
8833                scsi_status = AscReadLramByte(iop_base,
8834                                              (ushort)((ushort)halt_q_addr +
8835                                                       (ushort)
8836                                                       ASC_SCSIQ_SCSI_STATUS));
8837                cur_dvc_qng =
8838                    AscReadLramByte(iop_base,
8839                                    (ushort)((ushort)ASC_QADR_BEG +
8840                                             (ushort)target_ix));
8841                if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8842
8843                        scsi_busy = AscReadLramByte(iop_base,
8844                                                    (ushort)ASCV_SCSIBUSY_B);
8845                        scsi_busy |= target_id;
8846                        AscWriteLramByte(iop_base,
8847                                         (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8848                        asc_dvc->queue_full_or_busy |= target_id;
8849
8850                        if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8851                                if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8852                                        cur_dvc_qng -= 1;
8853                                        asc_dvc->max_dvc_qng[tid_no] =
8854                                            cur_dvc_qng;
8855
8856                                        AscWriteLramByte(iop_base,
8857                                                         (ushort)((ushort)
8858                                                                  ASCV_MAX_DVC_QNG_BEG
8859                                                                  + (ushort)
8860                                                                  tid_no),
8861                                                         cur_dvc_qng);
8862
8863                                        /*
8864                                         * Set the device queue depth to the
8865                                         * number of active requests when the
8866                                         * QUEUE FULL condition was encountered.
8867                                         */
8868                                        boardp->queue_full |= target_id;
8869                                        boardp->queue_full_cnt[tid_no] =
8870                                            cur_dvc_qng;
8871                                }
8872                        }
8873                }
8874                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8875                return (0);
8876        }
8877#if CC_VERY_LONG_SG_LIST
8878        else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8879                uchar q_no;
8880                ushort q_addr;
8881                uchar sg_wk_q_no;
8882                uchar first_sg_wk_q_no;
8883                ASC_SCSI_Q *scsiq;      /* Ptr to driver request. */
8884                ASC_SG_HEAD *sg_head;   /* Ptr to driver SG request. */
8885                ASC_SG_LIST_Q scsi_sg_q;        /* Structure written to queue. */
8886                ushort sg_list_dwords;
8887                ushort sg_entry_cnt;
8888                uchar next_qp;
8889                int i;
8890
8891                q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8892                if (q_no == ASC_QLINK_END)
8893                        return 0;
8894
8895                q_addr = ASC_QNO_TO_QADDR(q_no);
8896
8897                /*
8898                 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8899                 * structure pointer using a macro provided by the driver.
8900                 * The ASC_SCSI_REQ pointer provides a pointer to the
8901                 * host ASC_SG_HEAD structure.
8902                 */
8903                /* Read request's SRB pointer. */
8904                scsiq = (ASC_SCSI_Q *)
8905                    ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8906                                                                    (ushort)
8907                                                                    (q_addr +
8908                                                                     ASC_SCSIQ_D_SRBPTR))));
8909
8910                /*
8911                 * Get request's first and working SG queue.
8912                 */
8913                sg_wk_q_no = AscReadLramByte(iop_base,
8914                                             (ushort)(q_addr +
8915                                                      ASC_SCSIQ_B_SG_WK_QP));
8916
8917                first_sg_wk_q_no = AscReadLramByte(iop_base,
8918                                                   (ushort)(q_addr +
8919                                                            ASC_SCSIQ_B_FIRST_SG_WK_QP));
8920
8921                /*
8922                 * Reset request's working SG queue back to the
8923                 * first SG queue.
8924                 */
8925                AscWriteLramByte(iop_base,
8926                                 (ushort)(q_addr +
8927                                          (ushort)ASC_SCSIQ_B_SG_WK_QP),
8928                                 first_sg_wk_q_no);
8929
8930                sg_head = scsiq->sg_head;
8931
8932                /*
8933                 * Set sg_entry_cnt to the number of SG elements
8934                 * that will be completed on this interrupt.
8935                 *
8936                 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8937                 * SG elements. The data_cnt and data_addr fields which
8938                 * add 1 to the SG element capacity are not used when
8939                 * restarting SG handling after a halt.
8940                 */
8941                if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8942                        sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8943
8944                        /*
8945                         * Keep track of remaining number of SG elements that
8946                         * will need to be handled on the next interrupt.
8947                         */
8948                        scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8949                } else {
8950                        sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8951                        scsiq->remain_sg_entry_cnt = 0;
8952                }
8953
8954                /*
8955                 * Copy SG elements into the list of allocated SG queues.
8956                 *
8957                 * Last index completed is saved in scsiq->next_sg_index.
8958                 */
8959                next_qp = first_sg_wk_q_no;
8960                q_addr = ASC_QNO_TO_QADDR(next_qp);
8961                scsi_sg_q.sg_head_qp = q_no;
8962                scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8963                for (i = 0; i < sg_head->queue_cnt; i++) {
8964                        scsi_sg_q.seq_no = i + 1;
8965                        if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8966                                sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8967                                sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8968                                /*
8969                                 * After very first SG queue RISC FW uses next
8970                                 * SG queue first element then checks sg_list_cnt
8971                                 * against zero and then decrements, so set
8972                                 * sg_list_cnt 1 less than number of SG elements
8973                                 * in each SG queue.
8974                                 */
8975                                scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8976                                scsi_sg_q.sg_cur_list_cnt =
8977                                    ASC_SG_LIST_PER_Q - 1;
8978                        } else {
8979                                /*
8980                                 * This is the last SG queue in the list of
8981                                 * allocated SG queues. If there are more
8982                                 * SG elements than will fit in the allocated
8983                                 * queues, then set the QCSG_SG_XFER_MORE flag.
8984                                 */
8985                                if (scsiq->remain_sg_entry_cnt != 0) {
8986                                        scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8987                                } else {
8988                                        scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8989                                }
8990                                /* equals sg_entry_cnt * 2 */
8991                                sg_list_dwords = sg_entry_cnt << 1;
8992                                scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8993                                scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8994                                sg_entry_cnt = 0;
8995                        }
8996
8997                        scsi_sg_q.q_no = next_qp;
8998                        AscMemWordCopyPtrToLram(iop_base,
8999                                                q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9000                                                (uchar *)&scsi_sg_q,
9001                                                sizeof(ASC_SG_LIST_Q) >> 1);
9002
9003                        AscMemDWordCopyPtrToLram(iop_base,
9004                                                 q_addr + ASC_SGQ_LIST_BEG,
9005                                                 (uchar *)&sg_head->
9006                                                 sg_list[scsiq->next_sg_index],
9007                                                 sg_list_dwords);
9008
9009                        scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
9010
9011                        /*
9012                         * If the just completed SG queue contained the
9013                         * last SG element, then no more SG queues need
9014                         * to be written.
9015                         */
9016                        if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
9017                                break;
9018                        }
9019
9020                        next_qp = AscReadLramByte(iop_base,
9021                                                  (ushort)(q_addr +
9022                                                           ASC_SCSIQ_B_FWD));
9023                        q_addr = ASC_QNO_TO_QADDR(next_qp);
9024                }
9025
9026                /*
9027                 * Clear the halt condition so the RISC will be restarted
9028                 * after the return.
9029                 */
9030                AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9031                return (0);
9032        }
9033#endif /* CC_VERY_LONG_SG_LIST */
9034        return (0);
9035}
9036
9037/*
9038 * void
9039 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9040 *
9041 * Calling/Exit State:
9042 *    none
9043 *
9044 * Description:
9045 *     Input an ASC_QDONE_INFO structure from the chip
9046 */
9047static void
9048DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9049{
9050        int i;
9051        ushort word;
9052
9053        AscSetChipLramAddr(iop_base, s_addr);
9054        for (i = 0; i < 2 * words; i += 2) {
9055                if (i == 10) {
9056                        continue;
9057                }
9058                word = inpw(iop_base + IOP_RAM_DATA);
9059                inbuf[i] = word & 0xff;
9060                inbuf[i + 1] = (word >> 8) & 0xff;
9061        }
9062        ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9063}
9064
9065static uchar
9066_AscCopyLramScsiDoneQ(PortAddr iop_base,
9067                      ushort q_addr,
9068                      ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
9069{
9070        ushort _val;
9071        uchar sg_queue_cnt;
9072
9073        DvcGetQinfo(iop_base,
9074                    q_addr + ASC_SCSIQ_DONE_INFO_BEG,
9075                    (uchar *)scsiq,
9076                    (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
9077
9078        _val = AscReadLramWord(iop_base,
9079                               (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
9080        scsiq->q_status = (uchar)_val;
9081        scsiq->q_no = (uchar)(_val >> 8);
9082        _val = AscReadLramWord(iop_base,
9083                               (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
9084        scsiq->cntl = (uchar)_val;
9085        sg_queue_cnt = (uchar)(_val >> 8);
9086        _val = AscReadLramWord(iop_base,
9087                               (ushort)(q_addr +
9088                                        (ushort)ASC_SCSIQ_B_SENSE_LEN));
9089        scsiq->sense_len = (uchar)_val;
9090        scsiq->extra_bytes = (uchar)(_val >> 8);
9091
9092        /*
9093         * Read high word of remain bytes from alternate location.
9094         */
9095        scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9096                                                          (ushort)(q_addr +
9097                                                                   (ushort)
9098                                                                   ASC_SCSIQ_W_ALT_DC1)))
9099                               << 16);
9100        /*
9101         * Read low word of remain bytes from original location.
9102         */
9103        scsiq->remain_bytes += AscReadLramWord(iop_base,
9104                                               (ushort)(q_addr + (ushort)
9105                                                        ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9106
9107        scsiq->remain_bytes &= max_dma_count;
9108        return sg_queue_cnt;
9109}
9110
9111/*
9112 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
9113 *
9114 * Interrupt callback function for the Narrow SCSI Asc Library.
9115 */
9116static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
9117{
9118        struct asc_board *boardp;
9119        struct scsi_cmnd *scp;
9120        struct Scsi_Host *shost;
9121
9122        ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
9123        ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
9124
9125        scp = advansys_srb_to_ptr(asc_dvc_varp, qdonep->d2.srb_ptr);
9126        if (!scp)
9127                return;
9128
9129        ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
9130
9131        shost = scp->device->host;
9132        ASC_STATS(shost, callback);
9133        ASC_DBG(1, "shost 0x%p\n", shost);
9134
9135        boardp = shost_priv(shost);
9136        BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
9137
9138        dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
9139                        sizeof(scp->sense_buffer), DMA_FROM_DEVICE);
9140        /*
9141         * 'qdonep' contains the command's ending status.
9142         */
9143        switch (qdonep->d3.done_stat) {
9144        case QD_NO_ERROR:
9145                ASC_DBG(2, "QD_NO_ERROR\n");
9146                scp->result = 0;
9147
9148                /*
9149                 * Check for an underrun condition.
9150                 *
9151                 * If there was no error and an underrun condition, then
9152                 * return the number of underrun bytes.
9153                 */
9154                if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 &&
9155                    qdonep->remain_bytes <= scsi_bufflen(scp)) {
9156                        ASC_DBG(1, "underrun condition %u bytes\n",
9157                                 (unsigned)qdonep->remain_bytes);
9158                        scsi_set_resid(scp, qdonep->remain_bytes);
9159                }
9160                break;
9161
9162        case QD_WITH_ERROR:
9163                ASC_DBG(2, "QD_WITH_ERROR\n");
9164                switch (qdonep->d3.host_stat) {
9165                case QHSTA_NO_ERROR:
9166                        if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
9167                                ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
9168                                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
9169                                                  sizeof(scp->sense_buffer));
9170                                /*
9171                                 * Note: The 'status_byte()' macro used by
9172                                 * target drivers defined in scsi.h shifts the
9173                                 * status byte returned by host drivers right
9174                                 * by 1 bit.  This is why target drivers also
9175                                 * use right shifted status byte definitions.
9176                                 * For instance target drivers use
9177                                 * CHECK_CONDITION, defined to 0x1, instead of
9178                                 * the SCSI defined check condition value of
9179                                 * 0x2. Host drivers are supposed to return
9180                                 * the status byte as it is defined by SCSI.
9181                                 */
9182                                scp->result = DRIVER_BYTE(DRIVER_SENSE) |
9183                                    STATUS_BYTE(qdonep->d3.scsi_stat);
9184                        } else {
9185                                scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
9186                        }
9187                        break;
9188
9189                default:
9190                        /* QHSTA error occurred */
9191                        ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
9192                        scp->result = HOST_BYTE(DID_BAD_TARGET);
9193                        break;
9194                }
9195                break;
9196
9197        case QD_ABORTED_BY_HOST:
9198                ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
9199                scp->result =
9200                    HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
9201                                                    scsi_msg) |
9202                    STATUS_BYTE(qdonep->d3.scsi_stat);
9203                break;
9204
9205        default:
9206                ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
9207                scp->result =
9208                    HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
9209                                                    scsi_msg) |
9210                    STATUS_BYTE(qdonep->d3.scsi_stat);
9211                break;
9212        }
9213
9214        /*
9215         * If the 'init_tidmask' bit isn't already set for the target and the
9216         * current request finished normally, then set the bit for the target
9217         * to indicate that a device is present.
9218         */
9219        if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
9220            qdonep->d3.done_stat == QD_NO_ERROR &&
9221            qdonep->d3.host_stat == QHSTA_NO_ERROR) {
9222                boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
9223        }
9224
9225        asc_scsi_done(scp);
9226}
9227
9228static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9229{
9230        uchar next_qp;
9231        uchar n_q_used;
9232        uchar sg_list_qp;
9233        uchar sg_queue_cnt;
9234        uchar q_cnt;
9235        uchar done_q_tail;
9236        uchar tid_no;
9237        ASC_SCSI_BIT_ID_TYPE scsi_busy;
9238        ASC_SCSI_BIT_ID_TYPE target_id;
9239        PortAddr iop_base;
9240        ushort q_addr;
9241        ushort sg_q_addr;
9242        uchar cur_target_qng;
9243        ASC_QDONE_INFO scsiq_buf;
9244        ASC_QDONE_INFO *scsiq;
9245        int false_overrun;
9246
9247        iop_base = asc_dvc->iop_base;
9248        n_q_used = 1;
9249        scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9250        done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9251        q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9252        next_qp = AscReadLramByte(iop_base,
9253                                  (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9254        if (next_qp != ASC_QLINK_END) {
9255                AscPutVarDoneQTail(iop_base, next_qp);
9256                q_addr = ASC_QNO_TO_QADDR(next_qp);
9257                sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9258                                                     asc_dvc->max_dma_count);
9259                AscWriteLramByte(iop_base,
9260                                 (ushort)(q_addr +
9261                                          (ushort)ASC_SCSIQ_B_STATUS),
9262                                 (uchar)(scsiq->
9263                                         q_status & (uchar)~(QS_READY |
9264                                                             QS_ABORTED)));
9265                tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9266                target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9267                if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9268                        sg_q_addr = q_addr;
9269                        sg_list_qp = next_qp;
9270                        for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9271                                sg_list_qp = AscReadLramByte(iop_base,
9272                                                             (ushort)(sg_q_addr
9273                                                                      + (ushort)
9274                                                                      ASC_SCSIQ_B_FWD));
9275                                sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9276                                if (sg_list_qp == ASC_QLINK_END) {
9277                                        AscSetLibErrorCode(asc_dvc,
9278                                                           ASCQ_ERR_SG_Q_LINKS);
9279                                        scsiq->d3.done_stat = QD_WITH_ERROR;
9280                                        scsiq->d3.host_stat =
9281                                            QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9282                                        goto FATAL_ERR_QDONE;
9283                                }
9284                                AscWriteLramByte(iop_base,
9285                                                 (ushort)(sg_q_addr + (ushort)
9286                                                          ASC_SCSIQ_B_STATUS),
9287                                                 QS_FREE);
9288                        }
9289                        n_q_used = sg_queue_cnt + 1;
9290                        AscPutVarDoneQTail(iop_base, sg_list_qp);
9291                }
9292                if (asc_dvc->queue_full_or_busy & target_id) {
9293                        cur_target_qng = AscReadLramByte(iop_base,
9294                                                         (ushort)((ushort)
9295                                                                  ASC_QADR_BEG
9296                                                                  + (ushort)
9297                                                                  scsiq->d2.
9298                                                                  target_ix));
9299                        if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9300                                scsi_busy = AscReadLramByte(iop_base, (ushort)
9301                                                            ASCV_SCSIBUSY_B);
9302                                scsi_busy &= ~target_id;
9303                                AscWriteLramByte(iop_base,
9304                                                 (ushort)ASCV_SCSIBUSY_B,
9305                                                 scsi_busy);
9306                                asc_dvc->queue_full_or_busy &= ~target_id;
9307                        }
9308                }
9309                if (asc_dvc->cur_total_qng >= n_q_used) {
9310                        asc_dvc->cur_total_qng -= n_q_used;
9311                        if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9312                                asc_dvc->cur_dvc_qng[tid_no]--;
9313                        }
9314                } else {
9315                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9316                        scsiq->d3.done_stat = QD_WITH_ERROR;
9317                        goto FATAL_ERR_QDONE;
9318                }
9319                if ((scsiq->d2.srb_ptr == 0UL) ||
9320                    ((scsiq->q_status & QS_ABORTED) != 0)) {
9321                        return (0x11);
9322                } else if (scsiq->q_status == QS_DONE) {
9323                        false_overrun = FALSE;
9324                        if (scsiq->extra_bytes != 0) {
9325                                scsiq->remain_bytes +=
9326                                    (ADV_DCNT)scsiq->extra_bytes;
9327                        }
9328                        if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9329                                if (scsiq->d3.host_stat ==
9330                                    QHSTA_M_DATA_OVER_RUN) {
9331                                        if ((scsiq->
9332                                             cntl & (QC_DATA_IN | QC_DATA_OUT))
9333                                            == 0) {
9334                                                scsiq->d3.done_stat =
9335                                                    QD_NO_ERROR;
9336                                                scsiq->d3.host_stat =
9337                                                    QHSTA_NO_ERROR;
9338                                        } else if (false_overrun) {
9339                                                scsiq->d3.done_stat =
9340                                                    QD_NO_ERROR;
9341                                                scsiq->d3.host_stat =
9342                                                    QHSTA_NO_ERROR;
9343                                        }
9344                                } else if (scsiq->d3.host_stat ==
9345                                           QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9346                                        AscStopChip(iop_base);
9347                                        AscSetChipControl(iop_base,
9348                                                          (uchar)(CC_SCSI_RESET
9349                                                                  | CC_HALT));
9350                                        udelay(60);
9351                                        AscSetChipControl(iop_base, CC_HALT);
9352                                        AscSetChipStatus(iop_base,
9353                                                         CIW_CLR_SCSI_RESET_INT);
9354                                        AscSetChipStatus(iop_base, 0);
9355                                        AscSetChipControl(iop_base, 0);
9356                                }
9357                        }
9358                        if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9359                                asc_isr_callback(asc_dvc, scsiq);
9360                        } else {
9361                                if ((AscReadLramByte(iop_base,
9362                                                     (ushort)(q_addr + (ushort)
9363                                                              ASC_SCSIQ_CDB_BEG))
9364                                     == START_STOP)) {
9365                                        asc_dvc->unit_not_ready &= ~target_id;
9366                                        if (scsiq->d3.done_stat != QD_NO_ERROR) {
9367                                                asc_dvc->start_motor &=
9368                                                    ~target_id;
9369                                        }
9370                                }
9371                        }
9372                        return (1);
9373                } else {
9374                        AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9375 FATAL_ERR_QDONE:
9376                        if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9377                                asc_isr_callback(asc_dvc, scsiq);
9378                        }
9379                        return (0x80);
9380                }
9381        }
9382        return (0);
9383}
9384
9385static int AscISR(ASC_DVC_VAR *asc_dvc)
9386{
9387        ASC_CS_TYPE chipstat;
9388        PortAddr iop_base;
9389        ushort saved_ram_addr;
9390        uchar ctrl_reg;
9391        uchar saved_ctrl_reg;
9392        int int_pending;
9393        int status;
9394        uchar host_flag;
9395
9396        iop_base = asc_dvc->iop_base;
9397        int_pending = FALSE;
9398
9399        if (AscIsIntPending(iop_base) == 0)
9400                return int_pending;
9401
9402        if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) {
9403                return ERR;
9404        }
9405        if (asc_dvc->in_critical_cnt != 0) {
9406                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9407                return ERR;
9408        }
9409        if (asc_dvc->is_in_int) {
9410                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9411                return ERR;
9412        }
9413        asc_dvc->is_in_int = TRUE;
9414        ctrl_reg = AscGetChipControl(iop_base);
9415        saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9416                                       CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9417        chipstat = AscGetChipStatus(iop_base);
9418        if (chipstat & CSW_SCSI_RESET_LATCH) {
9419                if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9420                        int i = 10;
9421                        int_pending = TRUE;
9422                        asc_dvc->sdtr_done = 0;
9423                        saved_ctrl_reg &= (uchar)(~CC_HALT);
9424                        while ((AscGetChipStatus(iop_base) &
9425                                CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9426                                mdelay(100);
9427                        }
9428                        AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9429                        AscSetChipControl(iop_base, CC_HALT);
9430                        AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9431                        AscSetChipStatus(iop_base, 0);
9432                        chipstat = AscGetChipStatus(iop_base);
9433                }
9434        }
9435        saved_ram_addr = AscGetChipLramAddr(iop_base);
9436        host_flag = AscReadLramByte(iop_base,
9437                                    ASCV_HOST_FLAG_B) &
9438            (uchar)(~ASC_HOST_FLAG_IN_ISR);
9439        AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9440                         (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9441        if ((chipstat & CSW_INT_PENDING) || (int_pending)) {
9442                AscAckInterrupt(iop_base);
9443                int_pending = TRUE;
9444                if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9445                        if (AscIsrChipHalted(asc_dvc) == ERR) {
9446                                goto ISR_REPORT_QDONE_FATAL_ERROR;
9447                        } else {
9448                                saved_ctrl_reg &= (uchar)(~CC_HALT);
9449                        }
9450                } else {
9451 ISR_REPORT_QDONE_FATAL_ERROR:
9452                        if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9453                                while (((status =
9454                                         AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9455                                }
9456                        } else {
9457                                do {
9458                                        if ((status =
9459                                             AscIsrQDone(asc_dvc)) == 1) {
9460                                                break;
9461                                        }
9462                                } while (status == 0x11);
9463                        }
9464                        if ((status & 0x80) != 0)
9465                                int_pending = ERR;
9466                }
9467        }
9468        AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9469        AscSetChipLramAddr(iop_base, saved_ram_addr);
9470        AscSetChipControl(iop_base, saved_ctrl_reg);
9471        asc_dvc->is_in_int = FALSE;
9472        return int_pending;
9473}
9474
9475/*
9476 * advansys_reset()
9477 *
9478 * Reset the bus associated with the command 'scp'.
9479 *
9480 * This function runs its own thread. Interrupts must be blocked but
9481 * sleeping is allowed and no locking other than for host structures is
9482 * required. Returns SUCCESS or FAILED.
9483 */
9484static int advansys_reset(struct scsi_cmnd *scp)
9485{
9486        struct Scsi_Host *shost = scp->device->host;
9487        struct asc_board *boardp = shost_priv(shost);
9488        unsigned long flags;
9489        int status;
9490        int ret = SUCCESS;
9491
9492        ASC_DBG(1, "0x%p\n", scp);
9493
9494        ASC_STATS(shost, reset);
9495
9496        scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n");
9497
9498        if (ASC_NARROW_BOARD(boardp)) {
9499                ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9500
9501                /* Reset the chip and SCSI bus. */
9502                ASC_DBG(1, "before AscInitAsc1000Driver()\n");
9503                status = AscInitAsc1000Driver(asc_dvc);
9504
9505                /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
9506                if (asc_dvc->err_code) {
9507                        scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
9508                                    "0x%x\n", asc_dvc->err_code);
9509                        ret = FAILED;
9510                } else if (status) {
9511                        scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
9512                                    "0x%x\n", status);
9513                } else {
9514                        scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9515                                    "successful\n");
9516                }
9517
9518                ASC_DBG(1, "after AscInitAsc1000Driver()\n");
9519                spin_lock_irqsave(shost->host_lock, flags);
9520        } else {
9521                /*
9522                 * If the suggest reset bus flags are set, then reset the bus.
9523                 * Otherwise only reset the device.
9524                 */
9525                ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
9526
9527                /*
9528                 * Reset the target's SCSI bus.
9529                 */
9530                ASC_DBG(1, "before AdvResetChipAndSB()\n");
9531                switch (AdvResetChipAndSB(adv_dvc)) {
9532                case ASC_TRUE:
9533                        scmd_printk(KERN_INFO, scp, "SCSI bus reset "
9534                                    "successful\n");
9535                        break;
9536                case ASC_FALSE:
9537                default:
9538                        scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n");
9539                        ret = FAILED;
9540                        break;
9541                }
9542                spin_lock_irqsave(shost->host_lock, flags);
9543                AdvISR(adv_dvc);
9544        }
9545
9546        /* Save the time of the most recently completed reset. */
9547        boardp->last_reset = jiffies;
9548        spin_unlock_irqrestore(shost->host_lock, flags);
9549
9550        ASC_DBG(1, "ret %d\n", ret);
9551
9552        return ret;
9553}
9554
9555/*
9556 * advansys_biosparam()
9557 *
9558 * Translate disk drive geometry if the "BIOS greater than 1 GB"
9559 * support is enabled for a drive.
9560 *
9561 * ip (information pointer) is an int array with the following definition:
9562 * ip[0]: heads
9563 * ip[1]: sectors
9564 * ip[2]: cylinders
9565 */
9566static int
9567advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
9568                   sector_t capacity, int ip[])
9569{
9570        struct asc_board *boardp = shost_priv(sdev->host);
9571
9572        ASC_DBG(1, "begin\n");
9573        ASC_STATS(sdev->host, biosparam);
9574        if (ASC_NARROW_BOARD(boardp)) {
9575                if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
9576                     ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
9577                        ip[0] = 255;
9578                        ip[1] = 63;
9579                } else {
9580                        ip[0] = 64;
9581                        ip[1] = 32;
9582                }
9583        } else {
9584                if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
9585                     BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
9586                        ip[0] = 255;
9587                        ip[1] = 63;
9588                } else {
9589                        ip[0] = 64;
9590                        ip[1] = 32;
9591                }
9592        }
9593        ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
9594        ASC_DBG(1, "end\n");
9595        return 0;
9596}
9597
9598/*
9599 * First-level interrupt handler.
9600 *
9601 * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host.
9602 */
9603static irqreturn_t advansys_interrupt(int irq, void *dev_id)
9604{
9605        struct Scsi_Host *shost = dev_id;
9606        struct asc_board *boardp = shost_priv(shost);
9607        irqreturn_t result = IRQ_NONE;
9608
9609        ASC_DBG(2, "boardp 0x%p\n", boardp);
9610        spin_lock(shost->host_lock);
9611        if (ASC_NARROW_BOARD(boardp)) {
9612                if (AscIsIntPending(shost->io_port)) {
9613                        result = IRQ_HANDLED;
9614                        ASC_STATS(shost, interrupt);
9615                        ASC_DBG(1, "before AscISR()\n");
9616                        AscISR(&boardp->dvc_var.asc_dvc_var);
9617                }
9618        } else {
9619                ASC_DBG(1, "before AdvISR()\n");
9620                if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
9621                        result = IRQ_HANDLED;
9622                        ASC_STATS(shost, interrupt);
9623                }
9624        }
9625        spin_unlock(shost->host_lock);
9626
9627        ASC_DBG(1, "end\n");
9628        return result;
9629}
9630
9631static int AscHostReqRiscHalt(PortAddr iop_base)
9632{
9633        int count = 0;
9634        int sta = 0;
9635        uchar saved_stop_code;
9636
9637        if (AscIsChipHalted(iop_base))
9638                return (1);
9639        saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
9640        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
9641                         ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
9642        do {
9643                if (AscIsChipHalted(iop_base)) {
9644                        sta = 1;
9645                        break;
9646                }
9647                mdelay(100);
9648        } while (count++ < 20);
9649        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
9650        return (sta);
9651}
9652
9653static int
9654AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9655{
9656        int sta = FALSE;
9657
9658        if (AscHostReqRiscHalt(iop_base)) {
9659                sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9660                AscStartChip(iop_base);
9661        }
9662        return sta;
9663}
9664
9665static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
9666{
9667        char type = sdev->type;
9668        ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
9669
9670        if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN))
9671                return;
9672        if (asc_dvc->init_sdtr & tid_bits)
9673                return;
9674
9675        if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
9676                asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
9677
9678        asc_dvc->pci_fix_asyn_xfer |= tid_bits;
9679        if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) ||
9680            (type == TYPE_ROM) || (type == TYPE_TAPE))
9681                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
9682
9683        if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
9684                AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id,
9685                                        ASYN_SDTR_DATA_FIX_PCI_REV_AB);
9686}
9687
9688static void
9689advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
9690{
9691        ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
9692        ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
9693
9694        if (sdev->lun == 0) {
9695                ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
9696                if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
9697                        asc_dvc->init_sdtr |= tid_bit;
9698                } else {
9699                        asc_dvc->init_sdtr &= ~tid_bit;
9700                }
9701
9702                if (orig_init_sdtr != asc_dvc->init_sdtr)
9703                        AscAsyncFix(asc_dvc, sdev);
9704        }
9705
9706        if (sdev->tagged_supported) {
9707                if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
9708                        if (sdev->lun == 0) {
9709                                asc_dvc->cfg->can_tagged_qng |= tid_bit;
9710                                asc_dvc->use_tagged_qng |= tid_bit;
9711                        }
9712                        scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9713                                                asc_dvc->max_dvc_qng[sdev->id]);
9714                }
9715        } else {
9716                if (sdev->lun == 0) {
9717                        asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
9718                        asc_dvc->use_tagged_qng &= ~tid_bit;
9719                }
9720                scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9721        }
9722
9723        if ((sdev->lun == 0) &&
9724            (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
9725                AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
9726                                 asc_dvc->cfg->disc_enable);
9727                AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
9728                                 asc_dvc->use_tagged_qng);
9729                AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
9730                                 asc_dvc->cfg->can_tagged_qng);
9731
9732                asc_dvc->max_dvc_qng[sdev->id] =
9733                                        asc_dvc->cfg->max_tag_qng[sdev->id];
9734                AscWriteLramByte(asc_dvc->iop_base,
9735                                 (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
9736                                 asc_dvc->max_dvc_qng[sdev->id]);
9737        }
9738}
9739
9740/*
9741 * Wide Transfers
9742 *
9743 * If the EEPROM enabled WDTR for the device and the device supports wide
9744 * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
9745 * write the new value to the microcode.
9746 */
9747static void
9748advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
9749{
9750        unsigned short cfg_word;
9751        AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9752        if ((cfg_word & tidmask) != 0)
9753                return;
9754
9755        cfg_word |= tidmask;
9756        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
9757
9758        /*
9759         * Clear the microcode SDTR and WDTR negotiation done indicators for
9760         * the target to cause it to negotiate with the new setting set above.
9761         * WDTR when accepted causes the target to enter asynchronous mode, so
9762         * SDTR must be negotiated.
9763         */
9764        AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9765        cfg_word &= ~tidmask;
9766        AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9767        AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9768        cfg_word &= ~tidmask;
9769        AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
9770}
9771
9772/*
9773 * Synchronous Transfers
9774 *
9775 * If the EEPROM enabled SDTR for the device and the device
9776 * supports synchronous transfers, then turn on the device's
9777 * 'sdtr_able' bit. Write the new value to the microcode.
9778 */
9779static void
9780advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
9781{
9782        unsigned short cfg_word;
9783        AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9784        if ((cfg_word & tidmask) != 0)
9785                return;
9786
9787        cfg_word |= tidmask;
9788        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
9789
9790        /*
9791         * Clear the microcode "SDTR negotiation" done indicator for the
9792         * target to cause it to negotiate with the new setting set above.
9793         */
9794        AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9795        cfg_word &= ~tidmask;
9796        AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
9797}
9798
9799/*
9800 * PPR (Parallel Protocol Request) Capable
9801 *
9802 * If the device supports DT mode, then it must be PPR capable.
9803 * The PPR message will be used in place of the SDTR and WDTR
9804 * messages to negotiate synchronous speed and offset, transfer
9805 * width, and protocol options.
9806 */
9807static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
9808                                AdvPortAddr iop_base, unsigned short tidmask)
9809{
9810        AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9811        adv_dvc->ppr_able |= tidmask;
9812        AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
9813}
9814
9815static void
9816advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
9817{
9818        AdvPortAddr iop_base = adv_dvc->iop_base;
9819        unsigned short tidmask = 1 << sdev->id;
9820
9821        if (sdev->lun == 0) {
9822                /*
9823                 * Handle WDTR, SDTR, and Tag Queuing. If the feature
9824                 * is enabled in the EEPROM and the device supports the
9825                 * feature, then enable it in the microcode.
9826                 */
9827
9828                if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
9829                        advansys_wide_enable_wdtr(iop_base, tidmask);
9830                if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
9831                        advansys_wide_enable_sdtr(iop_base, tidmask);
9832                if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
9833                        advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
9834
9835                /*
9836                 * Tag Queuing is disabled for the BIOS which runs in polled
9837                 * mode and would see no benefit from Tag Queuing. Also by
9838                 * disabling Tag Queuing in the BIOS devices with Tag Queuing
9839                 * bugs will at least work with the BIOS.
9840                 */
9841                if ((adv_dvc->tagqng_able & tidmask) &&
9842                    sdev->tagged_supported) {
9843                        unsigned short cfg_word;
9844                        AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
9845                        cfg_word |= tidmask;
9846                        AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
9847                                         cfg_word);
9848                        AdvWriteByteLram(iop_base,
9849                                         ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
9850                                         adv_dvc->max_dvc_qng);
9851                }
9852        }
9853
9854        if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
9855                scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
9856                                        adv_dvc->max_dvc_qng);
9857        } else {
9858                scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
9859        }
9860}
9861
9862/*
9863 * Set the number of commands to queue per device for the
9864 * specified host adapter.
9865 */
9866static int advansys_slave_configure(struct scsi_device *sdev)
9867{
9868        struct asc_board *boardp = shost_priv(sdev->host);
9869
9870        if (ASC_NARROW_BOARD(boardp))
9871                advansys_narrow_slave_configure(sdev,
9872                                                &boardp->dvc_var.asc_dvc_var);
9873        else
9874                advansys_wide_slave_configure(sdev,
9875                                                &boardp->dvc_var.adv_dvc_var);
9876
9877        return 0;
9878}
9879
9880static __le32 advansys_get_sense_buffer_dma(struct scsi_cmnd *scp)
9881{
9882        struct asc_board *board = shost_priv(scp->device->host);
9883        scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer,
9884                                sizeof(scp->sense_buffer), DMA_FROM_DEVICE);
9885        dma_cache_sync(board->dev, scp->sense_buffer,
9886                                sizeof(scp->sense_buffer), DMA_FROM_DEVICE);
9887        return cpu_to_le32(scp->SCp.dma_handle);
9888}
9889
9890static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
9891                        struct asc_scsi_q *asc_scsi_q)
9892{
9893        struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var;
9894        int use_sg;
9895
9896        memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
9897
9898        /*
9899         * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
9900         */
9901        asc_scsi_q->q2.srb_ptr = advansys_ptr_to_srb(asc_dvc, scp);
9902        if (asc_scsi_q->q2.srb_ptr == BAD_SRB) {
9903                scp->result = HOST_BYTE(DID_SOFT_ERROR);
9904                return ASC_ERROR;
9905        }
9906
9907        /*
9908         * Build the ASC_SCSI_Q request.
9909         */
9910        asc_scsi_q->cdbptr = &scp->cmnd[0];
9911        asc_scsi_q->q2.cdb_len = scp->cmd_len;
9912        asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
9913        asc_scsi_q->q1.target_lun = scp->device->lun;
9914        asc_scsi_q->q2.target_ix =
9915            ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
9916        asc_scsi_q->q1.sense_addr = advansys_get_sense_buffer_dma(scp);
9917        asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
9918
9919        /*
9920         * If there are any outstanding requests for the current target,
9921         * then every 255th request send an ORDERED request. This heuristic
9922         * tries to retain the benefit of request sorting while preventing
9923         * request starvation. 255 is the max number of tags or pending commands
9924         * a device may have outstanding.
9925         *
9926         * The request count is incremented below for every successfully
9927         * started request.
9928         *
9929         */
9930        if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) &&
9931            (boardp->reqcnt[scp->device->id] % 255) == 0) {
9932                asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
9933        } else {
9934                asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
9935        }
9936
9937        /* Build ASC_SCSI_Q */
9938        use_sg = scsi_dma_map(scp);
9939        if (use_sg != 0) {
9940                int sgcnt;
9941                struct scatterlist *slp;
9942                struct asc_sg_head *asc_sg_head;
9943
9944                if (use_sg > scp->device->host->sg_tablesize) {
9945                        scmd_printk(KERN_ERR, scp, "use_sg %d > "
9946                                "sg_tablesize %d\n", use_sg,
9947                                scp->device->host->sg_tablesize);
9948                        scsi_dma_unmap(scp);
9949                        scp->result = HOST_BYTE(DID_ERROR);
9950                        return ASC_ERROR;
9951                }
9952
9953                asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
9954                        use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
9955                if (!asc_sg_head) {
9956                        scsi_dma_unmap(scp);
9957                        scp->result = HOST_BYTE(DID_SOFT_ERROR);
9958                        return ASC_ERROR;
9959                }
9960
9961                asc_scsi_q->q1.cntl |= QC_SG_HEAD;
9962                asc_scsi_q->sg_head = asc_sg_head;
9963                asc_scsi_q->q1.data_cnt = 0;
9964                asc_scsi_q->q1.data_addr = 0;
9965                /* This is a byte value, otherwise it would need to be swapped. */
9966                asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
9967                ASC_STATS_ADD(scp->device->host, xfer_elem,
9968                              asc_sg_head->entry_cnt);
9969
9970                /*
9971                 * Convert scatter-gather list into ASC_SG_HEAD list.
9972                 */
9973                scsi_for_each_sg(scp, slp, use_sg, sgcnt) {
9974                        asc_sg_head->sg_list[sgcnt].addr =
9975                            cpu_to_le32(sg_dma_address(slp));
9976                        asc_sg_head->sg_list[sgcnt].bytes =
9977                            cpu_to_le32(sg_dma_len(slp));
9978                        ASC_STATS_ADD(scp->device->host, xfer_sect,
9979                                      DIV_ROUND_UP(sg_dma_len(slp), 512));
9980                }
9981        }
9982
9983        ASC_STATS(scp->device->host, xfer_cnt);
9984
9985        ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
9986        ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
9987
9988        return ASC_NOERROR;
9989}
9990
9991/*
9992 * Build scatter-gather list for Adv Library (Wide Board).
9993 *
9994 * Additional ADV_SG_BLOCK structures will need to be allocated
9995 * if the total number of scatter-gather elements exceeds
9996 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
9997 * assumed to be physically contiguous.
9998 *
9999 * Return:
10000 *      ADV_SUCCESS(1) - SG List successfully created
10001 *      ADV_ERROR(-1) - SG List creation failed
10002 */
10003static int
10004adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
10005               int use_sg)
10006{
10007        adv_sgblk_t *sgblkp;
10008        ADV_SCSI_REQ_Q *scsiqp;
10009        struct scatterlist *slp;
10010        int sg_elem_cnt;
10011        ADV_SG_BLOCK *sg_block, *prev_sg_block;
10012        ADV_PADDR sg_block_paddr;
10013        int i;
10014
10015        scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10016        slp = scsi_sglist(scp);
10017        sg_elem_cnt = use_sg;
10018        prev_sg_block = NULL;
10019        reqp->sgblkp = NULL;
10020
10021        for (;;) {
10022                /*
10023                 * Allocate a 'adv_sgblk_t' structure from the board free
10024                 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
10025                 * (15) scatter-gather elements.
10026                 */
10027                if ((sgblkp = boardp->adv_sgblkp) == NULL) {
10028                        ASC_DBG(1, "no free adv_sgblk_t\n");
10029                        ASC_STATS(scp->device->host, adv_build_nosg);
10030
10031                        /*
10032                         * Allocation failed. Free 'adv_sgblk_t' structures
10033                         * already allocated for the request.
10034                         */
10035                        while ((sgblkp = reqp->sgblkp) != NULL) {
10036                                /* Remove 'sgblkp' from the request list. */
10037                                reqp->sgblkp = sgblkp->next_sgblkp;
10038
10039                                /* Add 'sgblkp' to the board free list. */
10040                                sgblkp->next_sgblkp = boardp->adv_sgblkp;
10041                                boardp->adv_sgblkp = sgblkp;
10042                        }
10043                        return ASC_BUSY;
10044                }
10045
10046                /* Complete 'adv_sgblk_t' board allocation. */
10047                boardp->adv_sgblkp = sgblkp->next_sgblkp;
10048                sgblkp->next_sgblkp = NULL;
10049
10050                /*
10051                 * Get 8 byte aligned virtual and physical addresses
10052                 * for the allocated ADV_SG_BLOCK structure.
10053                 */
10054                sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
10055                sg_block_paddr = virt_to_bus(sg_block);
10056
10057                /*
10058                 * Check if this is the first 'adv_sgblk_t' for the
10059                 * request.
10060                 */
10061                if (reqp->sgblkp == NULL) {
10062                        /* Request's first scatter-gather block. */
10063                        reqp->sgblkp = sgblkp;
10064
10065                        /*
10066                         * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
10067                         * address pointers.
10068                         */
10069                        scsiqp->sg_list_ptr = sg_block;
10070                        scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
10071                } else {
10072                        /* Request's second or later scatter-gather block. */
10073                        sgblkp->next_sgblkp = reqp->sgblkp;
10074                        reqp->sgblkp = sgblkp;
10075
10076                        /*
10077                         * Point the previous ADV_SG_BLOCK structure to
10078                         * the newly allocated ADV_SG_BLOCK structure.
10079                         */
10080                        prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
10081                }
10082
10083                for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
10084                        sg_block->sg_list[i].sg_addr =
10085                                        cpu_to_le32(sg_dma_address(slp));
10086                        sg_block->sg_list[i].sg_count =
10087                                        cpu_to_le32(sg_dma_len(slp));
10088                        ASC_STATS_ADD(scp->device->host, xfer_sect,
10089                                      DIV_ROUND_UP(sg_dma_len(slp), 512));
10090
10091                        if (--sg_elem_cnt == 0) {       /* Last ADV_SG_BLOCK and scatter-gather entry. */
10092                                sg_block->sg_cnt = i + 1;
10093                                sg_block->sg_ptr = 0L;  /* Last ADV_SG_BLOCK in list. */
10094                                return ADV_SUCCESS;
10095                        }
10096                        slp++;
10097                }
10098                sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
10099                prev_sg_block = sg_block;
10100        }
10101}
10102
10103/*
10104 * Build a request structure for the Adv Library (Wide Board).
10105 *
10106 * If an adv_req_t can not be allocated to issue the request,
10107 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
10108 *
10109 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
10110 * microcode for DMA addresses or math operations are byte swapped
10111 * to little-endian order.
10112 */
10113static int
10114adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
10115              ADV_SCSI_REQ_Q **adv_scsiqpp)
10116{
10117        adv_req_t *reqp;
10118        ADV_SCSI_REQ_Q *scsiqp;
10119        int i;
10120        int ret;
10121        int use_sg;
10122
10123        /*
10124         * Allocate an adv_req_t structure from the board to execute
10125         * the command.
10126         */
10127        if (boardp->adv_reqp == NULL) {
10128                ASC_DBG(1, "no free adv_req_t\n");
10129                ASC_STATS(scp->device->host, adv_build_noreq);
10130                return ASC_BUSY;
10131        } else {
10132                reqp = boardp->adv_reqp;
10133                boardp->adv_reqp = reqp->next_reqp;
10134                reqp->next_reqp = NULL;
10135        }
10136
10137        /*
10138         * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
10139         */
10140        scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
10141
10142        /*
10143         * Initialize the structure.
10144         */
10145        scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
10146
10147        /*
10148         * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
10149         */
10150        scsiqp->srb_ptr = ADV_VADDR_TO_U32(reqp);
10151
10152        /*
10153         * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
10154         */
10155        reqp->cmndp = scp;
10156
10157        /*
10158         * Build the ADV_SCSI_REQ_Q request.
10159         */
10160
10161        /* Set CDB length and copy it to the request structure.  */
10162        scsiqp->cdb_len = scp->cmd_len;
10163        /* Copy first 12 CDB bytes to cdb[]. */
10164        for (i = 0; i < scp->cmd_len && i < 12; i++) {
10165                scsiqp->cdb[i] = scp->cmnd[i];
10166        }
10167        /* Copy last 4 CDB bytes, if present, to cdb16[]. */
10168        for (; i < scp->cmd_len; i++) {
10169                scsiqp->cdb16[i - 12] = scp->cmnd[i];
10170        }
10171
10172        scsiqp->target_id = scp->device->id;
10173        scsiqp->target_lun = scp->device->lun;
10174
10175        scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10176        scsiqp->sense_len = sizeof(scp->sense_buffer);
10177
10178        /* Build ADV_SCSI_REQ_Q */
10179
10180        use_sg = scsi_dma_map(scp);
10181        if (use_sg == 0) {
10182                /* Zero-length transfer */
10183                reqp->sgblkp = NULL;
10184                scsiqp->data_cnt = 0;
10185                scsiqp->vdata_addr = NULL;
10186
10187                scsiqp->data_addr = 0;
10188                scsiqp->sg_list_ptr = NULL;
10189                scsiqp->sg_real_addr = 0;
10190        } else {
10191                if (use_sg > ADV_MAX_SG_LIST) {
10192                        scmd_printk(KERN_ERR, scp, "use_sg %d > "
10193                                   "ADV_MAX_SG_LIST %d\n", use_sg,
10194                                   scp->device->host->sg_tablesize);
10195                        scsi_dma_unmap(scp);
10196                        scp->result = HOST_BYTE(DID_ERROR);
10197
10198                        /*
10199                         * Free the 'adv_req_t' structure by adding it back
10200                         * to the board free list.
10201                         */
10202                        reqp->next_reqp = boardp->adv_reqp;
10203                        boardp->adv_reqp = reqp;
10204
10205                        return ASC_ERROR;
10206                }
10207
10208                scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp));
10209
10210                ret = adv_get_sglist(boardp, reqp, scp, use_sg);
10211                if (ret != ADV_SUCCESS) {
10212                        /*
10213                         * Free the adv_req_t structure by adding it back to
10214                         * the board free list.
10215                         */
10216                        reqp->next_reqp = boardp->adv_reqp;
10217                        boardp->adv_reqp = reqp;
10218
10219                        return ret;
10220                }
10221
10222                ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg);
10223        }
10224
10225        ASC_STATS(scp->device->host, xfer_cnt);
10226
10227        ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
10228        ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
10229
10230        *adv_scsiqpp = scsiqp;
10231
10232        return ASC_NOERROR;
10233}
10234
10235static int AscSgListToQueue(int sg_list)
10236{
10237        int n_sg_list_qs;
10238
10239        n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
10240        if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
10241                n_sg_list_qs++;
10242        return n_sg_list_qs + 1;
10243}
10244
10245static uint
10246AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
10247{
10248        uint cur_used_qs;
10249        uint cur_free_qs;
10250        ASC_SCSI_BIT_ID_TYPE target_id;
10251        uchar tid_no;
10252
10253        target_id = ASC_TIX_TO_TARGET_ID(target_ix);
10254        tid_no = ASC_TIX_TO_TID(target_ix);
10255        if ((asc_dvc->unit_not_ready & target_id) ||
10256            (asc_dvc->queue_full_or_busy & target_id)) {
10257                return 0;
10258        }
10259        if (n_qs == 1) {
10260                cur_used_qs = (uint) asc_dvc->cur_total_qng +
10261                    (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
10262        } else {
10263                cur_used_qs = (uint) asc_dvc->cur_total_qng +
10264                    (uint) ASC_MIN_FREE_Q;
10265        }
10266        if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
10267                cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
10268                if (asc_dvc->cur_dvc_qng[tid_no] >=
10269                    asc_dvc->max_dvc_qng[tid_no]) {
10270                        return 0;
10271                }
10272                return cur_free_qs;
10273        }
10274        if (n_qs > 1) {
10275                if ((n_qs > asc_dvc->last_q_shortage)
10276                    && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
10277                        asc_dvc->last_q_shortage = n_qs;
10278                }
10279        }
10280        return 0;
10281}
10282
10283static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10284{
10285        ushort q_addr;
10286        uchar next_qp;
10287        uchar q_status;
10288
10289        q_addr = ASC_QNO_TO_QADDR(free_q_head);
10290        q_status = (uchar)AscReadLramByte(iop_base,
10291                                          (ushort)(q_addr +
10292                                                   ASC_SCSIQ_B_STATUS));
10293        next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10294        if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END))
10295                return next_qp;
10296        return ASC_QLINK_END;
10297}
10298
10299static uchar
10300AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10301{
10302        uchar i;
10303
10304        for (i = 0; i < n_free_q; i++) {
10305                free_q_head = AscAllocFreeQueue(iop_base, free_q_head);
10306                if (free_q_head == ASC_QLINK_END)
10307                        break;
10308        }
10309        return free_q_head;
10310}
10311
10312/*
10313 * void
10314 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10315 *
10316 * Calling/Exit State:
10317 *    none
10318 *
10319 * Description:
10320 *     Output an ASC_SCSI_Q structure to the chip
10321 */
10322static void
10323DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
10324{
10325        int i;
10326
10327        ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
10328        AscSetChipLramAddr(iop_base, s_addr);
10329        for (i = 0; i < 2 * words; i += 2) {
10330                if (i == 4 || i == 20) {
10331                        continue;
10332                }
10333                outpw(iop_base + IOP_RAM_DATA,
10334                      ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
10335        }
10336}
10337
10338static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10339{
10340        ushort q_addr;
10341        uchar tid_no;
10342        uchar sdtr_data;
10343        uchar syn_period_ix;
10344        uchar syn_offset;
10345        PortAddr iop_base;
10346
10347        iop_base = asc_dvc->iop_base;
10348        if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
10349            ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
10350                tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
10351                sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10352                syn_period_ix =
10353                    (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
10354                syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
10355                AscMsgOutSDTR(asc_dvc,
10356                              asc_dvc->sdtr_period_tbl[syn_period_ix],
10357                              syn_offset);
10358                scsiq->q1.cntl |= QC_MSG_OUT;
10359        }
10360        q_addr = ASC_QNO_TO_QADDR(q_no);
10361        if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
10362                scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10363        }
10364        scsiq->q1.status = QS_FREE;
10365        AscMemWordCopyPtrToLram(iop_base,
10366                                q_addr + ASC_SCSIQ_CDB_BEG,
10367                                (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
10368
10369        DvcPutScsiQ(iop_base,
10370                    q_addr + ASC_SCSIQ_CPY_BEG,
10371                    (uchar *)&scsiq->q1.cntl,
10372                    ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
10373        AscWriteLramWord(iop_base,
10374                         (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
10375                         (ushort)(((ushort)scsiq->q1.
10376                                   q_no << 8) | (ushort)QS_READY));
10377        return 1;
10378}
10379
10380static int
10381AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
10382{
10383        int sta;
10384        int i;
10385        ASC_SG_HEAD *sg_head;
10386        ASC_SG_LIST_Q scsi_sg_q;
10387        ASC_DCNT saved_data_addr;
10388        ASC_DCNT saved_data_cnt;
10389        PortAddr iop_base;
10390        ushort sg_list_dwords;
10391        ushort sg_index;
10392        ushort sg_entry_cnt;
10393        ushort q_addr;
10394        uchar next_qp;
10395
10396        iop_base = asc_dvc->iop_base;
10397        sg_head = scsiq->sg_head;
10398        saved_data_addr = scsiq->q1.data_addr;
10399        saved_data_cnt = scsiq->q1.data_cnt;
10400        scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
10401        scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
10402#if CC_VERY_LONG_SG_LIST
10403        /*
10404         * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
10405         * then not all SG elements will fit in the allocated queues.
10406         * The rest of the SG elements will be copied when the RISC
10407         * completes the SG elements that fit and halts.
10408         */
10409        if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10410                /*
10411                 * Set sg_entry_cnt to be the number of SG elements that
10412                 * will fit in the allocated SG queues. It is minus 1, because
10413                 * the first SG element is handled above. ASC_MAX_SG_LIST is
10414                 * already inflated by 1 to account for this. For example it
10415                 * may be 50 which is 1 + 7 queues * 7 SG elements.
10416                 */
10417                sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10418
10419                /*
10420                 * Keep track of remaining number of SG elements that will
10421                 * need to be handled from a_isr.c.
10422                 */
10423                scsiq->remain_sg_entry_cnt =
10424                    sg_head->entry_cnt - ASC_MAX_SG_LIST;
10425        } else {
10426#endif /* CC_VERY_LONG_SG_LIST */
10427                /*
10428                 * Set sg_entry_cnt to be the number of SG elements that
10429                 * will fit in the allocated SG queues. It is minus 1, because
10430                 * the first SG element is handled above.
10431                 */
10432                sg_entry_cnt = sg_head->entry_cnt - 1;
10433#if CC_VERY_LONG_SG_LIST
10434        }
10435#endif /* CC_VERY_LONG_SG_LIST */
10436        if (sg_entry_cnt != 0) {
10437                scsiq->q1.cntl |= QC_SG_HEAD;
10438                q_addr = ASC_QNO_TO_QADDR(q_no);
10439                sg_index = 1;
10440                scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10441                scsi_sg_q.sg_head_qp = q_no;
10442                scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10443                for (i = 0; i < sg_head->queue_cnt; i++) {
10444                        scsi_sg_q.seq_no = i + 1;
10445                        if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10446                                sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10447                                sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10448                                if (i == 0) {
10449                                        scsi_sg_q.sg_list_cnt =
10450                                            ASC_SG_LIST_PER_Q;
10451                                        scsi_sg_q.sg_cur_list_cnt =
10452                                            ASC_SG_LIST_PER_Q;
10453                                } else {
10454                                        scsi_sg_q.sg_list_cnt =
10455                                            ASC_SG_LIST_PER_Q - 1;
10456                                        scsi_sg_q.sg_cur_list_cnt =
10457                                            ASC_SG_LIST_PER_Q - 1;
10458                                }
10459                        } else {
10460#if CC_VERY_LONG_SG_LIST
10461                                /*
10462                                 * This is the last SG queue in the list of
10463                                 * allocated SG queues. If there are more
10464                                 * SG elements than will fit in the allocated
10465                                 * queues, then set the QCSG_SG_XFER_MORE flag.
10466                                 */
10467                                if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10468                                        scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10469                                } else {
10470#endif /* CC_VERY_LONG_SG_LIST */
10471                                        scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10472#if CC_VERY_LONG_SG_LIST
10473                                }
10474#endif /* CC_VERY_LONG_SG_LIST */
10475                                sg_list_dwords = sg_entry_cnt << 1;
10476                                if (i == 0) {
10477                                        scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10478                                        scsi_sg_q.sg_cur_list_cnt =
10479                                            sg_entry_cnt;
10480                                } else {
10481                                        scsi_sg_q.sg_list_cnt =
10482                                            sg_entry_cnt - 1;
10483                                        scsi_sg_q.sg_cur_list_cnt =
10484                                            sg_entry_cnt - 1;
10485                                }
10486                                sg_entry_cnt = 0;
10487                        }
10488                        next_qp = AscReadLramByte(iop_base,
10489                                                  (ushort)(q_addr +
10490                                                           ASC_SCSIQ_B_FWD));
10491                        scsi_sg_q.q_no = next_qp;
10492                        q_addr = ASC_QNO_TO_QADDR(next_qp);
10493                        AscMemWordCopyPtrToLram(iop_base,
10494                                                q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10495                                                (uchar *)&scsi_sg_q,
10496                                                sizeof(ASC_SG_LIST_Q) >> 1);
10497                        AscMemDWordCopyPtrToLram(iop_base,
10498                                                 q_addr + ASC_SGQ_LIST_BEG,
10499                                                 (uchar *)&sg_head->
10500                                                 sg_list[sg_index],
10501                                                 sg_list_dwords);
10502                        sg_index += ASC_SG_LIST_PER_Q;
10503                        scsiq->next_sg_index = sg_index;
10504                }
10505        } else {
10506                scsiq->q1.cntl &= ~QC_SG_HEAD;
10507        }
10508        sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10509        scsiq->q1.data_addr = saved_data_addr;
10510        scsiq->q1.data_cnt = saved_data_cnt;
10511        return (sta);
10512}
10513
10514static int
10515AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
10516{
10517        PortAddr iop_base;
10518        uchar free_q_head;
10519        uchar next_qp;
10520        uchar tid_no;
10521        uchar target_ix;
10522        int sta;
10523
10524        iop_base = asc_dvc->iop_base;
10525        target_ix = scsiq->q2.target_ix;
10526        tid_no = ASC_TIX_TO_TID(target_ix);
10527        sta = 0;
10528        free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
10529        if (n_q_required > 1) {
10530                next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head,
10531                                                    (uchar)n_q_required);
10532                if (next_qp != ASC_QLINK_END) {
10533                        asc_dvc->last_q_shortage = 0;
10534                        scsiq->sg_head->queue_cnt = n_q_required - 1;
10535                        scsiq->q1.q_no = free_q_head;
10536                        sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10537                                                     free_q_head);
10538                }
10539        } else if (n_q_required == 1) {
10540                next_qp = AscAllocFreeQueue(iop_base, free_q_head);
10541                if (next_qp != ASC_QLINK_END) {
10542                        scsiq->q1.q_no = free_q_head;
10543                        sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head);
10544                }
10545        }
10546        if (sta == 1) {
10547                AscPutVarFreeQHead(iop_base, next_qp);
10548                asc_dvc->cur_total_qng += n_q_required;
10549                asc_dvc->cur_dvc_qng[tid_no]++;
10550        }
10551        return sta;
10552}
10553
10554#define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
10555static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
10556        INQUIRY,
10557        REQUEST_SENSE,
10558        READ_CAPACITY,
10559        READ_TOC,
10560        MODE_SELECT,
10561        MODE_SENSE,
10562        MODE_SELECT_10,
10563        MODE_SENSE_10,
10564        0xFF,
10565        0xFF,
10566        0xFF,
10567        0xFF,
10568        0xFF,
10569        0xFF,
10570        0xFF,
10571        0xFF
10572};
10573
10574static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
10575{
10576        PortAddr iop_base;
10577        int sta;
10578        int n_q_required;
10579        int disable_syn_offset_one_fix;
10580        int i;
10581        ASC_PADDR addr;
10582        ushort sg_entry_cnt = 0;
10583        ushort sg_entry_cnt_minus_one = 0;
10584        uchar target_ix;
10585        uchar tid_no;
10586        uchar sdtr_data;
10587        uchar extra_bytes;
10588        uchar scsi_cmd;
10589        uchar disable_cmd;
10590        ASC_SG_HEAD *sg_head;
10591        ASC_DCNT data_cnt;
10592
10593        iop_base = asc_dvc->iop_base;
10594        sg_head = scsiq->sg_head;
10595        if (asc_dvc->err_code != 0)
10596                return (ERR);
10597        scsiq->q1.q_no = 0;
10598        if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10599                scsiq->q1.extra_bytes = 0;
10600        }
10601        sta = 0;
10602        target_ix = scsiq->q2.target_ix;
10603        tid_no = ASC_TIX_TO_TID(target_ix);
10604        n_q_required = 1;
10605        if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10606                if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10607                        asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10608                        sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10609                        AscMsgOutSDTR(asc_dvc,
10610                                      asc_dvc->
10611                                      sdtr_period_tbl[(sdtr_data >> 4) &
10612                                                      (uchar)(asc_dvc->
10613                                                              max_sdtr_index -
10614                                                              1)],
10615                                      (uchar)(sdtr_data & (uchar)
10616                                              ASC_SYN_MAX_OFFSET));
10617                        scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10618                }
10619        }
10620        if (asc_dvc->in_critical_cnt != 0) {
10621                AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10622                return (ERR);
10623        }
10624        asc_dvc->in_critical_cnt++;
10625        if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10626                if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10627                        asc_dvc->in_critical_cnt--;
10628                        return (ERR);
10629                }
10630#if !CC_VERY_LONG_SG_LIST
10631                if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10632                        asc_dvc->in_critical_cnt--;
10633                        return (ERR);
10634                }
10635#endif /* !CC_VERY_LONG_SG_LIST */
10636                if (sg_entry_cnt == 1) {
10637                        scsiq->q1.data_addr =
10638                            (ADV_PADDR)sg_head->sg_list[0].addr;
10639                        scsiq->q1.data_cnt =
10640                            (ADV_DCNT)sg_head->sg_list[0].bytes;
10641                        scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10642                }
10643                sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10644        }
10645        scsi_cmd = scsiq->cdbptr[0];
10646        disable_syn_offset_one_fix = FALSE;
10647        if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10648            !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10649                if (scsiq->q1.cntl & QC_SG_HEAD) {
10650                        data_cnt = 0;
10651                        for (i = 0; i < sg_entry_cnt; i++) {
10652                                data_cnt +=
10653                                    (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
10654                                                          bytes);
10655                        }
10656                } else {
10657                        data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10658                }
10659                if (data_cnt != 0UL) {
10660                        if (data_cnt < 512UL) {
10661                                disable_syn_offset_one_fix = TRUE;
10662                        } else {
10663                                for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
10664                                     i++) {
10665                                        disable_cmd =
10666                                            _syn_offset_one_disable_cmd[i];
10667                                        if (disable_cmd == 0xFF) {
10668                                                break;
10669                                        }
10670                                        if (scsi_cmd == disable_cmd) {
10671                                                disable_syn_offset_one_fix =
10672                                                    TRUE;
10673                                                break;
10674                                        }
10675                                }
10676                        }
10677                }
10678        }
10679        if (disable_syn_offset_one_fix) {
10680                scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10681                scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10682                                       ASC_TAG_FLAG_DISABLE_DISCONNECT);
10683        } else {
10684                scsiq->q2.tag_code &= 0x27;
10685        }
10686        if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10687                if (asc_dvc->bug_fix_cntl) {
10688                        if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10689                                if ((scsi_cmd == READ_6) ||
10690                                    (scsi_cmd == READ_10)) {
10691                                        addr =
10692                                            (ADV_PADDR)le32_to_cpu(sg_head->
10693                                                                   sg_list
10694                                                                   [sg_entry_cnt_minus_one].
10695                                                                   addr) +
10696                                            (ADV_DCNT)le32_to_cpu(sg_head->
10697                                                                  sg_list
10698                                                                  [sg_entry_cnt_minus_one].
10699                                                                  bytes);
10700                                        extra_bytes =
10701                                            (uchar)((ushort)addr & 0x0003);
10702                                        if ((extra_bytes != 0)
10703                                            &&
10704                                            ((scsiq->q2.
10705                                              tag_code &
10706                                              ASC_TAG_FLAG_EXTRA_BYTES)
10707                                             == 0)) {
10708                                                scsiq->q2.tag_code |=
10709                                                    ASC_TAG_FLAG_EXTRA_BYTES;
10710                                                scsiq->q1.extra_bytes =
10711                                                    extra_bytes;
10712                                                data_cnt =
10713                                                    le32_to_cpu(sg_head->
10714                                                                sg_list
10715                                                                [sg_entry_cnt_minus_one].
10716                                                                bytes);
10717                                                data_cnt -=
10718                                                    (ASC_DCNT) extra_bytes;
10719                                                sg_head->
10720                                                    sg_list
10721                                                    [sg_entry_cnt_minus_one].
10722                                                    bytes =
10723                                                    cpu_to_le32(data_cnt);
10724                                        }
10725                                }
10726                        }
10727                }
10728                sg_head->entry_to_copy = sg_head->entry_cnt;
10729#if CC_VERY_LONG_SG_LIST
10730                /*
10731                 * Set the sg_entry_cnt to the maximum possible. The rest of
10732                 * the SG elements will be copied when the RISC completes the
10733                 * SG elements that fit and halts.
10734                 */
10735                if (sg_entry_cnt > ASC_MAX_SG_LIST) {
10736                        sg_entry_cnt = ASC_MAX_SG_LIST;
10737                }
10738#endif /* CC_VERY_LONG_SG_LIST */
10739                n_q_required = AscSgListToQueue(sg_entry_cnt);
10740                if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10741                     (uint) n_q_required)
10742                    || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10743                        if ((sta =
10744                             AscSendScsiQueue(asc_dvc, scsiq,
10745                                              n_q_required)) == 1) {
10746                                asc_dvc->in_critical_cnt--;
10747                                return (sta);
10748                        }
10749                }
10750        } else {
10751                if (asc_dvc->bug_fix_cntl) {
10752                        if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10753                                if ((scsi_cmd == READ_6) ||
10754                                    (scsi_cmd == READ_10)) {
10755                                        addr =
10756                                            le32_to_cpu(scsiq->q1.data_addr) +
10757                                            le32_to_cpu(scsiq->q1.data_cnt);
10758                                        extra_bytes =
10759                                            (uchar)((ushort)addr & 0x0003);
10760                                        if ((extra_bytes != 0)
10761                                            &&
10762                                            ((scsiq->q2.
10763                                              tag_code &
10764                                              ASC_TAG_FLAG_EXTRA_BYTES)
10765                                             == 0)) {
10766                                                data_cnt =
10767                                                    le32_to_cpu(scsiq->q1.
10768                                                                data_cnt);
10769                                                if (((ushort)data_cnt & 0x01FF)
10770                                                    == 0) {
10771                                                        scsiq->q2.tag_code |=
10772                                                            ASC_TAG_FLAG_EXTRA_BYTES;
10773                                                        data_cnt -= (ASC_DCNT)
10774                                                            extra_bytes;
10775                                                        scsiq->q1.data_cnt =
10776                                                            cpu_to_le32
10777                                                            (data_cnt);
10778                                                        scsiq->q1.extra_bytes =
10779                                                            extra_bytes;
10780                                                }
10781                                        }
10782                                }
10783                        }
10784                }
10785                n_q_required = 1;
10786                if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10787                    ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10788                        if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10789                                                    n_q_required)) == 1) {
10790                                asc_dvc->in_critical_cnt--;
10791                                return (sta);
10792                        }
10793                }
10794        }
10795        asc_dvc->in_critical_cnt--;
10796        return (sta);
10797}
10798
10799/*
10800 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
10801 *
10802 *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
10803 *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
10804 *   RISC to notify it a new command is ready to be executed.
10805 *
10806 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
10807 * set to SCSI_MAX_RETRY.
10808 *
10809 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
10810 * for DMA addresses or math operations are byte swapped to little-endian
10811 * order.
10812 *
10813 * Return:
10814 *      ADV_SUCCESS(1) - The request was successfully queued.
10815 *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
10816 *                       request completes.
10817 *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
10818 *                       host IC error.
10819 */
10820static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
10821{
10822        AdvPortAddr iop_base;
10823        ADV_PADDR req_paddr;
10824        ADV_CARR_T *new_carrp;
10825
10826        /*
10827         * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
10828         */
10829        if (scsiq->target_id > ADV_MAX_TID) {
10830                scsiq->host_status = QHSTA_M_INVALID_DEVICE;
10831                scsiq->done_status = QD_WITH_ERROR;
10832                return ADV_ERROR;
10833        }
10834
10835        iop_base = asc_dvc->iop_base;
10836
10837        /*
10838         * Allocate a carrier ensuring at least one carrier always
10839         * remains on the freelist and initialize fields.
10840         */
10841        if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
10842                return ADV_BUSY;
10843        }
10844        asc_dvc->carr_freelist = (ADV_CARR_T *)
10845            ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
10846        asc_dvc->carr_pending_cnt++;
10847
10848        /*
10849         * Set the carrier to be a stopper by setting 'next_vpa'
10850         * to the stopper value. The current stopper will be changed
10851         * below to point to the new stopper.
10852         */
10853        new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
10854
10855        /*
10856         * Clear the ADV_SCSI_REQ_Q done flag.
10857         */
10858        scsiq->a_flag &= ~ADV_SCSIQ_DONE;
10859
10860        req_paddr = virt_to_bus(scsiq);
10861        BUG_ON(req_paddr & 31);
10862        /* Wait for assertion before making little-endian */
10863        req_paddr = cpu_to_le32(req_paddr);
10864
10865        /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
10866        scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
10867        scsiq->scsiq_rptr = req_paddr;
10868
10869        scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
10870        /*
10871         * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
10872         * order during initialization.
10873         */
10874        scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
10875
10876        /*
10877         * Use the current stopper to send the ADV_SCSI_REQ_Q command to
10878         * the microcode. The newly allocated stopper will become the new
10879         * stopper.
10880         */
10881        asc_dvc->icq_sp->areq_vpa = req_paddr;
10882
10883        /*
10884         * Set the 'next_vpa' pointer for the old stopper to be the
10885         * physical address of the new stopper. The RISC can only
10886         * follow physical addresses.
10887         */
10888        asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
10889
10890        /*
10891         * Set the host adapter stopper pointer to point to the new carrier.
10892         */
10893        asc_dvc->icq_sp = new_carrp;
10894
10895        if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
10896            asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
10897                /*
10898                 * Tickle the RISC to tell it to read its Command Queue Head pointer.
10899                 */
10900                AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
10901                if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
10902                        /*
10903                         * Clear the tickle value. In the ASC-3550 the RISC flag
10904                         * command 'clr_tickle_a' does not work unless the host
10905                         * value is cleared.
10906                         */
10907                        AdvWriteByteRegister(iop_base, IOPB_TICKLE,
10908                                             ADV_TICKLE_NOP);
10909                }
10910        } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
10911                /*
10912                 * Notify the RISC a carrier is ready by writing the physical
10913                 * address of the new carrier stopper to the COMMA register.
10914                 */
10915                AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
10916                                      le32_to_cpu(new_carrp->carr_pa));
10917        }
10918
10919        return ADV_SUCCESS;
10920}
10921
10922/*
10923 * Execute a single 'Scsi_Cmnd'.
10924 */
10925static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
10926{
10927        int ret, err_code;
10928        struct asc_board *boardp = shost_priv(scp->device->host);
10929
10930        ASC_DBG(1, "scp 0x%p\n", scp);
10931
10932        if (ASC_NARROW_BOARD(boardp)) {
10933                ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
10934                struct asc_scsi_q asc_scsi_q;
10935
10936                /* asc_build_req() can not return ASC_BUSY. */
10937                ret = asc_build_req(boardp, scp, &asc_scsi_q);
10938                if (ret == ASC_ERROR) {
10939                        ASC_STATS(scp->device->host, build_error);
10940                        return ASC_ERROR;
10941                }
10942
10943                ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
10944                kfree(asc_scsi_q.sg_head);
10945                err_code = asc_dvc->err_code;
10946        } else {
10947                ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;
10948                ADV_SCSI_REQ_Q *adv_scsiqp;
10949
10950                switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
10951                case ASC_NOERROR:
10952                        ASC_DBG(3, "adv_build_req ASC_NOERROR\n");
10953                        break;
10954                case ASC_BUSY:
10955                        ASC_DBG(1, "adv_build_req ASC_BUSY\n");
10956                        /*
10957                         * The asc_stats fields 'adv_build_noreq' and
10958                         * 'adv_build_nosg' count wide board busy conditions.
10959                         * They are updated in adv_build_req and
10960                         * adv_get_sglist, respectively.
10961                         */
10962                        return ASC_BUSY;
10963                case ASC_ERROR:
10964                default:
10965                        ASC_DBG(1, "adv_build_req ASC_ERROR\n");
10966                        ASC_STATS(scp->device->host, build_error);
10967                        return ASC_ERROR;
10968                }
10969
10970                ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp);
10971                err_code = adv_dvc->err_code;
10972        }
10973
10974        switch (ret) {
10975        case ASC_NOERROR:
10976                ASC_STATS(scp->device->host, exe_noerror);
10977                /*
10978                 * Increment monotonically increasing per device
10979                 * successful request counter. Wrapping doesn't matter.
10980                 */
10981                boardp->reqcnt[scp->device->id]++;
10982                ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n");
10983                break;
10984        case ASC_BUSY:
10985                ASC_STATS(scp->device->host, exe_busy);
10986                break;
10987        case ASC_ERROR:
10988                scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
10989                        "err_code 0x%x\n", err_code);
10990                ASC_STATS(scp->device->host, exe_error);
10991                scp->result = HOST_BYTE(DID_ERROR);
10992                break;
10993        default:
10994                scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
10995                        "err_code 0x%x\n", err_code);
10996                ASC_STATS(scp->device->host, exe_unknown);
10997                scp->result = HOST_BYTE(DID_ERROR);
10998                break;
10999        }
11000
11001        ASC_DBG(1, "end\n");
11002        return ret;
11003}
11004
11005/*
11006 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
11007 *
11008 * This function always returns 0. Command return status is saved
11009 * in the 'scp' result field.
11010 */
11011static int
11012advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
11013{
11014        struct Scsi_Host *shost = scp->device->host;
11015        int asc_res, result = 0;
11016
11017        ASC_STATS(shost, queuecommand);
11018        scp->scsi_done = done;
11019
11020        asc_res = asc_execute_scsi_cmnd(scp);
11021
11022        switch (asc_res) {
11023        case ASC_NOERROR:
11024                break;
11025        case ASC_BUSY:
11026                result = SCSI_MLQUEUE_HOST_BUSY;
11027                break;
11028        case ASC_ERROR:
11029        default:
11030                asc_scsi_done(scp);
11031                break;
11032        }
11033
11034        return result;
11035}
11036
11037static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
11038{
11039        PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11040            (PortAddr) (ASC_EISA_CFG_IOP_MASK);
11041        return inpw(eisa_cfg_iop);
11042}
11043
11044/*
11045 * Return the BIOS address of the adapter at the specified
11046 * I/O port and with the specified bus type.
11047 */
11048static unsigned short __devinit
11049AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
11050{
11051        unsigned short cfg_lsw;
11052        unsigned short bios_addr;
11053
11054        /*
11055         * The PCI BIOS is re-located by the motherboard BIOS. Because
11056         * of this the driver can not determine where a PCI BIOS is
11057         * loaded and executes.
11058         */
11059        if (bus_type & ASC_IS_PCI)
11060                return 0;
11061
11062        if ((bus_type & ASC_IS_EISA) != 0) {
11063                cfg_lsw = AscGetEisaChipCfg(iop_base);
11064                cfg_lsw &= 0x000F;
11065                bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
11066                return bios_addr;
11067        }
11068
11069        cfg_lsw = AscGetChipCfgLsw(iop_base);
11070
11071        /*
11072         *  ISA PnP uses the top bit as the 32K BIOS flag
11073         */
11074        if (bus_type == ASC_IS_ISAPNP)
11075                cfg_lsw &= 0x7FFF;
11076        bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
11077        return bios_addr;
11078}
11079
11080static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
11081{
11082        ushort cfg_lsw;
11083
11084        if (AscGetChipScsiID(iop_base) == new_host_id) {
11085                return (new_host_id);
11086        }
11087        cfg_lsw = AscGetChipCfgLsw(iop_base);
11088        cfg_lsw &= 0xF8FF;
11089        cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
11090        AscSetChipCfgLsw(iop_base, cfg_lsw);
11091        return (AscGetChipScsiID(iop_base));
11092}
11093
11094static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
11095{
11096        unsigned char sc;
11097
11098        AscSetBank(iop_base, 1);
11099        sc = inp(iop_base + IOP_REG_SC);
11100        AscSetBank(iop_base, 0);
11101        return sc;
11102}
11103
11104static unsigned char __devinit
11105AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
11106{
11107        if (bus_type & ASC_IS_EISA) {
11108                PortAddr eisa_iop;
11109                unsigned char revision;
11110                eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
11111                    (PortAddr) ASC_EISA_REV_IOP_MASK;
11112                revision = inp(eisa_iop);
11113                return ASC_CHIP_MIN_VER_EISA - 1 + revision;
11114        }
11115        return AscGetChipVerNo(iop_base);
11116}
11117
11118#ifdef CONFIG_ISA
11119static void __devinit AscEnableIsaDma(uchar dma_channel)
11120{
11121        if (dma_channel < 4) {
11122                outp(0x000B, (ushort)(0xC0 | dma_channel));
11123                outp(0x000A, dma_channel);
11124        } else if (dma_channel < 8) {
11125                outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
11126                outp(0x00D4, (ushort)(dma_channel - 4));
11127        }
11128}
11129#endif /* CONFIG_ISA */
11130
11131static int AscStopQueueExe(PortAddr iop_base)
11132{
11133        int count = 0;
11134
11135        if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11136                AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11137                                 ASC_STOP_REQ_RISC_STOP);
11138                do {
11139                        if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11140                            ASC_STOP_ACK_RISC_STOP) {
11141                                return (1);
11142                        }
11143                        mdelay(100);
11144                } while (count++ < 20);
11145        }
11146        return (0);
11147}
11148
11149static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
11150{
11151        if (bus_type & ASC_IS_ISA)
11152                return ASC_MAX_ISA_DMA_COUNT;
11153        else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11154                return ASC_MAX_VL_DMA_COUNT;
11155        return ASC_MAX_PCI_DMA_COUNT;
11156}
11157
11158#ifdef CONFIG_ISA
11159static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
11160{
11161        ushort channel;
11162
11163        channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11164        if (channel == 0x03)
11165                return (0);
11166        else if (channel == 0x00)
11167                return (7);
11168        return (channel + 4);
11169}
11170
11171static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
11172{
11173        ushort cfg_lsw;
11174        uchar value;
11175
11176        if ((dma_channel >= 5) && (dma_channel <= 7)) {
11177                if (dma_channel == 7)
11178                        value = 0x00;
11179                else
11180                        value = dma_channel - 4;
11181                cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11182                cfg_lsw |= value;
11183                AscSetChipCfgLsw(iop_base, cfg_lsw);
11184                return (AscGetIsaDmaChannel(iop_base));
11185        }
11186        return 0;
11187}
11188
11189static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
11190{
11191        uchar speed_value;
11192
11193        AscSetBank(iop_base, 1);
11194        speed_value = AscReadChipDmaSpeed(iop_base);
11195        speed_value &= 0x07;
11196        AscSetBank(iop_base, 0);
11197        return speed_value;
11198}
11199
11200static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
11201{
11202        speed_value &= 0x07;
11203        AscSetBank(iop_base, 1);
11204        AscWriteChipDmaSpeed(iop_base, speed_value);
11205        AscSetBank(iop_base, 0);
11206        return AscGetIsaDmaSpeed(iop_base);
11207}
11208#endif /* CONFIG_ISA */
11209
11210static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
11211{
11212        int i;
11213        PortAddr iop_base;
11214        ushort warn_code;
11215        uchar chip_version;
11216
11217        iop_base = asc_dvc->iop_base;
11218        warn_code = 0;
11219        asc_dvc->err_code = 0;
11220        if ((asc_dvc->bus_type &
11221             (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
11222                asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
11223        }
11224        AscSetChipControl(iop_base, CC_HALT);
11225        AscSetChipStatus(iop_base, 0);
11226        asc_dvc->bug_fix_cntl = 0;
11227        asc_dvc->pci_fix_asyn_xfer = 0;
11228        asc_dvc->pci_fix_asyn_xfer_always = 0;
11229        /* asc_dvc->init_state initalized in AscInitGetConfig(). */
11230        asc_dvc->sdtr_done = 0;
11231        asc_dvc->cur_total_qng = 0;
11232        asc_dvc->is_in_int = 0;
11233        asc_dvc->in_critical_cnt = 0;
11234        asc_dvc->last_q_shortage = 0;
11235        asc_dvc->use_tagged_qng = 0;
11236        asc_dvc->no_scam = 0;
11237        asc_dvc->unit_not_ready = 0;
11238        asc_dvc->queue_full_or_busy = 0;
11239        asc_dvc->redo_scam = 0;
11240        asc_dvc->res2 = 0;
11241        asc_dvc->min_sdtr_index = 0;
11242        asc_dvc->cfg->can_tagged_qng = 0;
11243        asc_dvc->cfg->cmd_qng_enabled = 0;
11244        asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
11245        asc_dvc->init_sdtr = 0;
11246        asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
11247        asc_dvc->scsi_reset_wait = 3;
11248        asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
11249        asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
11250        asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
11251        asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
11252        asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
11253        chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
11254        asc_dvc->cfg->chip_version = chip_version;
11255        asc_dvc->sdtr_period_tbl = asc_syn_xfer_period;
11256        asc_dvc->max_sdtr_index = 7;
11257        if ((asc_dvc->bus_type & ASC_IS_PCI) &&
11258            (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
11259                asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
11260                asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period;
11261                asc_dvc->max_sdtr_index = 15;
11262                if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
11263                        AscSetExtraControl(iop_base,
11264                                           (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11265                } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
11266                        AscSetExtraControl(iop_base,
11267                                           (SEC_ACTIVE_NEGATE |
11268                                            SEC_ENABLE_FILTER));
11269                }
11270        }
11271        if (asc_dvc->bus_type == ASC_IS_PCI) {
11272                AscSetExtraControl(iop_base,
11273                                   (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
11274        }
11275
11276        asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
11277#ifdef CONFIG_ISA
11278        if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
11279                if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
11280                        AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
11281                        asc_dvc->bus_type = ASC_IS_ISAPNP;
11282                }
11283                asc_dvc->cfg->isa_dma_channel =
11284                    (uchar)AscGetIsaDmaChannel(iop_base);
11285        }
11286#endif /* CONFIG_ISA */
11287        for (i = 0; i <= ASC_MAX_TID; i++) {
11288                asc_dvc->cur_dvc_qng[i] = 0;
11289                asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
11290                asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
11291                asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
11292                asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
11293        }
11294        return warn_code;
11295}
11296
11297static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11298{
11299        int retry;
11300
11301        for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) {
11302                unsigned char read_back;
11303                AscSetChipEEPCmd(iop_base, cmd_reg);
11304                mdelay(1);
11305                read_back = AscGetChipEEPCmd(iop_base);
11306                if (read_back == cmd_reg)
11307                        return 1;
11308        }
11309        return 0;
11310}
11311
11312static void __devinit AscWaitEEPRead(void)
11313{
11314        mdelay(1);
11315}
11316
11317static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
11318{
11319        ushort read_wval;
11320        uchar cmd_reg;
11321
11322        AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11323        AscWaitEEPRead();
11324        cmd_reg = addr | ASC_EEP_CMD_READ;
11325        AscWriteEEPCmdReg(iop_base, cmd_reg);
11326        AscWaitEEPRead();
11327        read_wval = AscGetChipEEPData(iop_base);
11328        AscWaitEEPRead();
11329        return read_wval;
11330}
11331
11332static ushort __devinit
11333AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11334{
11335        ushort wval;
11336        ushort sum;
11337        ushort *wbuf;
11338        int cfg_beg;
11339        int cfg_end;
11340        int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11341        int s_addr;
11342
11343        wbuf = (ushort *)cfg_buf;
11344        sum = 0;
11345        /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11346        for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11347                *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11348                sum += *wbuf;
11349        }
11350        if (bus_type & ASC_IS_VL) {
11351                cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11352                cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11353        } else {
11354                cfg_beg = ASC_EEP_DVC_CFG_BEG;
11355                cfg_end = ASC_EEP_MAX_DVC_ADDR;
11356        }
11357        for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11358                wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11359                if (s_addr <= uchar_end_in_config) {
11360                        /*
11361                         * Swap all char fields - must unswap bytes already swapped
11362                         * by AscReadEEPWord().
11363                         */
11364                        *wbuf = le16_to_cpu(wval);
11365                } else {
11366                        /* Don't swap word field at the end - cntl field. */
11367                        *wbuf = wval;
11368                }
11369                sum += wval;    /* Checksum treats all EEPROM data as words. */
11370        }
11371        /*
11372         * Read the checksum word which will be compared against 'sum'
11373         * by the caller. Word field already swapped.
11374         */
11375        *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11376        return sum;
11377}
11378
11379static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11380{
11381        PortAddr iop_base;
11382        ushort q_addr;
11383        ushort saved_word;
11384        int sta;
11385
11386        iop_base = asc_dvc->iop_base;
11387        sta = 0;
11388        q_addr = ASC_QNO_TO_QADDR(241);
11389        saved_word = AscReadLramWord(iop_base, q_addr);
11390        AscSetChipLramAddr(iop_base, q_addr);
11391        AscSetChipLramData(iop_base, 0x55AA);
11392        mdelay(10);
11393        AscSetChipLramAddr(iop_base, q_addr);
11394        if (AscGetChipLramData(iop_base) == 0x55AA) {
11395                sta = 1;
11396                AscWriteLramWord(iop_base, q_addr, saved_word);
11397        }
11398        return (sta);
11399}
11400
11401static void __devinit AscWaitEEPWrite(void)
11402{
11403        mdelay(20);
11404}
11405
11406static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11407{
11408        ushort read_back;
11409        int retry;
11410
11411        retry = 0;
11412        while (TRUE) {
11413                AscSetChipEEPData(iop_base, data_reg);
11414                mdelay(1);
11415                read_back = AscGetChipEEPData(iop_base);
11416                if (read_back == data_reg) {
11417                        return (1);
11418                }
11419                if (retry++ > ASC_EEP_MAX_RETRY) {
11420                        return (0);
11421                }
11422        }
11423}
11424
11425static ushort __devinit
11426AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11427{
11428        ushort read_wval;
11429
11430        read_wval = AscReadEEPWord(iop_base, addr);
11431        if (read_wval != word_val) {
11432                AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11433                AscWaitEEPRead();
11434                AscWriteEEPDataReg(iop_base, word_val);
11435                AscWaitEEPRead();
11436                AscWriteEEPCmdReg(iop_base,
11437                                  (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11438                AscWaitEEPWrite();
11439                AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11440                AscWaitEEPRead();
11441                return (AscReadEEPWord(iop_base, addr));
11442        }
11443        return (read_wval);
11444}
11445
11446static int __devinit
11447AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11448{
11449        int n_error;
11450        ushort *wbuf;
11451        ushort word;
11452        ushort sum;
11453        int s_addr;
11454        int cfg_beg;
11455        int cfg_end;
11456        int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11457
11458        wbuf = (ushort *)cfg_buf;
11459        n_error = 0;
11460        sum = 0;
11461        /* Write two config words; AscWriteEEPWord() will swap bytes. */
11462        for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11463                sum += *wbuf;
11464                if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11465                        n_error++;
11466                }
11467        }
11468        if (bus_type & ASC_IS_VL) {
11469                cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11470                cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11471        } else {
11472                cfg_beg = ASC_EEP_DVC_CFG_BEG;
11473                cfg_end = ASC_EEP_MAX_DVC_ADDR;
11474        }
11475        for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11476                if (s_addr <= uchar_end_in_config) {
11477                        /*
11478                         * This is a char field. Swap char fields before they are
11479                         * swapped again by AscWriteEEPWord().
11480                         */
11481                        word = cpu_to_le16(*wbuf);
11482                        if (word !=
11483                            AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11484                                n_error++;
11485                        }
11486                } else {
11487                        /* Don't swap word field at the end - cntl field. */
11488                        if (*wbuf !=
11489                            AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11490                                n_error++;
11491                        }
11492                }
11493                sum += *wbuf;   /* Checksum calculated from word values. */
11494        }
11495        /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11496        *wbuf = sum;
11497        if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11498                n_error++;
11499        }
11500
11501        /* Read EEPROM back again. */
11502        wbuf = (ushort *)cfg_buf;
11503        /*
11504         * Read two config words; Byte-swapping done by AscReadEEPWord().
11505         */
11506        for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11507                if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11508                        n_error++;
11509                }
11510        }
11511        if (bus_type & ASC_IS_VL) {
11512                cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11513                cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11514        } else {
11515                cfg_beg = ASC_EEP_DVC_CFG_BEG;
11516                cfg_end = ASC_EEP_MAX_DVC_ADDR;
11517        }
11518        for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11519                if (s_addr <= uchar_end_in_config) {
11520                        /*
11521                         * Swap all char fields. Must unswap bytes already swapped
11522                         * by AscReadEEPWord().
11523                         */
11524                        word =
11525                            le16_to_cpu(AscReadEEPWord
11526                                        (iop_base, (uchar)s_addr));
11527                } else {
11528                        /* Don't swap word field at the end - cntl field. */
11529                        word = AscReadEEPWord(iop_base, (uchar)s_addr);
11530                }
11531                if (*wbuf != word) {
11532                        n_error++;
11533                }
11534        }
11535        /* Read checksum; Byte swapping not needed. */
11536        if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11537                n_error++;
11538        }
11539        return n_error;
11540}
11541
11542static int __devinit
11543AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11544{
11545        int retry;
11546        int n_error;
11547
11548        retry = 0;
11549        while (TRUE) {
11550                if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11551                                                   bus_type)) == 0) {
11552                        break;
11553                }
11554                if (++retry > ASC_EEP_MAX_RETRY) {
11555                        break;
11556                }
11557        }
11558        return n_error;
11559}
11560
11561static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
11562{
11563        ASCEEP_CONFIG eep_config_buf;
11564        ASCEEP_CONFIG *eep_config;
11565        PortAddr iop_base;
11566        ushort chksum;
11567        ushort warn_code;
11568        ushort cfg_msw, cfg_lsw;
11569        int i;
11570        int write_eep = 0;
11571
11572        iop_base = asc_dvc->iop_base;
11573        warn_code = 0;
11574        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
11575        AscStopQueueExe(iop_base);
11576        if ((AscStopChip(iop_base) == FALSE) ||
11577            (AscGetChipScsiCtrl(iop_base) != 0)) {
11578                asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
11579                AscResetChipAndScsiBus(asc_dvc);
11580                mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */
11581        }
11582        if (AscIsChipHalted(iop_base) == FALSE) {
11583                asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11584                return (warn_code);
11585        }
11586        AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11587        if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11588                asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11589                return (warn_code);
11590        }
11591        eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
11592        cfg_msw = AscGetChipCfgMsw(iop_base);
11593        cfg_lsw = AscGetChipCfgLsw(iop_base);
11594        if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11595                cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11596                warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11597                AscSetChipCfgMsw(iop_base, cfg_msw);
11598        }
11599        chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
11600        ASC_DBG(1, "chksum 0x%x\n", chksum);
11601        if (chksum == 0) {
11602                chksum = 0xaa55;
11603        }
11604        if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11605                warn_code |= ASC_WARN_AUTO_CONFIG;
11606                if (asc_dvc->cfg->chip_version == 3) {
11607                        if (eep_config->cfg_lsw != cfg_lsw) {
11608                                warn_code |= ASC_WARN_EEPROM_RECOVER;
11609                                eep_config->cfg_lsw =
11610                                    AscGetChipCfgLsw(iop_base);
11611                        }
11612                        if (eep_config->cfg_msw != cfg_msw) {
11613                                warn_code |= ASC_WARN_EEPROM_RECOVER;
11614                                eep_config->cfg_msw =
11615                                    AscGetChipCfgMsw(iop_base);
11616                        }
11617                }
11618        }
11619        eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11620        eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
11621        ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum);
11622        if (chksum != eep_config->chksum) {
11623                if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
11624                    ASC_CHIP_VER_PCI_ULTRA_3050) {
11625                        ASC_DBG(1, "chksum error ignored; EEPROM-less board\n");
11626                        eep_config->init_sdtr = 0xFF;
11627                        eep_config->disc_enable = 0xFF;
11628                        eep_config->start_motor = 0xFF;
11629                        eep_config->use_cmd_qng = 0;
11630                        eep_config->max_total_qng = 0xF0;
11631                        eep_config->max_tag_qng = 0x20;
11632                        eep_config->cntl = 0xBFFF;
11633                        ASC_EEP_SET_CHIP_ID(eep_config, 7);
11634                        eep_config->no_scam = 0;
11635                        eep_config->adapter_info[0] = 0;
11636                        eep_config->adapter_info[1] = 0;
11637                        eep_config->adapter_info[2] = 0;
11638                        eep_config->adapter_info[3] = 0;
11639                        eep_config->adapter_info[4] = 0;
11640                        /* Indicate EEPROM-less board. */
11641                        eep_config->adapter_info[5] = 0xBB;
11642                } else {
11643                        ASC_PRINT
11644                            ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
11645                        write_eep = 1;
11646                        warn_code |= ASC_WARN_EEPROM_CHKSUM;
11647                }
11648        }
11649        asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
11650        asc_dvc->cfg->disc_enable = eep_config->disc_enable;
11651        asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
11652        asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
11653        asc_dvc->start_motor = eep_config->start_motor;
11654        asc_dvc->dvc_cntl = eep_config->cntl;
11655        asc_dvc->no_scam = eep_config->no_scam;
11656        asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
11657        asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
11658        asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
11659        asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
11660        asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
11661        asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
11662        if (!AscTestExternalLram(asc_dvc)) {
11663                if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
11664                     ASC_IS_PCI_ULTRA)) {
11665                        eep_config->max_total_qng =
11666                            ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
11667                        eep_config->max_tag_qng =
11668                            ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
11669                } else {
11670                        eep_config->cfg_msw |= 0x0800;
11671                        cfg_msw |= 0x0800;
11672                        AscSetChipCfgMsw(iop_base, cfg_msw);
11673                        eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
11674                        eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
11675                }
11676        } else {
11677        }
11678        if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11679                eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11680        }
11681        if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11682                eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11683        }
11684        if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11685                eep_config->max_tag_qng = eep_config->max_total_qng;
11686        }
11687        if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
11688                eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
11689        }
11690        asc_dvc->max_total_qng = eep_config->max_total_qng;
11691        if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
11692            eep_config->use_cmd_qng) {
11693                eep_config->disc_enable = eep_config->use_cmd_qng;
11694                warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11695        }
11696        ASC_EEP_SET_CHIP_ID(eep_config,
11697                            ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
11698        asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
11699        if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
11700            !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
11701                asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
11702        }
11703
11704        for (i = 0; i <= ASC_MAX_TID; i++) {
11705                asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
11706                asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
11707                asc_dvc->cfg->sdtr_period_offset[i] =
11708                    (uchar)(ASC_DEF_SDTR_OFFSET |
11709                            (asc_dvc->min_sdtr_index << 4));
11710        }
11711        eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
11712        if (write_eep) {
11713                if ((i = AscSetEEPConfig(iop_base, eep_config,
11714                                     asc_dvc->bus_type)) != 0) {
11715                        ASC_PRINT1
11716                            ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
11717                             i);
11718                } else {
11719                        ASC_PRINT
11720                            ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
11721                }
11722        }
11723        return (warn_code);
11724}
11725
11726static int __devinit AscInitGetConfig(struct Scsi_Host *shost)
11727{
11728        struct asc_board *board = shost_priv(shost);
11729        ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
11730        unsigned short warn_code = 0;
11731
11732        asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11733        if (asc_dvc->err_code != 0)
11734                return asc_dvc->err_code;
11735
11736        if (AscFindSignature(asc_dvc->iop_base)) {
11737                warn_code |= AscInitAscDvcVar(asc_dvc);
11738                warn_code |= AscInitFromEEP(asc_dvc);
11739                asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11740                if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
11741                        asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11742        } else {
11743                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11744        }
11745
11746        switch (warn_code) {
11747        case 0: /* No error */
11748                break;
11749        case ASC_WARN_IO_PORT_ROTATE:
11750                shost_printk(KERN_WARNING, shost, "I/O port address "
11751                                "modified\n");
11752                break;
11753        case ASC_WARN_AUTO_CONFIG:
11754                shost_printk(KERN_WARNING, shost, "I/O port increment switch "
11755                                "enabled\n");
11756                break;
11757        case ASC_WARN_EEPROM_CHKSUM:
11758                shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
11759                break;
11760        case ASC_WARN_IRQ_MODIFIED:
11761                shost_printk(KERN_WARNING, shost, "IRQ modified\n");
11762                break;
11763        case ASC_WARN_CMD_QNG_CONFLICT:
11764                shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o "
11765                                "disconnects\n");
11766                break;
11767        default:
11768                shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
11769                                warn_code);
11770                break;
11771        }
11772
11773        if (asc_dvc->err_code != 0)
11774                shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
11775                        "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
11776
11777        return asc_dvc->err_code;
11778}
11779
11780static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
11781{
11782        struct asc_board *board = shost_priv(shost);
11783        ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var;
11784        PortAddr iop_base = asc_dvc->iop_base;
11785        unsigned short cfg_msw;
11786        unsigned short warn_code = 0;
11787
11788        asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11789        if (asc_dvc->err_code != 0)
11790                return asc_dvc->err_code;
11791        if (!AscFindSignature(asc_dvc->iop_base)) {
11792                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11793                return asc_dvc->err_code;
11794        }
11795
11796        cfg_msw = AscGetChipCfgMsw(iop_base);
11797        if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11798                cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11799                warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11800                AscSetChipCfgMsw(iop_base, cfg_msw);
11801        }
11802        if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
11803            asc_dvc->cfg->cmd_qng_enabled) {
11804                asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
11805                warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11806        }
11807        if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11808                warn_code |= ASC_WARN_AUTO_CONFIG;
11809        }
11810#ifdef CONFIG_PCI
11811        if (asc_dvc->bus_type & ASC_IS_PCI) {
11812                cfg_msw &= 0xFFC0;
11813                AscSetChipCfgMsw(iop_base, cfg_msw);
11814                if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
11815                } else {
11816                        if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
11817                            (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
11818                                asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
11819                                asc_dvc->bug_fix_cntl |=
11820                                    ASC_BUG_FIX_ASYN_USE_SYN;
11821                        }
11822                }
11823        } else
11824#endif /* CONFIG_PCI */
11825        if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
11826                if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
11827                    == ASC_CHIP_VER_ASYN_BUG) {
11828                        asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
11829                }
11830        }
11831        if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
11832            asc_dvc->cfg->chip_scsi_id) {
11833                asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
11834        }
11835#ifdef CONFIG_ISA
11836        if (asc_dvc->bus_type & ASC_IS_ISA) {
11837                AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
11838                AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
11839        }
11840#endif /* CONFIG_ISA */
11841
11842        asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11843
11844        switch (warn_code) {
11845        case 0: /* No error. */
11846                break;
11847        case ASC_WARN_IO_PORT_ROTATE:
11848                shost_printk(KERN_WARNING, shost, "I/O port address "
11849                                "modified\n");
11850                break;
11851        case ASC_WARN_AUTO_CONFIG:
11852                shost_printk(KERN_WARNING, shost, "I/O port increment switch "
11853                                "enabled\n");
11854                break;
11855        case ASC_WARN_EEPROM_CHKSUM:
11856                shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n");
11857                break;
11858        case ASC_WARN_IRQ_MODIFIED:
11859                shost_printk(KERN_WARNING, shost, "IRQ modified\n");
11860                break;
11861        case ASC_WARN_CMD_QNG_CONFLICT:
11862                shost_printk(KERN_WARNING, shost, "tag queuing w/o "
11863                                "disconnects\n");
11864                break;
11865        default:
11866                shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n",
11867                                warn_code);
11868                break;
11869        }
11870
11871        if (asc_dvc->err_code != 0)
11872                shost_printk(KERN_ERR, shost, "error 0x%x at init_state "
11873                        "0x%x\n", asc_dvc->err_code, asc_dvc->init_state);
11874
11875        return asc_dvc->err_code;
11876}
11877
11878/*
11879 * EEPROM Configuration.
11880 *
11881 * All drivers should use this structure to set the default EEPROM
11882 * configuration. The BIOS now uses this structure when it is built.
11883 * Additional structure information can be found in a_condor.h where
11884 * the structure is defined.
11885 *
11886 * The *_Field_IsChar structs are needed to correct for endianness.
11887 * These values are read from the board 16 bits at a time directly
11888 * into the structs. Because some fields are char, the values will be
11889 * in the wrong order. The *_Field_IsChar tells when to flip the
11890 * bytes. Data read and written to PCI memory is automatically swapped
11891 * on big-endian platforms so char fields read as words are actually being
11892 * unswapped on big-endian platforms.
11893 */
11894static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
11895        ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
11896        0x0000,                 /* cfg_msw */
11897        0xFFFF,                 /* disc_enable */
11898        0xFFFF,                 /* wdtr_able */
11899        0xFFFF,                 /* sdtr_able */
11900        0xFFFF,                 /* start_motor */
11901        0xFFFF,                 /* tagqng_able */
11902        0xFFFF,                 /* bios_scan */
11903        0,                      /* scam_tolerant */
11904        7,                      /* adapter_scsi_id */
11905        0,                      /* bios_boot_delay */
11906        3,                      /* scsi_reset_delay */
11907        0,                      /* bios_id_lun */
11908        0,                      /* termination */
11909        0,                      /* reserved1 */
11910        0xFFE7,                 /* bios_ctrl */
11911        0xFFFF,                 /* ultra_able */
11912        0,                      /* reserved2 */
11913        ASC_DEF_MAX_HOST_QNG,   /* max_host_qng */
11914        ASC_DEF_MAX_DVC_QNG,    /* max_dvc_qng */
11915        0,                      /* dvc_cntl */
11916        0,                      /* bug_fix */
11917        0,                      /* serial_number_word1 */
11918        0,                      /* serial_number_word2 */
11919        0,                      /* serial_number_word3 */
11920        0,                      /* check_sum */
11921        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11922        ,                       /* oem_name[16] */
11923        0,                      /* dvc_err_code */
11924        0,                      /* adv_err_code */
11925        0,                      /* adv_err_addr */
11926        0,                      /* saved_dvc_err_code */
11927        0,                      /* saved_adv_err_code */
11928        0,                      /* saved_adv_err_addr */
11929        0                       /* num_of_err */
11930};
11931
11932static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
11933        0,                      /* cfg_lsw */
11934        0,                      /* cfg_msw */
11935        0,                      /* -disc_enable */
11936        0,                      /* wdtr_able */
11937        0,                      /* sdtr_able */
11938        0,                      /* start_motor */
11939        0,                      /* tagqng_able */
11940        0,                      /* bios_scan */
11941        0,                      /* scam_tolerant */
11942        1,                      /* adapter_scsi_id */
11943        1,                      /* bios_boot_delay */
11944        1,                      /* scsi_reset_delay */
11945        1,                      /* bios_id_lun */
11946        1,                      /* termination */
11947        1,                      /* reserved1 */
11948        0,                      /* bios_ctrl */
11949        0,                      /* ultra_able */
11950        0,                      /* reserved2 */
11951        1,                      /* max_host_qng */
11952        1,                      /* max_dvc_qng */
11953        0,                      /* dvc_cntl */
11954        0,                      /* bug_fix */
11955        0,                      /* serial_number_word1 */
11956        0,                      /* serial_number_word2 */
11957        0,                      /* serial_number_word3 */
11958        0,                      /* check_sum */
11959        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
11960        ,                       /* oem_name[16] */
11961        0,                      /* dvc_err_code */
11962        0,                      /* adv_err_code */
11963        0,                      /* adv_err_addr */
11964        0,                      /* saved_dvc_err_code */
11965        0,                      /* saved_adv_err_code */
11966        0,                      /* saved_adv_err_addr */
11967        0                       /* num_of_err */
11968};
11969
11970static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
11971        ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
11972        0x0000,                 /* 01 cfg_msw */
11973        0xFFFF,                 /* 02 disc_enable */
11974        0xFFFF,                 /* 03 wdtr_able */
11975        0x4444,                 /* 04 sdtr_speed1 */
11976        0xFFFF,                 /* 05 start_motor */
11977        0xFFFF,                 /* 06 tagqng_able */
11978        0xFFFF,                 /* 07 bios_scan */
11979        0,                      /* 08 scam_tolerant */
11980        7,                      /* 09 adapter_scsi_id */
11981        0,                      /*    bios_boot_delay */
11982        3,                      /* 10 scsi_reset_delay */
11983        0,                      /*    bios_id_lun */
11984        0,                      /* 11 termination_se */
11985        0,                      /*    termination_lvd */
11986        0xFFE7,                 /* 12 bios_ctrl */
11987        0x4444,                 /* 13 sdtr_speed2 */
11988        0x4444,                 /* 14 sdtr_speed3 */
11989        ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
11990        ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
11991        0,                      /* 16 dvc_cntl */
11992        0x4444,                 /* 17 sdtr_speed4 */
11993        0,                      /* 18 serial_number_word1 */
11994        0,                      /* 19 serial_number_word2 */
11995        0,                      /* 20 serial_number_word3 */
11996        0,                      /* 21 check_sum */
11997        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
11998        ,                       /* 22-29 oem_name[16] */
11999        0,                      /* 30 dvc_err_code */
12000        0,                      /* 31 adv_err_code */
12001        0,                      /* 32 adv_err_addr */
12002        0,                      /* 33 saved_dvc_err_code */
12003        0,                      /* 34 saved_adv_err_code */
12004        0,                      /* 35 saved_adv_err_addr */
12005        0,                      /* 36 reserved */
12006        0,                      /* 37 reserved */
12007        0,                      /* 38 reserved */
12008        0,                      /* 39 reserved */
12009        0,                      /* 40 reserved */
12010        0,                      /* 41 reserved */
12011        0,                      /* 42 reserved */
12012        0,                      /* 43 reserved */
12013        0,                      /* 44 reserved */
12014        0,                      /* 45 reserved */
12015        0,                      /* 46 reserved */
12016        0,                      /* 47 reserved */
12017        0,                      /* 48 reserved */
12018        0,                      /* 49 reserved */
12019        0,                      /* 50 reserved */
12020        0,                      /* 51 reserved */
12021        0,                      /* 52 reserved */
12022        0,                      /* 53 reserved */
12023        0,                      /* 54 reserved */
12024        0,                      /* 55 reserved */
12025        0,                      /* 56 cisptr_lsw */
12026        0,                      /* 57 cisprt_msw */
12027        PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
12028        PCI_DEVICE_ID_38C0800_REV1,     /* 59 subsysid */
12029        0,                      /* 60 reserved */
12030        0,                      /* 61 reserved */
12031        0,                      /* 62 reserved */
12032        0                       /* 63 reserved */
12033};
12034
12035static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
12036        0,                      /* 00 cfg_lsw */
12037        0,                      /* 01 cfg_msw */
12038        0,                      /* 02 disc_enable */
12039        0,                      /* 03 wdtr_able */
12040        0,                      /* 04 sdtr_speed1 */
12041        0,                      /* 05 start_motor */
12042        0,                      /* 06 tagqng_able */
12043        0,                      /* 07 bios_scan */
12044        0,                      /* 08 scam_tolerant */
12045        1,                      /* 09 adapter_scsi_id */
12046        1,                      /*    bios_boot_delay */
12047        1,                      /* 10 scsi_reset_delay */
12048        1,                      /*    bios_id_lun */
12049        1,                      /* 11 termination_se */
12050        1,                      /*    termination_lvd */
12051        0,                      /* 12 bios_ctrl */
12052        0,                      /* 13 sdtr_speed2 */
12053        0,                      /* 14 sdtr_speed3 */
12054        1,                      /* 15 max_host_qng */
12055        1,                      /*    max_dvc_qng */
12056        0,                      /* 16 dvc_cntl */
12057        0,                      /* 17 sdtr_speed4 */
12058        0,                      /* 18 serial_number_word1 */
12059        0,                      /* 19 serial_number_word2 */
12060        0,                      /* 20 serial_number_word3 */
12061        0,                      /* 21 check_sum */
12062        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12063        ,                       /* 22-29 oem_name[16] */
12064        0,                      /* 30 dvc_err_code */
12065        0,                      /* 31 adv_err_code */
12066        0,                      /* 32 adv_err_addr */
12067        0,                      /* 33 saved_dvc_err_code */
12068        0,                      /* 34 saved_adv_err_code */
12069        0,                      /* 35 saved_adv_err_addr */
12070        0,                      /* 36 reserved */
12071        0,                      /* 37 reserved */
12072        0,                      /* 38 reserved */
12073        0,                      /* 39 reserved */
12074        0,                      /* 40 reserved */
12075        0,                      /* 41 reserved */
12076        0,                      /* 42 reserved */
12077        0,                      /* 43 reserved */
12078        0,                      /* 44 reserved */
12079        0,                      /* 45 reserved */
12080        0,                      /* 46 reserved */
12081        0,                      /* 47 reserved */
12082        0,                      /* 48 reserved */
12083        0,                      /* 49 reserved */
12084        0,                      /* 50 reserved */
12085        0,                      /* 51 reserved */
12086        0,                      /* 52 reserved */
12087        0,                      /* 53 reserved */
12088        0,                      /* 54 reserved */
12089        0,                      /* 55 reserved */
12090        0,                      /* 56 cisptr_lsw */
12091        0,                      /* 57 cisprt_msw */
12092        0,                      /* 58 subsysvid */
12093        0,                      /* 59 subsysid */
12094        0,                      /* 60 reserved */
12095        0,                      /* 61 reserved */
12096        0,                      /* 62 reserved */
12097        0                       /* 63 reserved */
12098};
12099
12100static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
12101        ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
12102        0x0000,                 /* 01 cfg_msw */
12103        0xFFFF,                 /* 02 disc_enable */
12104        0xFFFF,                 /* 03 wdtr_able */
12105        0x5555,                 /* 04 sdtr_speed1 */
12106        0xFFFF,                 /* 05 start_motor */
12107        0xFFFF,                 /* 06 tagqng_able */
12108        0xFFFF,                 /* 07 bios_scan */
12109        0,                      /* 08 scam_tolerant */
12110        7,                      /* 09 adapter_scsi_id */
12111        0,                      /*    bios_boot_delay */
12112        3,                      /* 10 scsi_reset_delay */
12113        0,                      /*    bios_id_lun */
12114        0,                      /* 11 termination_se */
12115        0,                      /*    termination_lvd */
12116        0xFFE7,                 /* 12 bios_ctrl */
12117        0x5555,                 /* 13 sdtr_speed2 */
12118        0x5555,                 /* 14 sdtr_speed3 */
12119        ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
12120        ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
12121        0,                      /* 16 dvc_cntl */
12122        0x5555,                 /* 17 sdtr_speed4 */
12123        0,                      /* 18 serial_number_word1 */
12124        0,                      /* 19 serial_number_word2 */
12125        0,                      /* 20 serial_number_word3 */
12126        0,                      /* 21 check_sum */
12127        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
12128        ,                       /* 22-29 oem_name[16] */
12129        0,                      /* 30 dvc_err_code */
12130        0,                      /* 31 adv_err_code */
12131        0,                      /* 32 adv_err_addr */
12132        0,                      /* 33 saved_dvc_err_code */
12133        0,                      /* 34 saved_adv_err_code */
12134        0,                      /* 35 saved_adv_err_addr */
12135        0,                      /* 36 reserved */
12136        0,                      /* 37 reserved */
12137        0,                      /* 38 reserved */
12138        0,                      /* 39 reserved */
12139        0,                      /* 40 reserved */
12140        0,                      /* 41 reserved */
12141        0,                      /* 42 reserved */
12142        0,                      /* 43 reserved */
12143        0,                      /* 44 reserved */
12144        0,                      /* 45 reserved */
12145        0,                      /* 46 reserved */
12146        0,                      /* 47 reserved */
12147        0,                      /* 48 reserved */
12148        0,                      /* 49 reserved */
12149        0,                      /* 50 reserved */
12150        0,                      /* 51 reserved */
12151        0,                      /* 52 reserved */
12152        0,                      /* 53 reserved */
12153        0,                      /* 54 reserved */
12154        0,                      /* 55 reserved */
12155        0,                      /* 56 cisptr_lsw */
12156        0,                      /* 57 cisprt_msw */
12157        PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
12158        PCI_DEVICE_ID_38C1600_REV1,     /* 59 subsysid */
12159        0,                      /* 60 reserved */
12160        0,                      /* 61 reserved */
12161        0,                      /* 62 reserved */
12162        0                       /* 63 reserved */
12163};
12164
12165static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
12166        0,                      /* 00 cfg_lsw */
12167        0,                      /* 01 cfg_msw */
12168        0,                      /* 02 disc_enable */
12169        0,                      /* 03 wdtr_able */
12170        0,                      /* 04 sdtr_speed1 */
12171        0,                      /* 05 start_motor */
12172        0,                      /* 06 tagqng_able */
12173        0,                      /* 07 bios_scan */
12174        0,                      /* 08 scam_tolerant */
12175        1,                      /* 09 adapter_scsi_id */
12176        1,                      /*    bios_boot_delay */
12177        1,                      /* 10 scsi_reset_delay */
12178        1,                      /*    bios_id_lun */
12179        1,                      /* 11 termination_se */
12180        1,                      /*    termination_lvd */
12181        0,                      /* 12 bios_ctrl */
12182        0,                      /* 13 sdtr_speed2 */
12183        0,                      /* 14 sdtr_speed3 */
12184        1,                      /* 15 max_host_qng */
12185        1,                      /*    max_dvc_qng */
12186        0,                      /* 16 dvc_cntl */
12187        0,                      /* 17 sdtr_speed4 */
12188        0,                      /* 18 serial_number_word1 */
12189        0,                      /* 19 serial_number_word2 */
12190        0,                      /* 20 serial_number_word3 */
12191        0,                      /* 21 check_sum */
12192        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
12193        ,                       /* 22-29 oem_name[16] */
12194        0,                      /* 30 dvc_err_code */
12195        0,                      /* 31 adv_err_code */
12196        0,                      /* 32 adv_err_addr */
12197        0,                      /* 33 saved_dvc_err_code */
12198        0,                      /* 34 saved_adv_err_code */
12199        0,                      /* 35 saved_adv_err_addr */
12200        0,                      /* 36 reserved */
12201        0,                      /* 37 reserved */
12202        0,                      /* 38 reserved */
12203        0,                      /* 39 reserved */
12204        0,                      /* 40 reserved */
12205        0,                      /* 41 reserved */
12206        0,                      /* 42 reserved */
12207        0,                      /* 43 reserved */
12208        0,                      /* 44 reserved */
12209        0,                      /* 45 reserved */
12210        0,                      /* 46 reserved */
12211        0,                      /* 47 reserved */
12212        0,                      /* 48 reserved */
12213        0,                      /* 49 reserved */
12214        0,                      /* 50 reserved */
12215        0,                      /* 51 reserved */
12216        0,                      /* 52 reserved */
12217        0,                      /* 53 reserved */
12218        0,                      /* 54 reserved */
12219        0,                      /* 55 reserved */
12220        0,                      /* 56 cisptr_lsw */
12221        0,                      /* 57 cisprt_msw */
12222        0,                      /* 58 subsysvid */
12223        0,                      /* 59 subsysid */
12224        0,                      /* 60 reserved */
12225        0,                      /* 61 reserved */
12226        0,                      /* 62 reserved */
12227        0                       /* 63 reserved */
12228};
12229
12230#ifdef CONFIG_PCI
12231/*
12232 * Wait for EEPROM command to complete
12233 */
12234static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
12235{
12236        int eep_delay_ms;
12237
12238        for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
12239                if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
12240                    ASC_EEP_CMD_DONE) {
12241                        break;
12242                }
12243                mdelay(1);
12244        }
12245        if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
12246            0)
12247                BUG();
12248}
12249
12250/*
12251 * Read the EEPROM from specified location
12252 */
12253static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
12254{
12255        AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12256                             ASC_EEP_CMD_READ | eep_word_addr);
12257        AdvWaitEEPCmd(iop_base);
12258        return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
12259}
12260
12261/*
12262 * Write the EEPROM from 'cfg_buf'.
12263 */
12264void __devinit
12265AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12266{
12267        ushort *wbuf;
12268        ushort addr, chksum;
12269        ushort *charfields;
12270
12271        wbuf = (ushort *)cfg_buf;
12272        charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12273        chksum = 0;
12274
12275        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12276        AdvWaitEEPCmd(iop_base);
12277
12278        /*
12279         * Write EEPROM from word 0 to word 20.
12280         */
12281        for (addr = ADV_EEP_DVC_CFG_BEGIN;
12282             addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12283                ushort word;
12284
12285                if (*charfields++) {
12286                        word = cpu_to_le16(*wbuf);
12287                } else {
12288                        word = *wbuf;
12289                }
12290                chksum += *wbuf;        /* Checksum is calculated from word values. */
12291                AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12292                AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12293                                     ASC_EEP_CMD_WRITE | addr);
12294                AdvWaitEEPCmd(iop_base);
12295                mdelay(ADV_EEP_DELAY_MS);
12296        }
12297
12298        /*
12299         * Write EEPROM checksum at word 21.
12300         */
12301        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12302        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12303        AdvWaitEEPCmd(iop_base);
12304        wbuf++;
12305        charfields++;
12306
12307        /*
12308         * Write EEPROM OEM name at words 22 to 29.
12309         */
12310        for (addr = ADV_EEP_DVC_CTL_BEGIN;
12311             addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12312                ushort word;
12313
12314                if (*charfields++) {
12315                        word = cpu_to_le16(*wbuf);
12316                } else {
12317                        word = *wbuf;
12318                }
12319                AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12320                AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12321                                     ASC_EEP_CMD_WRITE | addr);
12322                AdvWaitEEPCmd(iop_base);
12323        }
12324        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12325        AdvWaitEEPCmd(iop_base);
12326}
12327
12328/*
12329 * Write the EEPROM from 'cfg_buf'.
12330 */
12331void __devinit
12332AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12333{
12334        ushort *wbuf;
12335        ushort *charfields;
12336        ushort addr, chksum;
12337
12338        wbuf = (ushort *)cfg_buf;
12339        charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12340        chksum = 0;
12341
12342        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12343        AdvWaitEEPCmd(iop_base);
12344
12345        /*
12346         * Write EEPROM from word 0 to word 20.
12347         */
12348        for (addr = ADV_EEP_DVC_CFG_BEGIN;
12349             addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12350                ushort word;
12351
12352                if (*charfields++) {
12353                        word = cpu_to_le16(*wbuf);
12354                } else {
12355                        word = *wbuf;
12356                }
12357                chksum += *wbuf;        /* Checksum is calculated from word values. */
12358                AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12359                AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12360                                     ASC_EEP_CMD_WRITE | addr);
12361                AdvWaitEEPCmd(iop_base);
12362                mdelay(ADV_EEP_DELAY_MS);
12363        }
12364
12365        /*
12366         * Write EEPROM checksum at word 21.
12367         */
12368        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12369        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12370        AdvWaitEEPCmd(iop_base);
12371        wbuf++;
12372        charfields++;
12373
12374        /*
12375         * Write EEPROM OEM name at words 22 to 29.
12376         */
12377        for (addr = ADV_EEP_DVC_CTL_BEGIN;
12378             addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12379                ushort word;
12380
12381                if (*charfields++) {
12382                        word = cpu_to_le16(*wbuf);
12383                } else {
12384                        word = *wbuf;
12385                }
12386                AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12387                AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12388                                     ASC_EEP_CMD_WRITE | addr);
12389                AdvWaitEEPCmd(iop_base);
12390        }
12391        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12392        AdvWaitEEPCmd(iop_base);
12393}
12394
12395/*
12396 * Write the EEPROM from 'cfg_buf'.
12397 */
12398void __devinit
12399AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12400{
12401        ushort *wbuf;
12402        ushort *charfields;
12403        ushort addr, chksum;
12404
12405        wbuf = (ushort *)cfg_buf;
12406        charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12407        chksum = 0;
12408
12409        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
12410        AdvWaitEEPCmd(iop_base);
12411
12412        /*
12413         * Write EEPROM from word 0 to word 20.
12414         */
12415        for (addr = ADV_EEP_DVC_CFG_BEGIN;
12416             addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
12417                ushort word;
12418
12419                if (*charfields++) {
12420                        word = cpu_to_le16(*wbuf);
12421                } else {
12422                        word = *wbuf;
12423                }
12424                chksum += *wbuf;        /* Checksum is calculated from word values. */
12425                AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12426                AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12427                                     ASC_EEP_CMD_WRITE | addr);
12428                AdvWaitEEPCmd(iop_base);
12429                mdelay(ADV_EEP_DELAY_MS);
12430        }
12431
12432        /*
12433         * Write EEPROM checksum at word 21.
12434         */
12435        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
12436        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
12437        AdvWaitEEPCmd(iop_base);
12438        wbuf++;
12439        charfields++;
12440
12441        /*
12442         * Write EEPROM OEM name at words 22 to 29.
12443         */
12444        for (addr = ADV_EEP_DVC_CTL_BEGIN;
12445             addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
12446                ushort word;
12447
12448                if (*charfields++) {
12449                        word = cpu_to_le16(*wbuf);
12450                } else {
12451                        word = *wbuf;
12452                }
12453                AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
12454                AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
12455                                     ASC_EEP_CMD_WRITE | addr);
12456                AdvWaitEEPCmd(iop_base);
12457        }
12458        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
12459        AdvWaitEEPCmd(iop_base);
12460}
12461
12462/*
12463 * Read EEPROM configuration into the specified buffer.
12464 *
12465 * Return a checksum based on the EEPROM configuration read.
12466 */
12467static ushort __devinit
12468AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
12469{
12470        ushort wval, chksum;
12471        ushort *wbuf;
12472        int eep_addr;
12473        ushort *charfields;
12474
12475        charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
12476        wbuf = (ushort *)cfg_buf;
12477        chksum = 0;
12478
12479        for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12480             eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12481                wval = AdvReadEEPWord(iop_base, eep_addr);
12482                chksum += wval; /* Checksum is calculated from word values. */
12483                if (*charfields++) {
12484                        *wbuf = le16_to_cpu(wval);
12485                } else {
12486                        *wbuf = wval;
12487                }
12488        }
12489        /* Read checksum word. */
12490        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12491        wbuf++;
12492        charfields++;
12493
12494        /* Read rest of EEPROM not covered by the checksum. */
12495        for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12496             eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12497                *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12498                if (*charfields++) {
12499                        *wbuf = le16_to_cpu(*wbuf);
12500                }
12501        }
12502        return chksum;
12503}
12504
12505/*
12506 * Read EEPROM configuration into the specified buffer.
12507 *
12508 * Return a checksum based on the EEPROM configuration read.
12509 */
12510static ushort __devinit
12511AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
12512{
12513        ushort wval, chksum;
12514        ushort *wbuf;
12515        int eep_addr;
12516        ushort *charfields;
12517
12518        charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
12519        wbuf = (ushort *)cfg_buf;
12520        chksum = 0;
12521
12522        for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12523             eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12524                wval = AdvReadEEPWord(iop_base, eep_addr);
12525                chksum += wval; /* Checksum is calculated from word values. */
12526                if (*charfields++) {
12527                        *wbuf = le16_to_cpu(wval);
12528                } else {
12529                        *wbuf = wval;
12530                }
12531        }
12532        /* Read checksum word. */
12533        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12534        wbuf++;
12535        charfields++;
12536
12537        /* Read rest of EEPROM not covered by the checksum. */
12538        for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12539             eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12540                *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12541                if (*charfields++) {
12542                        *wbuf = le16_to_cpu(*wbuf);
12543                }
12544        }
12545        return chksum;
12546}
12547
12548/*
12549 * Read EEPROM configuration into the specified buffer.
12550 *
12551 * Return a checksum based on the EEPROM configuration read.
12552 */
12553static ushort __devinit
12554AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
12555{
12556        ushort wval, chksum;
12557        ushort *wbuf;
12558        int eep_addr;
12559        ushort *charfields;
12560
12561        charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
12562        wbuf = (ushort *)cfg_buf;
12563        chksum = 0;
12564
12565        for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
12566             eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
12567                wval = AdvReadEEPWord(iop_base, eep_addr);
12568                chksum += wval; /* Checksum is calculated from word values. */
12569                if (*charfields++) {
12570                        *wbuf = le16_to_cpu(wval);
12571                } else {
12572                        *wbuf = wval;
12573                }
12574        }
12575        /* Read checksum word. */
12576        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12577        wbuf++;
12578        charfields++;
12579
12580        /* Read rest of EEPROM not covered by the checksum. */
12581        for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
12582             eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
12583                *wbuf = AdvReadEEPWord(iop_base, eep_addr);
12584                if (*charfields++) {
12585                        *wbuf = le16_to_cpu(*wbuf);
12586                }
12587        }
12588        return chksum;
12589}
12590
12591/*
12592 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12593 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12594 * all of this is done.
12595 *
12596 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12597 *
12598 * For a non-fatal error return a warning code. If there are no warnings
12599 * then 0 is returned.
12600 *
12601 * Note: Chip is stopped on entry.
12602 */
12603static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
12604{
12605        AdvPortAddr iop_base;
12606        ushort warn_code;
12607        ADVEEP_3550_CONFIG eep_config;
12608
12609        iop_base = asc_dvc->iop_base;
12610
12611        warn_code = 0;
12612
12613        /*
12614         * Read the board's EEPROM configuration.
12615         *
12616         * Set default values if a bad checksum is found.
12617         */
12618        if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
12619                warn_code |= ASC_WARN_EEPROM_CHKSUM;
12620
12621                /*
12622                 * Set EEPROM default values.
12623                 */
12624                memcpy(&eep_config, &Default_3550_EEPROM_Config,
12625                        sizeof(ADVEEP_3550_CONFIG));
12626
12627                /*
12628                 * Assume the 6 byte board serial number that was read from
12629                 * EEPROM is correct even if the EEPROM checksum failed.
12630                 */
12631                eep_config.serial_number_word3 =
12632                    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
12633
12634                eep_config.serial_number_word2 =
12635                    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
12636
12637                eep_config.serial_number_word1 =
12638                    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
12639
12640                AdvSet3550EEPConfig(iop_base, &eep_config);
12641        }
12642        /*
12643         * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
12644         * EEPROM configuration that was read.
12645         *
12646         * This is the mapping of EEPROM fields to Adv Library fields.
12647         */
12648        asc_dvc->wdtr_able = eep_config.wdtr_able;
12649        asc_dvc->sdtr_able = eep_config.sdtr_able;
12650        asc_dvc->ultra_able = eep_config.ultra_able;
12651        asc_dvc->tagqng_able = eep_config.tagqng_able;
12652        asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12653        asc_dvc->max_host_qng = eep_config.max_host_qng;
12654        asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12655        asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12656        asc_dvc->start_motor = eep_config.start_motor;
12657        asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12658        asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12659        asc_dvc->no_scam = eep_config.scam_tolerant;
12660        asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12661        asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12662        asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12663
12664        /*
12665         * Set the host maximum queuing (max. 253, min. 16) and the per device
12666         * maximum queuing (max. 63, min. 4).
12667         */
12668        if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12669                eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12670        } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12671                /* If the value is zero, assume it is uninitialized. */
12672                if (eep_config.max_host_qng == 0) {
12673                        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12674                } else {
12675                        eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12676                }
12677        }
12678
12679        if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12680                eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12681        } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12682                /* If the value is zero, assume it is uninitialized. */
12683                if (eep_config.max_dvc_qng == 0) {
12684                        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12685                } else {
12686                        eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12687                }
12688        }
12689
12690        /*
12691         * If 'max_dvc_qng' is greater than 'max_host_qng', then
12692         * set 'max_dvc_qng' to 'max_host_qng'.
12693         */
12694        if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12695                eep_config.max_dvc_qng = eep_config.max_host_qng;
12696        }
12697
12698        /*
12699         * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12700         * values based on possibly adjusted EEPROM values.
12701         */
12702        asc_dvc->max_host_qng = eep_config.max_host_qng;
12703        asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12704
12705        /*
12706         * If the EEPROM 'termination' field is set to automatic (0), then set
12707         * the ADV_DVC_CFG 'termination' field to automatic also.
12708         *
12709         * If the termination is specified with a non-zero 'termination'
12710         * value check that a legal value is set and set the ADV_DVC_CFG
12711         * 'termination' field appropriately.
12712         */
12713        if (eep_config.termination == 0) {
12714                asc_dvc->cfg->termination = 0;  /* auto termination */
12715        } else {
12716                /* Enable manual control with low off / high off. */
12717                if (eep_config.termination == 1) {
12718                        asc_dvc->cfg->termination = TERM_CTL_SEL;
12719
12720                        /* Enable manual control with low off / high on. */
12721                } else if (eep_config.termination == 2) {
12722                        asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
12723
12724                        /* Enable manual control with low on / high on. */
12725                } else if (eep_config.termination == 3) {
12726                        asc_dvc->cfg->termination =
12727                            TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
12728                } else {
12729                        /*
12730                         * The EEPROM 'termination' field contains a bad value. Use
12731                         * automatic termination instead.
12732                         */
12733                        asc_dvc->cfg->termination = 0;
12734                        warn_code |= ASC_WARN_EEPROM_TERMINATION;
12735                }
12736        }
12737
12738        return warn_code;
12739}
12740
12741/*
12742 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
12743 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
12744 * all of this is done.
12745 *
12746 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
12747 *
12748 * For a non-fatal error return a warning code. If there are no warnings
12749 * then 0 is returned.
12750 *
12751 * Note: Chip is stopped on entry.
12752 */
12753static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
12754{
12755        AdvPortAddr iop_base;
12756        ushort warn_code;
12757        ADVEEP_38C0800_CONFIG eep_config;
12758        uchar tid, termination;
12759        ushort sdtr_speed = 0;
12760
12761        iop_base = asc_dvc->iop_base;
12762
12763        warn_code = 0;
12764
12765        /*
12766         * Read the board's EEPROM configuration.
12767         *
12768         * Set default values if a bad checksum is found.
12769         */
12770        if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
12771            eep_config.check_sum) {
12772                warn_code |= ASC_WARN_EEPROM_CHKSUM;
12773
12774                /*
12775                 * Set EEPROM default values.
12776                 */
12777                memcpy(&eep_config, &Default_38C0800_EEPROM_Config,
12778                        sizeof(ADVEEP_38C0800_CONFIG));
12779
12780                /*
12781                 * Assume the 6 byte board serial number that was read from
12782                 * EEPROM is correct even if the EEPROM checksum failed.
12783                 */
12784                eep_config.serial_number_word3 =
12785                    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
12786
12787                eep_config.serial_number_word2 =
12788                    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
12789
12790                eep_config.serial_number_word1 =
12791                    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
12792
12793                AdvSet38C0800EEPConfig(iop_base, &eep_config);
12794        }
12795        /*
12796         * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
12797         * EEPROM configuration that was read.
12798         *
12799         * This is the mapping of EEPROM fields to Adv Library fields.
12800         */
12801        asc_dvc->wdtr_able = eep_config.wdtr_able;
12802        asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
12803        asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
12804        asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
12805        asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
12806        asc_dvc->tagqng_able = eep_config.tagqng_able;
12807        asc_dvc->cfg->disc_enable = eep_config.disc_enable;
12808        asc_dvc->max_host_qng = eep_config.max_host_qng;
12809        asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12810        asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
12811        asc_dvc->start_motor = eep_config.start_motor;
12812        asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
12813        asc_dvc->bios_ctrl = eep_config.bios_ctrl;
12814        asc_dvc->no_scam = eep_config.scam_tolerant;
12815        asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
12816        asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
12817        asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
12818
12819        /*
12820         * For every Target ID if any of its 'sdtr_speed[1234]' bits
12821         * are set, then set an 'sdtr_able' bit for it.
12822         */
12823        asc_dvc->sdtr_able = 0;
12824        for (tid = 0; tid <= ADV_MAX_TID; tid++) {
12825                if (tid == 0) {
12826                        sdtr_speed = asc_dvc->sdtr_speed1;
12827                } else if (tid == 4) {
12828                        sdtr_speed = asc_dvc->sdtr_speed2;
12829                } else if (tid == 8) {
12830                        sdtr_speed = asc_dvc->sdtr_speed3;
12831                } else if (tid == 12) {
12832                        sdtr_speed = asc_dvc->sdtr_speed4;
12833                }
12834                if (sdtr_speed & ADV_MAX_TID) {
12835                        asc_dvc->sdtr_able |= (1 << tid);
12836                }
12837                sdtr_speed >>= 4;
12838        }
12839
12840        /*
12841         * Set the host maximum queuing (max. 253, min. 16) and the per device
12842         * maximum queuing (max. 63, min. 4).
12843         */
12844        if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
12845                eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12846        } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
12847                /* If the value is zero, assume it is uninitialized. */
12848                if (eep_config.max_host_qng == 0) {
12849                        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
12850                } else {
12851                        eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
12852                }
12853        }
12854
12855        if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
12856                eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12857        } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
12858                /* If the value is zero, assume it is uninitialized. */
12859                if (eep_config.max_dvc_qng == 0) {
12860                        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
12861                } else {
12862                        eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
12863                }
12864        }
12865
12866        /*
12867         * If 'max_dvc_qng' is greater than 'max_host_qng', then
12868         * set 'max_dvc_qng' to 'max_host_qng'.
12869         */
12870        if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
12871                eep_config.max_dvc_qng = eep_config.max_host_qng;
12872        }
12873
12874        /*
12875         * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
12876         * values based on possibly adjusted EEPROM values.
12877         */
12878        asc_dvc->max_host_qng = eep_config.max_host_qng;
12879        asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
12880
12881        /*
12882         * If the EEPROM 'termination' field is set to automatic (0), then set
12883         * the ADV_DVC_CFG 'termination' field to automatic also.
12884         *
12885         * If the termination is specified with a non-zero 'termination'
12886         * value check that a legal value is set and set the ADV_DVC_CFG
12887         * 'termination' field appropriately.
12888         */
12889        if (eep_config.termination_se == 0) {
12890                termination = 0;        /* auto termination for SE */
12891        } else {
12892                /* Enable manual control with low off / high off. */
12893                if (eep_config.termination_se == 1) {
12894                        termination = 0;
12895
12896                        /* Enable manual control with low off / high on. */
12897                } else if (eep_config.termination_se == 2) {
12898                        termination = TERM_SE_HI;
12899
12900                        /* Enable manual control with low on / high on. */
12901                } else if (eep_config.termination_se == 3) {
12902                        termination = TERM_SE;
12903                } else {
12904                        /*
12905                         * The EEPROM 'termination_se' field contains a bad value.
12906                         * Use automatic termination instead.
12907                         */
12908                        termination = 0;
12909                        warn_code |= ASC_WARN_EEPROM_TERMINATION;
12910                }
12911        }
12912
12913        if (eep_config.termination_lvd == 0) {
12914                asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
12915        } else {
12916                /* Enable manual control with low off / high off. */
12917                if (eep_config.termination_lvd == 1) {
12918                        asc_dvc->cfg->termination = termination;
12919
12920                        /* Enable manual control with low off / high on. */
12921                } else if (eep_config.termination_lvd == 2) {
12922                        asc_dvc->cfg->termination = termination | TERM_LVD_HI;
12923
12924                        /* Enable manual control with low on / high on. */
12925                } else if (eep_config.termination_lvd == 3) {
12926                        asc_dvc->cfg->termination = termination | TERM_LVD;
12927                } else {
12928                        /*
12929                         * The EEPROM 'termination_lvd' field contains a bad value.
12930                         * Use automatic termination instead.
12931                         */
12932                        asc_dvc->cfg->termination = termination;
12933                        warn_code |= ASC_WARN_EEPROM_TERMINATION;
12934                }
12935        }
12936
12937        return warn_code;
12938}
12939
12940/*
12941 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
12942 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
12943 * all of this is done.
12944 *
12945 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
12946 *
12947 * For a non-fatal error return a warning code. If there are no warnings
12948 * then 0 is returned.
12949 *
12950 * Note: Chip is stopped on entry.
12951 */
12952static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
12953{
12954        AdvPortAddr iop_base;
12955        ushort warn_code;
12956        ADVEEP_38C1600_CONFIG eep_config;
12957        uchar tid, termination;
12958        ushort sdtr_speed = 0;
12959
12960        iop_base = asc_dvc->iop_base;
12961
12962        warn_code = 0;
12963
12964        /*
12965         * Read the board's EEPROM configuration.
12966         *
12967         * Set default values if a bad checksum is found.
12968         */
12969        if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
12970            eep_config.check_sum) {
12971                struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc);
12972                warn_code |= ASC_WARN_EEPROM_CHKSUM;
12973
12974                /*
12975                 * Set EEPROM default values.
12976                 */
12977                memcpy(&eep_config, &Default_38C1600_EEPROM_Config,
12978                        sizeof(ADVEEP_38C1600_CONFIG));
12979
12980                if (PCI_FUNC(pdev->devfn) != 0) {
12981                        u8 ints;
12982                        /*
12983                         * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60
12984                         * and old Mac system booting problem. The Expansion
12985                         * ROM must be disabled in Function 1 for these systems
12986                         */
12987                        eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE;
12988                        /*
12989                         * Clear the INTAB (bit 11) if the GPIO 0 input
12990                         * indicates the Function 1 interrupt line is wired
12991                         * to INTB.
12992                         *
12993                         * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
12994                         *   1 - Function 1 interrupt line wired to INT A.
12995                         *   0 - Function 1 interrupt line wired to INT B.
12996                         *
12997                         * Note: Function 0 is always wired to INTA.
12998                         * Put all 5 GPIO bits in input mode and then read
12999                         * their input values.
13000                         */
13001                        AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
13002                        ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA);
13003                        if ((ints & 0x01) == 0)
13004                                eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB;
13005                }
13006
13007                /*
13008                 * Assume the 6 byte board serial number that was read from
13009                 * EEPROM is correct even if the EEPROM checksum failed.
13010                 */
13011                eep_config.serial_number_word3 =
13012                        AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
13013                eep_config.serial_number_word2 =
13014                        AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
13015                eep_config.serial_number_word1 =
13016                        AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
13017
13018                AdvSet38C1600EEPConfig(iop_base, &eep_config);
13019        }
13020
13021        /*
13022         * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
13023         * EEPROM configuration that was read.
13024         *
13025         * This is the mapping of EEPROM fields to Adv Library fields.
13026         */
13027        asc_dvc->wdtr_able = eep_config.wdtr_able;
13028        asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
13029        asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
13030        asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
13031        asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
13032        asc_dvc->ppr_able = 0;
13033        asc_dvc->tagqng_able = eep_config.tagqng_able;
13034        asc_dvc->cfg->disc_enable = eep_config.disc_enable;
13035        asc_dvc->max_host_qng = eep_config.max_host_qng;
13036        asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13037        asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
13038        asc_dvc->start_motor = eep_config.start_motor;
13039        asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
13040        asc_dvc->bios_ctrl = eep_config.bios_ctrl;
13041        asc_dvc->no_scam = eep_config.scam_tolerant;
13042
13043        /*
13044         * For every Target ID if any of its 'sdtr_speed[1234]' bits
13045         * are set, then set an 'sdtr_able' bit for it.
13046         */
13047        asc_dvc->sdtr_able = 0;
13048        for (tid = 0; tid <= ASC_MAX_TID; tid++) {
13049                if (tid == 0) {
13050                        sdtr_speed = asc_dvc->sdtr_speed1;
13051                } else if (tid == 4) {
13052                        sdtr_speed = asc_dvc->sdtr_speed2;
13053                } else if (tid == 8) {
13054                        sdtr_speed = asc_dvc->sdtr_speed3;
13055                } else if (tid == 12) {
13056                        sdtr_speed = asc_dvc->sdtr_speed4;
13057                }
13058                if (sdtr_speed & ASC_MAX_TID) {
13059                        asc_dvc->sdtr_able |= (1 << tid);
13060                }
13061                sdtr_speed >>= 4;
13062        }
13063
13064        /*
13065         * Set the host maximum queuing (max. 253, min. 16) and the per device
13066         * maximum queuing (max. 63, min. 4).
13067         */
13068        if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
13069                eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13070        } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
13071                /* If the value is zero, assume it is uninitialized. */
13072                if (eep_config.max_host_qng == 0) {
13073                        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
13074                } else {
13075                        eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
13076                }
13077        }
13078
13079        if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
13080                eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13081        } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
13082                /* If the value is zero, assume it is uninitialized. */
13083                if (eep_config.max_dvc_qng == 0) {
13084                        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
13085                } else {
13086                        eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
13087                }
13088        }
13089
13090        /*
13091         * If 'max_dvc_qng' is greater than 'max_host_qng', then
13092         * set 'max_dvc_qng' to 'max_host_qng'.
13093         */
13094        if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
13095                eep_config.max_dvc_qng = eep_config.max_host_qng;
13096        }
13097
13098        /*
13099         * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
13100         * values based on possibly adjusted EEPROM values.
13101         */
13102        asc_dvc->max_host_qng = eep_config.max_host_qng;
13103        asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
13104
13105        /*
13106         * If the EEPROM 'termination' field is set to automatic (0), then set
13107         * the ASC_DVC_CFG 'termination' field to automatic also.
13108         *
13109         * If the termination is specified with a non-zero 'termination'
13110         * value check that a legal value is set and set the ASC_DVC_CFG
13111         * 'termination' field appropriately.
13112         */
13113        if (eep_config.termination_se == 0) {
13114                termination = 0;        /* auto termination for SE */
13115        } else {
13116                /* Enable manual control with low off / high off. */
13117                if (eep_config.termination_se == 1) {
13118                        termination = 0;
13119
13120                        /* Enable manual control with low off / high on. */
13121                } else if (eep_config.termination_se == 2) {
13122                        termination = TERM_SE_HI;
13123
13124                        /* Enable manual control with low on / high on. */
13125                } else if (eep_config.termination_se == 3) {
13126                        termination = TERM_SE;
13127                } else {
13128                        /*
13129                         * The EEPROM 'termination_se' field contains a bad value.
13130                         * Use automatic termination instead.
13131                         */
13132                        termination = 0;
13133                        warn_code |= ASC_WARN_EEPROM_TERMINATION;
13134                }
13135        }
13136
13137        if (eep_config.termination_lvd == 0) {
13138                asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
13139        } else {
13140                /* Enable manual control with low off / high off. */
13141                if (eep_config.termination_lvd == 1) {
13142                        asc_dvc->cfg->termination = termination;
13143
13144                        /* Enable manual control with low off / high on. */
13145                } else if (eep_config.termination_lvd == 2) {
13146                        asc_dvc->cfg->termination = termination | TERM_LVD_HI;
13147
13148                        /* Enable manual control with low on / high on. */
13149                } else if (eep_config.termination_lvd == 3) {
13150                        asc_dvc->cfg->termination = termination | TERM_LVD;
13151                } else {
13152                        /*
13153                         * The EEPROM 'termination_lvd' field contains a bad value.
13154                         * Use automatic termination instead.
13155                         */
13156                        asc_dvc->cfg->termination = termination;
13157                        warn_code |= ASC_WARN_EEPROM_TERMINATION;
13158                }
13159        }
13160
13161        return warn_code;
13162}
13163
13164/*
13165 * Initialize the ADV_DVC_VAR structure.
13166 *
13167 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13168 *
13169 * For a non-fatal error return a warning code. If there are no warnings
13170 * then 0 is returned.
13171 */
13172static int __devinit
13173AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost)
13174{
13175        struct asc_board *board = shost_priv(shost);
13176        ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var;
13177        unsigned short warn_code = 0;
13178        AdvPortAddr iop_base = asc_dvc->iop_base;
13179        u16 cmd;
13180        int status;
13181
13182        asc_dvc->err_code = 0;
13183
13184        /*
13185         * Save the state of the PCI Configuration Command Register
13186         * "Parity Error Response Control" Bit. If the bit is clear (0),
13187         * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13188         * DMA parity errors.
13189         */
13190        asc_dvc->cfg->control_flag = 0;
13191        pci_read_config_word(pdev, PCI_COMMAND, &cmd);
13192        if ((cmd & PCI_COMMAND_PARITY) == 0)
13193                asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13194
13195        asc_dvc->cfg->chip_version =
13196            AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13197
13198        ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n",
13199                 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13200                 (ushort)ADV_CHIP_ID_BYTE);
13201
13202        ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n",
13203                 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13204                 (ushort)ADV_CHIP_ID_WORD);
13205
13206        /*
13207         * Reset the chip to start and allow register writes.
13208         */
13209        if (AdvFindSignature(iop_base) == 0) {
13210                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13211                return ADV_ERROR;
13212        } else {
13213                /*
13214                 * The caller must set 'chip_type' to a valid setting.
13215                 */
13216                if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13217                    asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13218                    asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13219                        asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13220                        return ADV_ERROR;
13221                }
13222
13223                /*
13224                 * Reset Chip.
13225                 */
13226                AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13227                                     ADV_CTRL_REG_CMD_RESET);
13228                mdelay(100);
13229                AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13230                                     ADV_CTRL_REG_CMD_WR_IO_REG);
13231
13232                if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13233                        status = AdvInitFrom38C1600EEP(asc_dvc);
13234                } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13235                        status = AdvInitFrom38C0800EEP(asc_dvc);
13236                } else {
13237                        status = AdvInitFrom3550EEP(asc_dvc);
13238                }
13239                warn_code |= status;
13240        }
13241
13242        if (warn_code != 0)
13243                shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code);
13244
13245        if (asc_dvc->err_code)
13246                shost_printk(KERN_ERR, shost, "error code 0x%x\n",
13247                                asc_dvc->err_code);
13248
13249        return asc_dvc->err_code;
13250}
13251#endif
13252
13253static struct scsi_host_template advansys_template = {
13254        .proc_name = DRV_NAME,
13255#ifdef CONFIG_PROC_FS
13256        .proc_info = advansys_proc_info,
13257#endif
13258        .name = DRV_NAME,
13259        .info = advansys_info,
13260        .queuecommand = advansys_queuecommand,
13261        .eh_bus_reset_handler = advansys_reset,
13262        .bios_param = advansys_biosparam,
13263        .slave_configure = advansys_slave_configure,
13264        /*
13265         * Because the driver may control an ISA adapter 'unchecked_isa_dma'
13266         * must be set. The flag will be cleared in advansys_board_found
13267         * for non-ISA adapters.
13268         */
13269        .unchecked_isa_dma = 1,
13270        /*
13271         * All adapters controlled by this driver are capable of large
13272         * scatter-gather lists. According to the mid-level SCSI documentation
13273         * this obviates any performance gain provided by setting
13274         * 'use_clustering'. But empirically while CPU utilization is increased
13275         * by enabling clustering, I/O throughput increases as well.
13276         */
13277        .use_clustering = ENABLE_CLUSTERING,
13278};
13279
13280static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
13281{
13282        struct asc_board *board = shost_priv(shost);
13283        struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
13284        int req_cnt = 0;
13285        adv_req_t *reqp = NULL;
13286        int sg_cnt = 0;
13287        adv_sgblk_t *sgp;
13288        int warn_code, err_code;
13289
13290        /*
13291         * Allocate buffer carrier structures. The total size
13292         * is about 4 KB, so allocate all at once.
13293         */
13294        adv_dvc->carrier_buf = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
13295        ASC_DBG(1, "carrier_buf 0x%p\n", adv_dvc->carrier_buf);
13296
13297        if (!adv_dvc->carrier_buf)
13298                goto kmalloc_failed;
13299
13300        /*
13301         * Allocate up to 'max_host_qng' request structures for the Wide
13302         * board. The total size is about 16 KB, so allocate all at once.
13303         * If the allocation fails decrement and try again.
13304         */
13305        for (req_cnt = adv_dvc->max_host_qng; req_cnt > 0; req_cnt--) {
13306                reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
13307
13308                ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt,
13309                         (ulong)sizeof(adv_req_t) * req_cnt);
13310
13311                if (reqp)
13312                        break;
13313        }
13314
13315        if (!reqp)
13316                goto kmalloc_failed;
13317
13318        adv_dvc->orig_reqp = reqp;
13319
13320        /*
13321         * Allocate up to ADV_TOT_SG_BLOCK request structures for
13322         * the Wide board. Each structure is about 136 bytes.
13323         */
13324        board->adv_sgblkp = NULL;
13325        for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
13326                sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
13327
13328                if (!sgp)
13329                        break;
13330
13331                sgp->next_sgblkp = board->adv_sgblkp;
13332                board->adv_sgblkp = sgp;
13333
13334        }
13335
13336        ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", sg_cnt, sizeof(adv_sgblk_t),
13337                 sizeof(adv_sgblk_t) * sg_cnt);
13338
13339        if (!board->adv_sgblkp)
13340                goto kmalloc_failed;
13341
13342        /*
13343         * Point 'adv_reqp' to the request structures and
13344         * link them together.
13345         */
13346        req_cnt--;
13347        reqp[req_cnt].next_reqp = NULL;
13348        for (; req_cnt > 0; req_cnt--) {
13349                reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
13350        }
13351        board->adv_reqp = &reqp[0];
13352
13353        if (adv_dvc->chip_type == ADV_CHIP_ASC3550) {
13354                ASC_DBG(2, "AdvInitAsc3550Driver()\n");
13355                warn_code = AdvInitAsc3550Driver(adv_dvc);
13356        } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13357                ASC_DBG(2, "AdvInitAsc38C0800Driver()\n");
13358                warn_code = AdvInitAsc38C0800Driver(adv_dvc);
13359        } else {
13360                ASC_DBG(2, "AdvInitAsc38C1600Driver()\n");
13361                warn_code = AdvInitAsc38C1600Driver(adv_dvc);
13362        }
13363        err_code = adv_dvc->err_code;
13364
13365        if (warn_code || err_code) {
13366                shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error "
13367                        "0x%x\n", warn_code, err_code);
13368        }
13369
13370        goto exit;
13371
13372 kmalloc_failed:
13373        shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n");
13374        err_code = ADV_ERROR;
13375 exit:
13376        return err_code;
13377}
13378
13379static void advansys_wide_free_mem(struct asc_board *board)
13380{
13381        struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
13382        kfree(adv_dvc->carrier_buf);
13383        adv_dvc->carrier_buf = NULL;
13384        kfree(adv_dvc->orig_reqp);
13385        adv_dvc->orig_reqp = board->adv_reqp = NULL;
13386        while (board->adv_sgblkp) {
13387                adv_sgblk_t *sgp = board->adv_sgblkp;
13388                board->adv_sgblkp = sgp->next_sgblkp;
13389                kfree(sgp);
13390        }
13391}
13392
13393static int __devinit advansys_board_found(struct Scsi_Host *shost,
13394                                          unsigned int iop, int bus_type)
13395{
13396        struct pci_dev *pdev;
13397        struct asc_board *boardp = shost_priv(shost);
13398        ASC_DVC_VAR *asc_dvc_varp = NULL;
13399        ADV_DVC_VAR *adv_dvc_varp = NULL;
13400        int share_irq, warn_code, ret;
13401
13402        pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
13403
13404        if (ASC_NARROW_BOARD(boardp)) {
13405                ASC_DBG(1, "narrow board\n");
13406                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
13407                asc_dvc_varp->bus_type = bus_type;
13408                asc_dvc_varp->drv_ptr = boardp;
13409                asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
13410                asc_dvc_varp->iop_base = iop;
13411        } else {
13412#ifdef CONFIG_PCI
13413                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
13414                adv_dvc_varp->drv_ptr = boardp;
13415                adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
13416                if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
13417                        ASC_DBG(1, "wide board ASC-3550\n");
13418                        adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
13419                } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
13420                        ASC_DBG(1, "wide board ASC-38C0800\n");
13421                        adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
13422                } else {
13423                        ASC_DBG(1, "wide board ASC-38C1600\n");
13424                        adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
13425                }
13426
13427                boardp->asc_n_io_port = pci_resource_len(pdev, 1);
13428                boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
13429                                               boardp->asc_n_io_port);
13430                if (!boardp->ioremap_addr) {
13431                        shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) "
13432                                        "returned NULL\n",
13433                                        (long)pci_resource_start(pdev, 1),
13434                                        boardp->asc_n_io_port);
13435                        ret = -ENODEV;
13436                        goto err_shost;
13437                }
13438                adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr;
13439                ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base);
13440
13441                /*
13442                 * Even though it isn't used to access wide boards, other
13443                 * than for the debug line below, save I/O Port address so
13444                 * that it can be reported.
13445                 */
13446                boardp->ioport = iop;
13447
13448                ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
13449                                (ushort)inp(iop + 1), (ushort)inpw(iop));
13450#endif /* CONFIG_PCI */
13451        }
13452
13453#ifdef CONFIG_PROC_FS
13454        /*
13455         * Allocate buffer for printing information from
13456         * /proc/scsi/advansys/[0...].
13457         */
13458        boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
13459        if (!boardp->prtbuf) {
13460                shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n",
13461                                ASC_PRTBUF_SIZE);
13462                ret = -ENOMEM;
13463                goto err_unmap;
13464        }
13465#endif /* CONFIG_PROC_FS */
13466
13467        if (ASC_NARROW_BOARD(boardp)) {
13468                /*
13469                 * Set the board bus type and PCI IRQ before
13470                 * calling AscInitGetConfig().
13471                 */
13472                switch (asc_dvc_varp->bus_type) {
13473#ifdef CONFIG_ISA
13474                case ASC_IS_ISA:
13475                        shost->unchecked_isa_dma = TRUE;
13476                        share_irq = 0;
13477                        break;
13478                case ASC_IS_VL:
13479                        shost->unchecked_isa_dma = FALSE;
13480                        share_irq = 0;
13481                        break;
13482                case ASC_IS_EISA:
13483                        shost->unchecked_isa_dma = FALSE;
13484                        share_irq = IRQF_SHARED;
13485                        break;
13486#endif /* CONFIG_ISA */
13487#ifdef CONFIG_PCI
13488                case ASC_IS_PCI:
13489                        shost->unchecked_isa_dma = FALSE;
13490                        share_irq = IRQF_SHARED;
13491                        break;
13492#endif /* CONFIG_PCI */
13493                default:
13494                        shost_printk(KERN_ERR, shost, "unknown adapter type: "
13495                                        "%d\n", asc_dvc_varp->bus_type);
13496                        shost->unchecked_isa_dma = TRUE;
13497                        share_irq = 0;
13498                        break;
13499                }
13500
13501                /*
13502                 * NOTE: AscInitGetConfig() may change the board's
13503                 * bus_type value. The bus_type value should no
13504                 * longer be used. If the bus_type field must be
13505                 * referenced only use the bit-wise AND operator "&".
13506                 */
13507                ASC_DBG(2, "AscInitGetConfig()\n");
13508                ret = AscInitGetConfig(shost) ? -ENODEV : 0;
13509        } else {
13510#ifdef CONFIG_PCI
13511                /*
13512                 * For Wide boards set PCI information before calling
13513                 * AdvInitGetConfig().
13514                 */
13515                shost->unchecked_isa_dma = FALSE;
13516                share_irq = IRQF_SHARED;
13517                ASC_DBG(2, "AdvInitGetConfig()\n");
13518
13519                ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0;
13520#endif /* CONFIG_PCI */
13521        }
13522
13523        if (ret)
13524                goto err_free_proc;
13525
13526        /*
13527         * Save the EEPROM configuration so that it can be displayed
13528         * from /proc/scsi/advansys/[0...].
13529         */
13530        if (ASC_NARROW_BOARD(boardp)) {
13531
13532                ASCEEP_CONFIG *ep;
13533
13534                /*
13535                 * Set the adapter's target id bit in the 'init_tidmask' field.
13536                 */
13537                boardp->init_tidmask |=
13538                    ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
13539
13540                /*
13541                 * Save EEPROM settings for the board.
13542                 */
13543                ep = &boardp->eep_config.asc_eep;
13544
13545                ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
13546                ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
13547                ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
13548                ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
13549                ep->start_motor = asc_dvc_varp->start_motor;
13550                ep->cntl = asc_dvc_varp->dvc_cntl;
13551                ep->no_scam = asc_dvc_varp->no_scam;
13552                ep->max_total_qng = asc_dvc_varp->max_total_qng;
13553                ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
13554                /* 'max_tag_qng' is set to the same value for every device. */
13555                ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
13556                ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
13557                ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
13558                ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
13559                ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
13560                ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
13561                ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
13562
13563                /*
13564                 * Modify board configuration.
13565                 */
13566                ASC_DBG(2, "AscInitSetConfig()\n");
13567                ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0;
13568                if (ret)
13569                        goto err_free_proc;
13570        } else {
13571                ADVEEP_3550_CONFIG *ep_3550;
13572                ADVEEP_38C0800_CONFIG *ep_38C0800;
13573                ADVEEP_38C1600_CONFIG *ep_38C1600;
13574
13575                /*
13576                 * Save Wide EEP Configuration Information.
13577                 */
13578                if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
13579                        ep_3550 = &boardp->eep_config.adv_3550_eep;
13580
13581                        ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
13582                        ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
13583                        ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13584                        ep_3550->termination = adv_dvc_varp->cfg->termination;
13585                        ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
13586                        ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
13587                        ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
13588                        ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
13589                        ep_3550->ultra_able = adv_dvc_varp->ultra_able;
13590                        ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
13591                        ep_3550->start_motor = adv_dvc_varp->start_motor;
13592                        ep_3550->scsi_reset_delay =
13593                            adv_dvc_varp->scsi_reset_wait;
13594                        ep_3550->serial_number_word1 =
13595                            adv_dvc_varp->cfg->serial1;
13596                        ep_3550->serial_number_word2 =
13597                            adv_dvc_varp->cfg->serial2;
13598                        ep_3550->serial_number_word3 =
13599                            adv_dvc_varp->cfg->serial3;
13600                } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
13601                        ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
13602
13603                        ep_38C0800->adapter_scsi_id =
13604                            adv_dvc_varp->chip_scsi_id;
13605                        ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
13606                        ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13607                        ep_38C0800->termination_lvd =
13608                            adv_dvc_varp->cfg->termination;
13609                        ep_38C0800->disc_enable =
13610                            adv_dvc_varp->cfg->disc_enable;
13611                        ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
13612                        ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
13613                        ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13614                        ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13615                        ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13616                        ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13617                        ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13618                        ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
13619                        ep_38C0800->start_motor = adv_dvc_varp->start_motor;
13620                        ep_38C0800->scsi_reset_delay =
13621                            adv_dvc_varp->scsi_reset_wait;
13622                        ep_38C0800->serial_number_word1 =
13623                            adv_dvc_varp->cfg->serial1;
13624                        ep_38C0800->serial_number_word2 =
13625                            adv_dvc_varp->cfg->serial2;
13626                        ep_38C0800->serial_number_word3 =
13627                            adv_dvc_varp->cfg->serial3;
13628                } else {
13629                        ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
13630
13631                        ep_38C1600->adapter_scsi_id =
13632                            adv_dvc_varp->chip_scsi_id;
13633                        ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
13634                        ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
13635                        ep_38C1600->termination_lvd =
13636                            adv_dvc_varp->cfg->termination;
13637                        ep_38C1600->disc_enable =
13638                            adv_dvc_varp->cfg->disc_enable;
13639                        ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
13640                        ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
13641                        ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13642                        ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
13643                        ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
13644                        ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
13645                        ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
13646                        ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
13647                        ep_38C1600->start_motor = adv_dvc_varp->start_motor;
13648                        ep_38C1600->scsi_reset_delay =
13649                            adv_dvc_varp->scsi_reset_wait;
13650                        ep_38C1600->serial_number_word1 =
13651                            adv_dvc_varp->cfg->serial1;
13652                        ep_38C1600->serial_number_word2 =
13653                            adv_dvc_varp->cfg->serial2;
13654                        ep_38C1600->serial_number_word3 =
13655                            adv_dvc_varp->cfg->serial3;
13656                }
13657
13658                /*
13659                 * Set the adapter's target id bit in the 'init_tidmask' field.
13660                 */
13661                boardp->init_tidmask |=
13662                    ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
13663        }
13664
13665        /*
13666         * Channels are numbered beginning with 0. For AdvanSys one host
13667         * structure supports one channel. Multi-channel boards have a
13668         * separate host structure for each channel.
13669         */
13670        shost->max_channel = 0;
13671        if (ASC_NARROW_BOARD(boardp)) {
13672                shost->max_id = ASC_MAX_TID + 1;
13673                shost->max_lun = ASC_MAX_LUN + 1;
13674                shost->max_cmd_len = ASC_MAX_CDB_LEN;
13675
13676                shost->io_port = asc_dvc_varp->iop_base;
13677                boardp->asc_n_io_port = ASC_IOADR_GAP;
13678                shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
13679
13680                /* Set maximum number of queues the adapter can handle. */
13681                shost->can_queue = asc_dvc_varp->max_total_qng;
13682        } else {
13683                shost->max_id = ADV_MAX_TID + 1;
13684                shost->max_lun = ADV_MAX_LUN + 1;
13685                shost->max_cmd_len = ADV_MAX_CDB_LEN;
13686
13687                /*
13688                 * Save the I/O Port address and length even though
13689                 * I/O ports are not used to access Wide boards.
13690                 * Instead the Wide boards are accessed with
13691                 * PCI Memory Mapped I/O.
13692                 */
13693                shost->io_port = iop;
13694
13695                shost->this_id = adv_dvc_varp->chip_scsi_id;
13696
13697                /* Set maximum number of queues the adapter can handle. */
13698                shost->can_queue = adv_dvc_varp->max_host_qng;
13699        }
13700
13701        /*
13702         * Following v1.3.89, 'cmd_per_lun' is no longer needed
13703         * and should be set to zero.
13704         *
13705         * But because of a bug introduced in v1.3.89 if the driver is
13706         * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
13707         * SCSI function 'allocate_device' will panic. To allow the driver
13708         * to work as a module in these kernels set 'cmd_per_lun' to 1.
13709         *
13710         * Note: This is wrong.  cmd_per_lun should be set to the depth
13711         * you want on untagged devices always.
13712         #ifdef MODULE
13713         */
13714        shost->cmd_per_lun = 1;
13715/* #else
13716            shost->cmd_per_lun = 0;
13717#endif */
13718
13719        /*
13720         * Set the maximum number of scatter-gather elements the
13721         * adapter can handle.
13722         */
13723        if (ASC_NARROW_BOARD(boardp)) {
13724                /*
13725                 * Allow two commands with 'sg_tablesize' scatter-gather
13726                 * elements to be executed simultaneously. This value is
13727                 * the theoretical hardware limit. It may be decreased
13728                 * below.
13729                 */
13730                shost->sg_tablesize =
13731                    (((asc_dvc_varp->max_total_qng - 2) / 2) *
13732                     ASC_SG_LIST_PER_Q) + 1;
13733        } else {
13734                shost->sg_tablesize = ADV_MAX_SG_LIST;
13735        }
13736
13737        /*
13738         * The value of 'sg_tablesize' can not exceed the SCSI
13739         * mid-level driver definition of SG_ALL. SG_ALL also
13740         * must not be exceeded, because it is used to define the
13741         * size of the scatter-gather table in 'struct asc_sg_head'.
13742         */
13743        if (shost->sg_tablesize > SG_ALL) {
13744                shost->sg_tablesize = SG_ALL;
13745        }
13746
13747        ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize);
13748
13749        /* BIOS start address. */
13750        if (ASC_NARROW_BOARD(boardp)) {
13751                shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
13752                                                    asc_dvc_varp->bus_type);
13753        } else {
13754                /*
13755                 * Fill-in BIOS board variables. The Wide BIOS saves
13756                 * information in LRAM that is used by the driver.
13757                 */
13758                AdvReadWordLram(adv_dvc_varp->iop_base,
13759                                BIOS_SIGNATURE, boardp->bios_signature);
13760                AdvReadWordLram(adv_dvc_varp->iop_base,
13761                                BIOS_VERSION, boardp->bios_version);
13762                AdvReadWordLram(adv_dvc_varp->iop_base,
13763                                BIOS_CODESEG, boardp->bios_codeseg);
13764                AdvReadWordLram(adv_dvc_varp->iop_base,
13765                                BIOS_CODELEN, boardp->bios_codelen);
13766
13767                ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n",
13768                         boardp->bios_signature, boardp->bios_version);
13769
13770                ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n",
13771                         boardp->bios_codeseg, boardp->bios_codelen);
13772
13773                /*
13774                 * If the BIOS saved a valid signature, then fill in
13775                 * the BIOS code segment base address.
13776                 */
13777                if (boardp->bios_signature == 0x55AA) {
13778                        /*
13779                         * Convert x86 realmode code segment to a linear
13780                         * address by shifting left 4.
13781                         */
13782                        shost->base = ((ulong)boardp->bios_codeseg << 4);
13783                } else {
13784                        shost->base = 0;
13785                }
13786        }
13787
13788        /*
13789         * Register Board Resources - I/O Port, DMA, IRQ
13790         */
13791
13792        /* Register DMA Channel for Narrow boards. */
13793        shost->dma_channel = NO_ISA_DMA;        /* Default to no ISA DMA. */
13794#ifdef CONFIG_ISA
13795        if (ASC_NARROW_BOARD(boardp)) {
13796                /* Register DMA channel for ISA bus. */
13797                if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
13798                        shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
13799                        ret = request_dma(shost->dma_channel, DRV_NAME);
13800                        if (ret) {
13801                                shost_printk(KERN_ERR, shost, "request_dma() "
13802                                                "%d failed %d\n",
13803                                                shost->dma_channel, ret);
13804                                goto err_free_proc;
13805                        }
13806                        AscEnableIsaDma(shost->dma_channel);
13807                }
13808        }
13809#endif /* CONFIG_ISA */
13810
13811        /* Register IRQ Number. */
13812        ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost);
13813
13814        ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
13815                          DRV_NAME, shost);
13816
13817        if (ret) {
13818                if (ret == -EBUSY) {
13819                        shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13820                                        "already in use\n", boardp->irq);
13821                } else if (ret == -EINVAL) {
13822                        shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13823                                        "not valid\n", boardp->irq);
13824                } else {
13825                        shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x "
13826                                        "failed with %d\n", boardp->irq, ret);
13827                }
13828                goto err_free_dma;
13829        }
13830
13831        /*
13832         * Initialize board RISC chip and enable interrupts.
13833         */
13834        if (ASC_NARROW_BOARD(boardp)) {
13835                ASC_DBG(2, "AscInitAsc1000Driver()\n");
13836                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
13837
13838                if (warn_code || asc_dvc_varp->err_code) {
13839                        shost_printk(KERN_ERR, shost, "error: init_state 0x%x, "
13840                                        "warn 0x%x, error 0x%x\n",
13841                                        asc_dvc_varp->init_state, warn_code,
13842                                        asc_dvc_varp->err_code);
13843                        if (asc_dvc_varp->err_code)
13844                                ret = -ENODEV;
13845                }
13846        } else {
13847                if (advansys_wide_init_chip(shost))
13848                        ret = -ENODEV;
13849        }
13850
13851        if (ret)
13852                goto err_free_wide_mem;
13853
13854        ASC_DBG_PRT_SCSI_HOST(2, shost);
13855
13856        ret = scsi_add_host(shost, boardp->dev);
13857        if (ret)
13858                goto err_free_wide_mem;
13859
13860        scsi_scan_host(shost);
13861        return 0;
13862
13863 err_free_wide_mem:
13864        advansys_wide_free_mem(boardp);
13865        free_irq(boardp->irq, shost);
13866 err_free_dma:
13867        if (shost->dma_channel != NO_ISA_DMA)
13868                free_dma(shost->dma_channel);
13869 err_free_proc:
13870        kfree(boardp->prtbuf);
13871 err_unmap:
13872        if (boardp->ioremap_addr)
13873                iounmap(boardp->ioremap_addr);
13874 err_shost:
13875        return ret;
13876}
13877
13878/*
13879 * advansys_release()
13880 *
13881 * Release resources allocated for a single AdvanSys adapter.
13882 */
13883static int advansys_release(struct Scsi_Host *shost)
13884{
13885        struct asc_board *board = shost_priv(shost);
13886        ASC_DBG(1, "begin\n");
13887        scsi_remove_host(shost);
13888        free_irq(board->irq, shost);
13889        if (shost->dma_channel != NO_ISA_DMA) {
13890                ASC_DBG(1, "free_dma()\n");
13891                free_dma(shost->dma_channel);
13892        }
13893        if (ASC_NARROW_BOARD(board)) {
13894                dma_unmap_single(board->dev,
13895                                        board->dvc_var.asc_dvc_var.overrun_dma,
13896                                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
13897        } else {
13898                iounmap(board->ioremap_addr);
13899                advansys_wide_free_mem(board);
13900        }
13901        kfree(board->prtbuf);
13902        scsi_host_put(shost);
13903        ASC_DBG(1, "end\n");
13904        return 0;
13905}
13906
13907#define ASC_IOADR_TABLE_MAX_IX  11
13908
13909static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
13910        0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
13911        0x0210, 0x0230, 0x0250, 0x0330
13912};
13913
13914/*
13915 * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw.  It decodes as:
13916 * 00: 10
13917 * 01: 11
13918 * 10: 12
13919 * 11: 15
13920 */
13921static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
13922{
13923        unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
13924        unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
13925        if (chip_irq == 13)
13926                chip_irq = 15;
13927        return chip_irq;
13928}
13929
13930static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
13931{
13932        int err = -ENODEV;
13933        PortAddr iop_base = _asc_def_iop_base[id];
13934        struct Scsi_Host *shost;
13935        struct asc_board *board;
13936
13937        if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
13938                ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
13939                return -ENODEV;
13940        }
13941        ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
13942        if (!AscFindSignature(iop_base))
13943                goto release_region;
13944        if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
13945                goto release_region;
13946
13947        err = -ENOMEM;
13948        shost = scsi_host_alloc(&advansys_template, sizeof(*board));
13949        if (!shost)
13950                goto release_region;
13951
13952        board = shost_priv(shost);
13953        board->irq = advansys_isa_irq_no(iop_base);
13954        board->dev = dev;
13955
13956        err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
13957        if (err)
13958                goto free_host;
13959
13960        dev_set_drvdata(dev, shost);
13961        return 0;
13962
13963 free_host:
13964        scsi_host_put(shost);
13965 release_region:
13966        release_region(iop_base, ASC_IOADR_GAP);
13967        return err;
13968}
13969
13970static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
13971{
13972        int ioport = _asc_def_iop_base[id];
13973        advansys_release(dev_get_drvdata(dev));
13974        release_region(ioport, ASC_IOADR_GAP);
13975        return 0;
13976}
13977
13978static struct isa_driver advansys_isa_driver = {
13979        .probe          = advansys_isa_probe,
13980        .remove         = __devexit_p(advansys_isa_remove),
13981        .driver = {
13982                .owner  = THIS_MODULE,
13983                .name   = DRV_NAME,
13984        },
13985};
13986
13987/*
13988 * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw.  It decodes as:
13989 * 000: invalid
13990 * 001: 10
13991 * 010: 11
13992 * 011: 12
13993 * 100: invalid
13994 * 101: 14
13995 * 110: 15
13996 * 111: invalid
13997 */
13998static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
13999{
14000        unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
14001        unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
14002        if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
14003                return 0;
14004        return chip_irq;
14005}
14006
14007static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
14008{
14009        int err = -ENODEV;
14010        PortAddr iop_base = _asc_def_iop_base[id];
14011        struct Scsi_Host *shost;
14012        struct asc_board *board;
14013
14014        if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
14015                ASC_DBG(1, "I/O port 0x%x busy\n", iop_base);
14016                return -ENODEV;
14017        }
14018        ASC_DBG(1, "probing I/O port 0x%x\n", iop_base);
14019        if (!AscFindSignature(iop_base))
14020                goto release_region;
14021        /*
14022         * I don't think this condition can actually happen, but the old
14023         * driver did it, and the chances of finding a VLB setup in 2007
14024         * to do testing with is slight to none.
14025         */
14026        if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
14027                goto release_region;
14028
14029        err = -ENOMEM;
14030        shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14031        if (!shost)
14032                goto release_region;
14033
14034        board = shost_priv(shost);
14035        board->irq = advansys_vlb_irq_no(iop_base);
14036        board->dev = dev;
14037
14038        err = advansys_board_found(shost, iop_base, ASC_IS_VL);
14039        if (err)
14040                goto free_host;
14041
14042        dev_set_drvdata(dev, shost);
14043        return 0;
14044
14045 free_host:
14046        scsi_host_put(shost);
14047 release_region:
14048        release_region(iop_base, ASC_IOADR_GAP);
14049        return -ENODEV;
14050}
14051
14052static struct isa_driver advansys_vlb_driver = {
14053        .probe          = advansys_vlb_probe,
14054        .remove         = __devexit_p(advansys_isa_remove),
14055        .driver = {
14056                .owner  = THIS_MODULE,
14057                .name   = "advansys_vlb",
14058        },
14059};
14060
14061static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
14062        { "ABP7401" },
14063        { "ABP7501" },
14064        { "" }
14065};
14066
14067MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
14068
14069/*
14070 * EISA is a little more tricky than PCI; each EISA device may have two
14071 * channels, and this driver is written to make each channel its own Scsi_Host
14072 */
14073struct eisa_scsi_data {
14074        struct Scsi_Host *host[2];
14075};
14076
14077/*
14078 * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw.  It decodes as:
14079 * 000: 10
14080 * 001: 11
14081 * 010: 12
14082 * 011: invalid
14083 * 100: 14
14084 * 101: 15
14085 * 110: invalid
14086 * 111: invalid
14087 */
14088static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
14089{
14090        unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
14091        unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
14092        if ((chip_irq == 13) || (chip_irq > 15))
14093                return 0;
14094        return chip_irq;
14095}
14096
14097static int __devinit advansys_eisa_probe(struct device *dev)
14098{
14099        int i, ioport, irq = 0;
14100        int err;
14101        struct eisa_device *edev = to_eisa_device(dev);
14102        struct eisa_scsi_data *data;
14103
14104        err = -ENOMEM;
14105        data = kzalloc(sizeof(*data), GFP_KERNEL);
14106        if (!data)
14107                goto fail;
14108        ioport = edev->base_addr + 0xc30;
14109
14110        err = -ENODEV;
14111        for (i = 0; i < 2; i++, ioport += 0x20) {
14112                struct asc_board *board;
14113                struct Scsi_Host *shost;
14114                if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
14115                        printk(KERN_WARNING "Region %x-%x busy\n", ioport,
14116                               ioport + ASC_IOADR_GAP - 1);
14117                        continue;
14118                }
14119                if (!AscFindSignature(ioport)) {
14120                        release_region(ioport, ASC_IOADR_GAP);
14121                        continue;
14122                }
14123
14124                /*
14125                 * I don't know why we need to do this for EISA chips, but
14126                 * not for any others.  It looks to be equivalent to
14127                 * AscGetChipCfgMsw, but I may have overlooked something,
14128                 * so I'm not converting it until I get an EISA board to
14129                 * test with.
14130                 */
14131                inw(ioport + 4);
14132
14133                if (!irq)
14134                        irq = advansys_eisa_irq_no(edev);
14135
14136                err = -ENOMEM;
14137                shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14138                if (!shost)
14139                        goto release_region;
14140
14141                board = shost_priv(shost);
14142                board->irq = irq;
14143                board->dev = dev;
14144
14145                err = advansys_board_found(shost, ioport, ASC_IS_EISA);
14146                if (!err) {
14147                        data->host[i] = shost;
14148                        continue;
14149                }
14150
14151                scsi_host_put(shost);
14152 release_region:
14153                release_region(ioport, ASC_IOADR_GAP);
14154                break;
14155        }
14156
14157        if (err)
14158                goto free_data;
14159        dev_set_drvdata(dev, data);
14160        return 0;
14161
14162 free_data:
14163        kfree(data->host[0]);
14164        kfree(data->host[1]);
14165        kfree(data);
14166 fail:
14167        return err;
14168}
14169
14170static __devexit int advansys_eisa_remove(struct device *dev)
14171{
14172        int i;
14173        struct eisa_scsi_data *data = dev_get_drvdata(dev);
14174
14175        for (i = 0; i < 2; i++) {
14176                int ioport;
14177                struct Scsi_Host *shost = data->host[i];
14178                if (!shost)
14179                        continue;
14180                ioport = shost->io_port;
14181                advansys_release(shost);
14182                release_region(ioport, ASC_IOADR_GAP);
14183        }
14184
14185        kfree(data);
14186        return 0;
14187}
14188
14189static struct eisa_driver advansys_eisa_driver = {
14190        .id_table =             advansys_eisa_table,
14191        .driver = {
14192                .name =         DRV_NAME,
14193                .probe =        advansys_eisa_probe,
14194                .remove =       __devexit_p(advansys_eisa_remove),
14195        }
14196};
14197
14198/* PCI Devices supported by this driver */
14199static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
14200        {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
14201         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14202        {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
14203         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14204        {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
14205         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14206        {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
14207         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14208        {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
14209         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14210        {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
14211         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
14212        {}
14213};
14214
14215MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
14216
14217static void __devinit advansys_set_latency(struct pci_dev *pdev)
14218{
14219        if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
14220            (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
14221                pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
14222        } else {
14223                u8 latency;
14224                pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
14225                if (latency < 0x20)
14226                        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
14227        }
14228}
14229
14230static int __devinit
14231advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14232{
14233        int err, ioport;
14234        struct Scsi_Host *shost;
14235        struct asc_board *board;
14236
14237        err = pci_enable_device(pdev);
14238        if (err)
14239                goto fail;
14240        err = pci_request_regions(pdev, DRV_NAME);
14241        if (err)
14242                goto disable_device;
14243        pci_set_master(pdev);
14244        advansys_set_latency(pdev);
14245
14246        err = -ENODEV;
14247        if (pci_resource_len(pdev, 0) == 0)
14248                goto release_region;
14249
14250        ioport = pci_resource_start(pdev, 0);
14251
14252        err = -ENOMEM;
14253        shost = scsi_host_alloc(&advansys_template, sizeof(*board));
14254        if (!shost)
14255                goto release_region;
14256
14257        board = shost_priv(shost);
14258        board->irq = pdev->irq;
14259        board->dev = &pdev->dev;
14260
14261        if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
14262            pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
14263            pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
14264                board->flags |= ASC_IS_WIDE_BOARD;
14265        }
14266
14267        err = advansys_board_found(shost, ioport, ASC_IS_PCI);
14268        if (err)
14269                goto free_host;
14270
14271        pci_set_drvdata(pdev, shost);
14272        return 0;
14273
14274 free_host:
14275        scsi_host_put(shost);
14276 release_region:
14277        pci_release_regions(pdev);
14278 disable_device:
14279        pci_disable_device(pdev);
14280 fail:
14281        return err;
14282}
14283
14284static void __devexit advansys_pci_remove(struct pci_dev *pdev)
14285{
14286        advansys_release(pci_get_drvdata(pdev));
14287        pci_release_regions(pdev);
14288        pci_disable_device(pdev);
14289}
14290
14291static struct pci_driver advansys_pci_driver = {
14292        .name =         DRV_NAME,
14293        .id_table =     advansys_pci_tbl,
14294        .probe =        advansys_pci_probe,
14295        .remove =       __devexit_p(advansys_pci_remove),
14296};
14297
14298static int __init advansys_init(void)
14299{
14300        int error;
14301
14302        error = isa_register_driver(&advansys_isa_driver,
14303                                    ASC_IOADR_TABLE_MAX_IX);
14304        if (error)
14305                goto fail;
14306
14307        error = isa_register_driver(&advansys_vlb_driver,
14308                                    ASC_IOADR_TABLE_MAX_IX);
14309        if (error)
14310                goto unregister_isa;
14311
14312        error = eisa_driver_register(&advansys_eisa_driver);
14313        if (error)
14314                goto unregister_vlb;
14315
14316        error = pci_register_driver(&advansys_pci_driver);
14317        if (error)
14318                goto unregister_eisa;
14319
14320        return 0;
14321
14322 unregister_eisa:
14323        eisa_driver_unregister(&advansys_eisa_driver);
14324 unregister_vlb:
14325        isa_unregister_driver(&advansys_vlb_driver);
14326 unregister_isa:
14327        isa_unregister_driver(&advansys_isa_driver);
14328 fail:
14329        return error;
14330}
14331
14332static void __exit advansys_exit(void)
14333{
14334        pci_unregister_driver(&advansys_pci_driver);
14335        eisa_driver_unregister(&advansys_eisa_driver);
14336        isa_unregister_driver(&advansys_vlb_driver);
14337        isa_unregister_driver(&advansys_isa_driver);
14338}
14339
14340module_init(advansys_init);
14341module_exit(advansys_exit);
14342
14343MODULE_LICENSE("GPL");
14344