]> err.no Git - linux-2.6/blobdiff - drivers/scsi/advansys.c
[SCSI] advansys: Move struct device out of the cfg structures
[linux-2.6] / drivers / scsi / advansys.c
index 8ace30ed4186fcf302cd00417f56714532e7f205..73d974a15fcae7c9102ed4c79b91687fd374c5d7 100644 (file)
 
         AdvanSys SCSI adapter files have the following path name format:
 
-           /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
+           /proc/scsi/advansys/{0,1,2,3,...}
 
         This information can be displayed with cat. For example:
 
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
+#include <linux/isa.h>
+#include <linux/eisa.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 
-/* FIXME: (by jejb@steeleye.com) This warning is present for two
- * reasons:
+/* FIXME: (by jejb@steeleye.com)
  *
- * 1) This driver badly needs converting to the correct driver model
- *    probing API
- *
- * 2) Although all of the necessary command mapping places have the
+ * Although all of the necessary command mapping places have the
  * appropriate dma_map.. APIs, the driver still processes its internal
  * queue using bus_to_virt() and virt_to_bus() which are illegal under
  * the API.  The entire queue processing structure will need to be
@@ -856,21 +854,8 @@ typedef unsigned char uchar;
 #define ERR      (-1)
 #define UW_ERR   (uint)(0xFFFF)
 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
-#define AscPCIConfigVendorIDRegister      0x0000
-#define AscPCIConfigDeviceIDRegister      0x0002
-#define AscPCIConfigCommandRegister       0x0004
-#define AscPCIConfigStatusRegister        0x0006
-#define AscPCIConfigRevisionIDRegister    0x0008
-#define AscPCIConfigCacheSize             0x000C
-#define AscPCIConfigLatencyTimer          0x000D
-#define AscPCIIOBaseRegister              0x0010
-#define AscPCICmdRegBits_IOMemBusMaster   0x0007
-#define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
-#define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
 #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
-#define ASC_PCI_REVISION_3150             0x02
-#define ASC_PCI_REVISION_3050             0x03
 
 #define  ASC_DVCLIB_CALL_DONE     (1)
 #define  ASC_DVCLIB_CALL_FAILED   (0)
@@ -959,10 +944,6 @@ typedef unsigned char uchar;
 #define ASC_MAX_CDB_LEN     12
 #define ASC_SCSI_RESET_HOLD_TIME_US  60
 
-#define ADV_INQ_CLOCKING_ST_ONLY    0x0
-#define ADV_INQ_CLOCKING_DT_ONLY    0x1
-#define ADV_INQ_CLOCKING_ST_AND_DT  0x3
-
 /*
  * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
  * and CmdDt (Command Support Data) field bit definitions.
@@ -981,57 +962,8 @@ typedef unsigned char uchar;
 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
-#define MS_CMD_DONE    0x00
-#define MS_EXTEND      0x01
 #define MS_SDTR_LEN    0x03
-#define MS_SDTR_CODE   0x01
 #define MS_WDTR_LEN    0x02
-#define MS_WDTR_CODE   0x03
-#define MS_MDP_LEN    0x05
-#define MS_MDP_CODE   0x00
-
-/*
- * Inquiry data structure and bitfield macros
- *
- * Only quantities of more than 1 bit are shifted, since the others are
- * just tested for true or false. C bitfields aren't portable between big
- * and little-endian platforms so they are not used.
- */
-
-#define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
-#define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
-#define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
-#define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
-#define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
-#define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
-#define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
-#define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
-#define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
-#define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
-#define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
-#define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
-#define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
-#define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
-#define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
-#define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
-#define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
-#define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
-#define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
-#define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
-
-typedef struct {
-       uchar periph;
-       uchar devtype;
-       uchar ver;
-       uchar byte3;
-       uchar add_len;
-       uchar res1;
-       uchar res2;
-       uchar flags;
-       uchar vendor_id[8];
-       uchar product_id[16];
-       uchar product_rev_level[4];
-} ASC_SCSI_INQUIRY;
 
 #define ASC_SG_LIST_PER_Q   7
 #define QS_FREE        0x00
@@ -1369,18 +1301,6 @@ typedef struct asc_risc_sg_list_q {
 #define ASC_MAX_INRAM_TAG_QNG   16
 #define ASC_IOADR_TABLE_MAX_IX  11
 #define ASC_IOADR_GAP   0x10
-#define ASC_SEARCH_IOP_GAP 0x10
-#define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
-#define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
-#define ASC_IOADR_1     (PortAddr)0x0110
-#define ASC_IOADR_2     (PortAddr)0x0130
-#define ASC_IOADR_3     (PortAddr)0x0150
-#define ASC_IOADR_4     (PortAddr)0x0190
-#define ASC_IOADR_5     (PortAddr)0x0210
-#define ASC_IOADR_6     (PortAddr)0x0230
-#define ASC_IOADR_7     (PortAddr)0x0250
-#define ASC_IOADR_8     (PortAddr)0x0330
-#define ASC_IOADR_DEF   ASC_IOADR_8
 #define ASC_LIB_SCSIQ_WK_SP        256
 #define ASC_MAX_SYN_XFER_NO        16
 #define ASC_SYN_MAX_OFFSET         0x0F
@@ -1460,7 +1380,6 @@ typedef struct asc_dvc_cfg {
        uchar sdtr_period_offset[ASC_MAX_TID + 1];
        ushort pci_slot_info;
        uchar adapter_info[6];
-       struct device *dev;
 } ASC_DVC_CFG;
 
 #define ASC_DEF_DVC_CNTL       0xFFFF
@@ -1791,16 +1710,10 @@ typedef struct asceep_config {
 #define ASC_1000_ID0W      0x04C1
 #define ASC_1000_ID0W_FIX  0x00C1
 #define ASC_1000_ID1B      0x25
-#define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
-#define ASC_EISA_SMALL_IOP_GAP (0x0020)
-#define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
-#define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
-#define ASC_EISA_ID_740    0x01745004UL
-#define ASC_EISA_ID_750    0x01755004UL
 #define INS_HALTINT        (ushort)0x6281
 #define INS_HALT           (ushort)0x6280
 #define INS_SINT           (ushort)0x6200
@@ -1901,9 +1814,6 @@ static void AscEnableInterrupt(PortAddr);
 static void AscSetBank(PortAddr, uchar);
 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
 #ifdef CONFIG_ISA
-static ushort AscGetIsaDmaChannel(PortAddr);
-static ushort AscSetIsaDmaChannel(PortAddr, ushort);
-static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
 static uchar AscGetIsaDmaSpeed(PortAddr);
 #endif /* CONFIG_ISA */
 static uchar AscReadLramByte(PortAddr, ushort);
@@ -1920,7 +1830,6 @@ static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
 static ushort AscInitFromEEP(ASC_DVC_VAR *);
-static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
 static int AscTestExternalLram(ASC_DVC_VAR *);
 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
@@ -1944,42 +1853,21 @@ static int AscIsrChipHalted(ASC_DVC_VAR *);
 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
                                   ASC_QDONE_INFO *, ASC_DCNT);
 static int AscIsrQDone(ASC_DVC_VAR *);
-static int AscCompareString(uchar *, uchar *, int);
 #ifdef CONFIG_ISA
 static ushort AscGetEisaChipCfg(PortAddr);
-static ASC_DCNT AscGetEisaProductID(PortAddr);
-static PortAddr AscSearchIOPortAddrEISA(PortAddr);
-static PortAddr AscSearchIOPortAddr11(PortAddr);
-static PortAddr AscSearchIOPortAddr(PortAddr, ushort);
-static void AscSetISAPNPWaitForKey(void);
 #endif /* CONFIG_ISA */
 static uchar AscGetChipScsiCtrl(PortAddr);
-static uchar AscSetChipScsiID(PortAddr, uchar);
 static uchar AscGetChipVersion(PortAddr, ushort);
-static ushort AscGetChipBusType(PortAddr);
 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
-static int AscFindSignature(PortAddr);
 static void AscToggleIRQAct(PortAddr);
-static uchar AscGetChipIRQ(PortAddr, ushort);
-static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
-static ushort AscGetChipBiosAddress(PortAddr, ushort);
 static inline ulong DvcEnterCritical(void);
 static inline void DvcLeaveCritical(ulong);
-#ifdef CONFIG_PCI
-static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
-static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
-#endif /* CONFIG_PCI */
-static ushort AscGetChipBiosAddress(PortAddr, ushort);
 static void DvcSleepMilliSecond(ASC_DCNT);
 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
-static ushort AscInitGetConfig(ASC_DVC_VAR *);
-static ushort AscInitSetConfig(ASC_DVC_VAR *);
 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
-static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
-static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
-static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
+static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
 static int AscISR(ASC_DVC_VAR *);
 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
@@ -1987,7 +1875,6 @@ static int AscSgListToQueue(int);
 #ifdef CONFIG_ISA
 static void AscEnableIsaDma(uchar);
 #endif /* CONFIG_ISA */
-static ASC_DCNT AscGetMaxDmaCount(ushort);
 static const char *advansys_info(struct Scsi_Host *shost);
 
 /*
@@ -2400,10 +2287,8 @@ typedef struct adveep_38C1600_config {
 #define BIOS_CTRL_AIPP_DIS           0x2000
 
 #define ADV_3550_MEMSIZE   0x2000      /* 8 KB Internal Memory */
-#define ADV_3550_IOLEN     0x40        /* I/O Port Range in bytes */
 
 #define ADV_38C0800_MEMSIZE  0x4000    /* 16 KB Internal Memory */
-#define ADV_38C0800_IOLEN    0x100     /* I/O Port Range in bytes */
 
 /*
  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
@@ -2413,8 +2298,6 @@ typedef struct adveep_38C1600_config {
  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
  */
 #define ADV_38C1600_MEMSIZE  0x4000    /* 16 KB Internal Memory */
-#define ADV_38C1600_IOLEN    0x100     /* I/O Port Range 256 bytes */
-#define ADV_38C1600_MEMLEN   0x1000    /* Memory Range 4KB bytes */
 
 /*
  * Byte I/O register address from base of 'iop_base'.
@@ -2942,7 +2825,6 @@ typedef struct adv_dvc_cfg {
        ushort serial1;         /* EEPROM serial number word 1 */
        ushort serial2;         /* EEPROM serial number word 2 */
        ushort serial3;         /* EEPROM serial number word 3 */
-       struct device *dev;     /* pointer to the pci dev structure for this board */
 } ADV_DVC_CFG;
 
 struct adv_dvc_var;
@@ -3106,8 +2988,6 @@ typedef struct adv_scsi_req_q {
 static inline ulong DvcEnterCritical(void);
 static inline void DvcLeaveCritical(ulong);
 static void DvcSleepMilliSecond(ADV_DCNT);
-static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
-static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
                               uchar *, ASC_SDCNT *, int);
 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
@@ -3117,7 +2997,6 @@ static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
  */
 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
 static int AdvISR(ADV_DVC_VAR *);
-static int AdvInitGetConfig(ADV_DVC_VAR *);
 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
@@ -3128,7 +3007,6 @@ static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
  * Internal Adv Library functions.
  */
 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
-static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
@@ -3141,12 +3019,6 @@ static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
 static void AdvWaitEEPCmd(AdvPortAddr);
 static ushort AdvReadEEPWord(AdvPortAddr, int);
 
-/*
- * PCI Bus Definitions
- */
-#define AscPCICmdRegBits_BusMastering     0x0007
-#define AscPCICmdRegBits_ParErrRespCtrl   0x0040
-
 /* Read byte from a register. */
 #define AdvReadByteRegister(iop_base, reg_off) \
      (ADV_MEM_READB((iop_base) + (reg_off)))
@@ -3348,82 +3220,10 @@ static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
          (sizeof(ADV_SG_BLOCK) * \
           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
 
-/*
- * Inquiry data structure and bitfield macros
- *
- * Using bitfields to access the subchar data isn't portable across
- * endianness, so instead mask and shift. Only quantities of more
- * than 1 bit are shifted, since the others are just tested for true
- * or false.
- */
-
-#define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
-#define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
-#define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
-#define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
-#define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
-#define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
-#define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
-#define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
-#define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
-#define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
-#define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
-#define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
-#define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
-#define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
-#define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
-#define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
-#define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
-#define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
-#define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
-#define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
-
-typedef struct {
-       uchar periph;           /* peripheral device type [0:4] */
-       /* peripheral qualifier [5:7] */
-       uchar devtype;          /* device type modifier (for SCSI I) [0:6] */
-       /* RMB - removable medium bit [7] */
-       uchar ver;              /* ANSI approved version [0:2] */
-       /* ECMA version [3:5] */
-       /* ISO version [6:7] */
-       uchar byte3;            /* response data format [0:3] */
-       /* 0 SCSI 1 */
-       /* 1 CCS */
-       /* 2 SCSI-2 */
-       /* 3-F reserved */
-       /* reserved [4:5] */
-       /* terminate I/O process bit (see 5.6.22) [6] */
-       /* asynch. event notification (processor) [7] */
-       uchar add_len;          /* additional length */
-       uchar res1;             /* reserved */
-       uchar res2;             /* reserved */
-       uchar flags;            /* soft reset implemented [0] */
-       /* command queuing [1] */
-       /* reserved [2] */
-       /* linked command for this logical unit [3] */
-       /* synchronous data transfer [4] */
-       /* wide bus 16 bit data transfer [5] */
-       /* wide bus 32 bit data transfer [6] */
-       /* relative addressing mode [7] */
-       uchar vendor_id[8];     /* vendor identification */
-       uchar product_id[16];   /* product identification */
-       uchar product_rev_level[4];     /* product revision level */
-       uchar vendor_specific[20];      /* vendor specific */
-       uchar info;             /* information unit supported [0] */
-       /* quick arbitrate supported [1] */
-       /* clocking field [2:3] */
-       /* reserved [4:7] */
-       uchar res3;             /* reserved */
-} ADV_SCSI_INQUIRY;            /* 58 bytes */
-
 /*
  * --- Driver Constants and Macros
  */
 
-#define ASC_NUM_BOARD_SUPPORTED 16
-#define ASC_NUM_IOPORT_PROBE    4
-#define ASC_NUM_BUS             4
-
 /* Reference Scsi_Host hostdata */
 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
 
@@ -3526,11 +3326,6 @@ typedef struct scsi_cmnd REQ, *REQP;
 /* Return non-zero, if the queue is empty. */
 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
 
-#define PCI_MAX_SLOT            0x1F
-#define PCI_MAX_BUS             0xFF
-#define PCI_IOADDRESS_MASK      0xFFFE
-#define ASC_PCI_DEVICE_ID_CNT   6      /* PCI Device ID count. */
-
 #ifndef ADVANSYS_STATS
 #define ASC_STATS(shost, counter)
 #define ASC_STATS_ADD(shost, counter, count)
@@ -3793,11 +3588,12 @@ typedef struct adv_req {
 /*
  * Structure allocated for each board.
  *
- * This structure is allocated by scsi_register() at the end
+ * This structure is allocated by scsi_host_alloc() at the end
  * of the 'Scsi_Host' structure starting at the 'hostdata'
  * field. It is guaranteed to be allocated from DMA-able memory.
  */
 typedef struct asc_board {
+       struct device *dev;
        int id;                 /* Board Id */
        uint flags;             /* Board flags */
        union {
@@ -3825,27 +3621,21 @@ typedef struct asc_board {
        } eep_config;
        ulong last_reset;       /* Saved last reset time */
        spinlock_t lock;        /* Board spinlock */
-#ifdef CONFIG_PROC_FS
        /* /proc/scsi/advansys/[0...] */
        char *prtbuf;           /* /proc print buffer */
-#endif                         /* CONFIG_PROC_FS */
 #ifdef ADVANSYS_STATS
        struct asc_stats asc_stats;     /* Board statistics */
 #endif                         /* ADVANSYS_STATS */
        /*
         * The following fields are used only for Narrow Boards.
         */
-       /* The following three structures must be in DMA-able memory. */
-       ASC_SCSI_REQ_Q scsireqq;
-       ASC_CAP_INFO cap_info;
-       ASC_SCSI_INQUIRY inquiry;
        uchar sdtr_data[ASC_MAX_TID + 1];       /* SDTR information */
        /*
         * The following fields are used only for Wide Boards.
         */
        void __iomem *ioremap_addr;     /* I/O Memory remap address. */
        ushort ioport;          /* I/O Port address. */
-       ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */
+       ADV_CARR_T *carrp;      /* ADV_CARR_T memory block. */
        adv_req_t *orig_reqp;   /* adv_req_t memory block. */
        adv_req_t *adv_reqp;    /* Request structures. */
        adv_sgblk_t *adv_sgblkp;        /* Scatter-gather structures. */
@@ -3855,61 +3645,8 @@ typedef struct asc_board {
        ushort bios_codelen;    /* BIOS Code Segment Length. */
 } asc_board_t;
 
-/*
- * PCI configuration structures
- */
-typedef struct _PCI_DATA_ {
-       uchar type;
-       uchar bus;
-       uchar slot;
-       uchar func;
-       uchar offset;
-} PCI_DATA;
-
-typedef struct _PCI_DEVICE_ {
-       ushort vendorID;
-       ushort deviceID;
-       ushort slotNumber;
-       ushort slotFound;
-       uchar busNumber;
-       uchar maxBusNumber;
-       uchar devFunc;
-       ushort startSlot;
-       ushort endSlot;
-       uchar bridge;
-       uchar type;
-} PCI_DEVICE;
-
-typedef struct _PCI_CONFIG_SPACE_ {
-       ushort vendorID;
-       ushort deviceID;
-       ushort command;
-       ushort status;
-       uchar revision;
-       uchar classCode[3];
-       uchar cacheSize;
-       uchar latencyTimer;
-       uchar headerType;
-       uchar bist;
-       ADV_PADDR baseAddress[6];
-       ushort reserved[4];
-       ADV_PADDR optionRomAddr;
-       ushort reserved2[4];
-       uchar irqLine;
-       uchar irqPin;
-       uchar minGnt;
-       uchar maxLatency;
-} PCI_CONFIG_SPACE;
-
-/*
- * --- Driver Data
- */
-
-/* Note: All driver global data should be initialized. */
-
 /* Number of boards detected in system. */
-static int asc_board_count = 0;
-static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
+static int asc_board_count;
 
 /* Overrun buffer used by all narrow boards. */
 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
@@ -3920,38 +3657,14 @@ static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
 static ASC_SCSI_Q asc_scsi_q = { {0} };
 static ASC_SG_HEAD asc_sg_head = { 0 };
 
-/* List of supported bus types. */
-static ushort asc_bus[ASC_NUM_BUS] __initdata = {
-       ASC_IS_ISA,
-       ASC_IS_VL,
-       ASC_IS_EISA,
-       ASC_IS_PCI,
-};
-
-static int asc_iopflag = ASC_FALSE;
-static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
-
 #ifdef ADVANSYS_DEBUG
-static char *asc_bus_name[ASC_NUM_BUS] = {
-       "ASC_IS_ISA",
-       "ASC_IS_VL",
-       "ASC_IS_EISA",
-       "ASC_IS_PCI",
-};
-
 static int asc_dbglvl = 3;
 #endif /* ADVANSYS_DEBUG */
 
-/* Declaration for Asc Library internal data referenced by driver. */
-static PortAddr _asc_def_iop_base[];
-
 /*
  * --- Driver Function Prototypes
- *
- * advansys.h contains function prototypes for functions global to Linux.
  */
 
-static irqreturn_t advansys_interrupt(int, void *);
 static int advansys_slave_configure(struct scsi_device *);
 static void asc_scsi_done_list(struct scsi_cmnd *);
 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
@@ -3979,10 +3692,6 @@ static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
 static int asc_prt_line(char *, int, char *fmt, ...);
 #endif /* CONFIG_PROC_FS */
 
-/* Declaration for Asc Library internal functions referenced by driver. */
-static int AscFindSignature(PortAddr);
-static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
-
 /* Statistics function prototypes. */
 #ifdef ADVANSYS_STATS
 #ifdef CONFIG_PROC_FS
@@ -4008,7 +3717,7 @@ static void asc_prt_hex(char *f, uchar *, int);
 
 #ifdef CONFIG_PROC_FS
 /*
- * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
+ * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
  *
  * *buffer: I/O buffer
  * **start: if inout == FALSE pointer into buffer where user read should start
@@ -4031,9 +3740,7 @@ static int
 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
                   off_t offset, int length, int inout)
 {
-       struct Scsi_Host *shp;
        asc_board_t *boardp;
-       int i;
        char *cp;
        int cplen;
        int cnt;
@@ -4058,18 +3765,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         * User read of /proc/scsi/advansys/[0...] file.
         */
 
-       /* Find the specified board. */
-       for (i = 0; i < asc_board_count; i++) {
-               if (asc_host[i]->host_no == shost->host_no) {
-                       break;
-               }
-       }
-       if (i == asc_board_count) {
-               return (-ENOENT);
-       }
-
-       shp = asc_host[i];
-       boardp = ASC_BOARDP(shp);
+       boardp = ASC_BOARDP(shost);
 
        /* Copy read data starting at the beginning of the buffer. */
        *start = buffer;
@@ -4083,7 +3779,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         *
         * advansys_info() returns the board string from its own static buffer.
         */
-       cp = (char *)advansys_info(shp);
+       cp = (char *)advansys_info(shost);
        strcat(cp, "\n");
        cplen = strlen(cp);
        /* Copy board information. */
@@ -4102,10 +3798,9 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         */
        if (ASC_WIDE_BOARD(boardp)) {
                cp = boardp->prtbuf;
-               cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
+               cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
                ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
-               cnt =
-                   asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
+               cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
                                  cplen);
                totcnt += cnt;
                leftlen -= cnt;
@@ -4121,7 +3816,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         * Display driver information for each device attached to the board.
         */
        cp = boardp->prtbuf;
-       cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
+       cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
        ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        totcnt += cnt;
@@ -4138,9 +3833,9 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         */
        cp = boardp->prtbuf;
        if (ASC_NARROW_BOARD(boardp)) {
-               cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
+               cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
        } else {
-               cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
+               cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
        }
        ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
@@ -4157,7 +3852,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         * Display driver configuration and information for the board.
         */
        cp = boardp->prtbuf;
-       cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
+       cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
        ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        totcnt += cnt;
@@ -4174,7 +3869,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         * Display driver statistics for the board.
         */
        cp = boardp->prtbuf;
-       cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
+       cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
        ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
        totcnt += cnt;
@@ -4191,11 +3886,11 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         */
        for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
                cp = boardp->prtbuf;
-               cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
+               cplen = asc_prt_target_stats(shost, tgt_id, cp,
+                                            ASC_PRTBUF_SIZE);
                ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
-               cnt =
-                   asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
-                                 cplen);
+               cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
+                                   cplen);
                totcnt += cnt;
                leftlen -= cnt;
                if (leftlen == 0) {
@@ -4213,9 +3908,9 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
         */
        cp = boardp->prtbuf;
        if (ASC_NARROW_BOARD(boardp)) {
-               cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
+               cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
        } else {
-               cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
+               cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
        }
        ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
        cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
@@ -4250,7 +3945,6 @@ static const char *advansys_info(struct Scsi_Host *shost)
        ASC_DVC_VAR *asc_dvc_varp;
        ADV_DVC_VAR *adv_dvc_varp;
        char *busname;
-       int iolen;
        char *widename = NULL;
 
        boardp = ASC_BOARDP(shost);
@@ -4264,13 +3958,12 @@ static const char *advansys_info(struct Scsi_Host *shost)
                        } else {
                                busname = "ISA";
                        }
-                       /* Don't reference 'shost->n_io_port'; It may be truncated. */
                        sprintf(info,
                                "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
                                ASC_VERSION, busname,
                                (ulong)shost->io_port,
-                               (ulong)shost->io_port + boardp->asc_n_io_port -
-                               1, shost->irq, shost->dma_channel);
+                               (ulong)shost->io_port + ASC_IOADR_GAP - 1,
+                               shost->irq, shost->dma_channel);
                } else {
                        if (asc_dvc_varp->bus_type & ASC_IS_VL) {
                                busname = "VL";
@@ -4285,17 +3978,15 @@ static const char *advansys_info(struct Scsi_Host *shost)
                                }
                        } else {
                                busname = "?";
-                               ASC_PRINT2
-                                   ("advansys_info: board %d: unknown bus type %d\n",
-                                    boardp->id, asc_dvc_varp->bus_type);
+                               ASC_PRINT2("advansys_info: board %d: unknown "
+                                          "bus type %d\n", boardp->id,
+                                          asc_dvc_varp->bus_type);
                        }
-                       /* Don't reference 'shost->n_io_port'; It may be truncated. */
                        sprintf(info,
                                "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
-                               ASC_VERSION, busname,
-                               (ulong)shost->io_port,
-                               (ulong)shost->io_port + boardp->asc_n_io_port -
-                               1, shost->irq);
+                               ASC_VERSION, busname, (ulong)shost->io_port,
+                               (ulong)shost->io_port + ASC_IOADR_GAP - 1,
+                               shost->irq);
                }
        } else {
                /*
@@ -4307,19 +3998,16 @@ static const char *advansys_info(struct Scsi_Host *shost)
                 */
                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-                       iolen = ADV_3550_IOLEN;
                        widename = "Ultra-Wide";
                } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
-                       iolen = ADV_38C0800_IOLEN;
                        widename = "Ultra2-Wide";
                } else {
-                       iolen = ADV_38C1600_IOLEN;
                        widename = "Ultra3-Wide";
                }
                sprintf(info,
                        "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
                        ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
-                       (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
+                       (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
        }
        ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
        ASC_DBG(1, "advansys_info: end\n");
@@ -4474,18 +4162,16 @@ static int advansys_reset(struct scsi_cmnd *scp)
 
                /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
                if (asc_dvc_varp->err_code) {
-                       ASC_PRINT2
-                           ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
-                            boardp->id, asc_dvc_varp->err_code);
+                       ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
+                                  "error: 0x%x\n", boardp->id,
+                                  asc_dvc_varp->err_code);
                        ret = FAILED;
                } else if (status) {
-                       ASC_PRINT2
-                           ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
-                            boardp->id, status);
+                       ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
+                                  "warning: 0x%x\n", boardp->id, status);
                } else {
-                       ASC_PRINT1
-                           ("advansys_reset: board %d: SCSI bus reset successful.\n",
-                            boardp->id);
+                       ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
+                                  "successful.\n", boardp->id);
                }
 
                ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
@@ -4506,15 +4192,13 @@ static int advansys_reset(struct scsi_cmnd *scp)
                ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
                switch (AdvResetChipAndSB(adv_dvc_varp)) {
                case ASC_TRUE:
-                       ASC_PRINT1
-                           ("advansys_reset: board %d: SCSI bus reset successful.\n",
-                            boardp->id);
+                       ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
+                                  "successful.\n", boardp->id);
                        break;
                case ASC_FALSE:
                default:
-                       ASC_PRINT1
-                           ("advansys_reset: board %d: SCSI bus reset error.\n",
-                            boardp->id);
+                       ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
+                                  "error.\n", boardp->id);
                        ret = FAILED;
                        break;
                }
@@ -4535,8 +4219,8 @@ static int advansys_reset(struct scsi_cmnd *scp)
         * is returned in 'last_scp'.
         */
        if (done_scp == NULL) {
-               done_scp =
-                   asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
+               done_scp = asc_dequeue_list(&boardp->active, &last_scp,
+                                           ASC_TID_ALL);
                for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
                        tscp->result = HOST_BYTE(DID_RESET);
                }
@@ -4562,8 +4246,8 @@ static int advansys_reset(struct scsi_cmnd *scp)
         * to DID_RESET.
         */
        if (done_scp == NULL) {
-               done_scp =
-                   asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
+               done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
+                                           ASC_TID_ALL);
                for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
                        tscp->result = HOST_BYTE(DID_RESET);
                }
@@ -4594,9 +4278,8 @@ static int advansys_reset(struct scsi_cmnd *scp)
        /*
         * Complete all the 'done_scp' requests.
         */
-       if (done_scp != NULL) {
+       if (done_scp)
                asc_scsi_done_list(done_scp);
-       }
 
        ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
 
@@ -4647,17 +4330,12 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
        return 0;
 }
 
-static int __init advansys_detect(struct scsi_host_template *tpnt);
-static int advansys_release(struct Scsi_Host *shp);
-
-static struct scsi_host_template driver_template = {
+static struct scsi_host_template advansys_template = {
        .proc_name = "advansys",
 #ifdef CONFIG_PROC_FS
        .proc_info = advansys_proc_info,
 #endif
        .name = "advansys",
-       .detect = advansys_detect,
-       .release = advansys_release,
        .info = advansys_info,
        .queuecommand = advansys_queuecommand,
        .eh_bus_reset_handler = advansys_reset,
@@ -4665,8 +4343,8 @@ static struct scsi_host_template driver_template = {
        .slave_configure = advansys_slave_configure,
        /*
         * Because the driver may control an ISA adapter 'unchecked_isa_dma'
-        * must be set. The flag will be cleared in advansys_detect for non-ISA
-        * adapters. Refer to the comment in scsi_module.c for more information.
+        * must be set. The flag will be cleared in advansys_board_found
+        * for non-ISA adapters.
         */
        .unchecked_isa_dma = 1,
        /*
@@ -4679,8 +4357,6 @@ static struct scsi_host_template driver_template = {
        .use_clustering = ENABLE_CLUSTERING,
 };
 
-#include "scsi_module.c"
-
 /*
  * --- Miscellaneous Driver Functions
  */
@@ -4696,89 +4372,76 @@ static struct scsi_host_template driver_template = {
  */
 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
 {
-       ulong flags;
-       int i;
-       asc_board_t *boardp;
+       unsigned long flags;
        struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
        struct scsi_cmnd *new_last_scp;
-       struct Scsi_Host *shost;
+       struct Scsi_Host *shost = dev_id;
+       asc_board_t *boardp = ASC_BOARDP(shost);
+       irqreturn_t result = IRQ_NONE;
 
-       ASC_DBG(1, "advansys_interrupt: begin\n");
+       ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
+       spin_lock_irqsave(&boardp->lock, flags);
+       if (ASC_NARROW_BOARD(boardp)) {
+               /*
+                * Narrow Board
+                */
+               if (AscIsIntPending(shost->io_port)) {
+                       result = IRQ_HANDLED;
+                       ASC_STATS(shost, interrupt);
+                       ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
+                       AscISR(&boardp->dvc_var.asc_dvc_var);
+               }
+       } else {
+               /*
+                * Wide Board
+                */
+               ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
+               if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
+                       result = IRQ_HANDLED;
+                       ASC_STATS(shost, interrupt);
+               }
+       }
 
        /*
-        * Check for interrupts on all boards.
-        * AscISR() will call asc_isr_callback().
-        */
-       for (i = 0; i < asc_board_count; i++) {
-               shost = asc_host[i];
-               boardp = ASC_BOARDP(shost);
-               ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
-                        i, (ulong)boardp);
-               spin_lock_irqsave(&boardp->lock, flags);
-               if (ASC_NARROW_BOARD(boardp)) {
-                       /*
-                        * Narrow Board
-                        */
-                       if (AscIsIntPending(shost->io_port)) {
-                               ASC_STATS(shost, interrupt);
-                               ASC_DBG(1,
-                                       "advansys_interrupt: before AscISR()\n");
-                               AscISR(&boardp->dvc_var.asc_dvc_var);
-                       }
-               } else {
-                       /*
-                        * Wide Board
-                        */
-                       ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
-                       if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
-                               ASC_STATS(shost, interrupt);
-                       }
+        * Start waiting requests and create a list of completed requests.
+        *
+        * If a reset request is being performed for the board, the reset
+        * handler will complete pending requests after it has completed.
+        */
+       if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
+               ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
+                        "last_scp 0x%p\n", done_scp, last_scp);
+
+               /* Start any waiting commands for the board. */
+               if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
+                       ASC_DBG(1, "advansys_interrupt: before "
+                               "asc_execute_queue()\n");
+                       asc_execute_queue(&boardp->waiting);
                }
 
                /*
-                * Start waiting requests and create a list of completed requests.
+                * Add to the list of requests that must be completed.
                 *
-                * If a reset request is being performed for the board, the reset
-                * handler will complete pending requests after it has completed.
+                * 'done_scp' will always be NULL on the first iteration of
+                * this loop. 'last_scp' is set at the same time as 'done_scp'.
                 */
-               if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
-                       ASC_DBG2(1,
-                                "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
-                                (ulong)done_scp, (ulong)last_scp);
-
-                       /* Start any waiting commands for the board. */
-                       if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
-                               ASC_DBG(1,
-                                       "advansys_interrupt: before asc_execute_queue()\n");
-                               asc_execute_queue(&boardp->waiting);
-                       }
-
-                       /*
-                        * Add to the list of requests that must be completed.
-                        *
-                        * 'done_scp' will always be NULL on the first iteration
-                        * of this loop. 'last_scp' is set at the same time as
-                        * 'done_scp'.
-                        */
-                       if (done_scp == NULL) {
-                               done_scp =
-                                   asc_dequeue_list(&boardp->done, &last_scp,
-                                                    ASC_TID_ALL);
-                       } else {
-                               ASC_ASSERT(last_scp != NULL);
-                               last_scp->host_scribble =
-                                   (unsigned char *)asc_dequeue_list(&boardp->
-                                                                     done,
-                                                                     &new_last_scp,
-                                                                     ASC_TID_ALL);
-                               if (new_last_scp != NULL) {
-                                       ASC_ASSERT(REQPNEXT(last_scp) != NULL);
-                                       last_scp = new_last_scp;
-                               }
+               if (done_scp == NULL) {
+                       done_scp = asc_dequeue_list(&boardp->done,
+                                               &last_scp, ASC_TID_ALL);
+               } else {
+                       ASC_ASSERT(last_scp != NULL);
+                       last_scp->host_scribble =
+                           (unsigned char *)asc_dequeue_list(&boardp->
+                                                             done,
+                                                             &new_last_scp,
+                                                             ASC_TID_ALL);
+                       if (new_last_scp != NULL) {
+                               ASC_ASSERT(REQPNEXT(last_scp) != NULL);
+                               last_scp = new_last_scp;
                        }
                }
-               spin_unlock_irqrestore(&boardp->lock, flags);
        }
+       spin_unlock_irqrestore(&boardp->lock, flags);
 
        /*
         * If interrupts were enabled on entry, then they
@@ -4790,41 +4453,206 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id)
        asc_scsi_done_list(done_scp);
 
        ASC_DBG(1, "advansys_interrupt: end\n");
-       return IRQ_HANDLED;
+       return result;
+}
+
+static void
+advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
+{
+       ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
+       ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
+
+       if (sdev->lun == 0) {
+               ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
+               if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
+                       asc_dvc->init_sdtr |= tid_bit;
+               } else {
+                       asc_dvc->init_sdtr &= ~tid_bit;
+               }
+
+               if (orig_init_sdtr != asc_dvc->init_sdtr)
+                       AscAsyncFix(asc_dvc, sdev);
+       }
+
+       if (sdev->tagged_supported) {
+               if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
+                       if (sdev->lun == 0) {
+                               asc_dvc->cfg->can_tagged_qng |= tid_bit;
+                               asc_dvc->use_tagged_qng |= tid_bit;
+                       }
+                       scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
+                                               asc_dvc->max_dvc_qng[sdev->id]);
+               }
+       } else {
+               if (sdev->lun == 0) {
+                       asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
+                       asc_dvc->use_tagged_qng &= ~tid_bit;
+               }
+               scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+       }
+
+       if ((sdev->lun == 0) &&
+           (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
+               AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
+                                asc_dvc->cfg->disc_enable);
+               AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
+                                asc_dvc->use_tagged_qng);
+               AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
+                                asc_dvc->cfg->can_tagged_qng);
+
+               asc_dvc->max_dvc_qng[sdev->id] =
+                                       asc_dvc->cfg->max_tag_qng[sdev->id];
+               AscWriteLramByte(asc_dvc->iop_base,
+                                (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
+                                asc_dvc->max_dvc_qng[sdev->id]);
+       }
 }
 
 /*
- * Set the number of commands to queue per device for the
- * specified host adapter.
+ * Wide Transfers
+ *
+ * If the EEPROM enabled WDTR for the device and the device supports wide
+ * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
+ * write the new value to the microcode.
  */
-static int advansys_slave_configure(struct scsi_device *device)
+static void
+advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
 {
-       asc_board_t *boardp;
+       unsigned short cfg_word;
+       AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
+       if ((cfg_word & tidmask) != 0)
+               return;
+
+       cfg_word |= tidmask;
+       AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
 
-       boardp = ASC_BOARDP(device->host);
-       boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
        /*
-        * Save a pointer to the device and set its initial/maximum
-        * queue depth.  Only save the pointer for a lun0 dev though.
+        * Clear the microcode SDTR and WDTR negotiation done indicators for
+        * the target to cause it to negotiate with the new setting set above.
+        * WDTR when accepted causes the target to enter asynchronous mode, so
+        * SDTR must be negotiated.
+        */
+       AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+       cfg_word &= ~tidmask;
+       AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+       AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
+       cfg_word &= ~tidmask;
+       AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
+}
+
+/*
+ * Synchronous Transfers
+ *
+ * If the EEPROM enabled SDTR for the device and the device
+ * supports synchronous transfers, then turn on the device's
+ * 'sdtr_able' bit. Write the new value to the microcode.
+ */
+static void
+advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
+{
+       unsigned short cfg_word;
+       AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
+       if ((cfg_word & tidmask) != 0)
+               return;
+
+       cfg_word |= tidmask;
+       AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
+
+       /*
+        * Clear the microcode "SDTR negotiation" done indicator for the
+        * target to cause it to negotiate with the new setting set above.
         */
-       if (device->lun == 0)
-               boardp->device[device->id] = device;
-       if (device->tagged_supported) {
-               if (ASC_NARROW_BOARD(boardp)) {
-                       scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
-                                               boardp->dvc_var.asc_dvc_var.
-                                               max_dvc_qng[device->id]);
-               } else {
-                       scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
-                                               boardp->dvc_var.adv_dvc_var.
-                                               max_dvc_qng);
+       AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+       cfg_word &= ~tidmask;
+       AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+}
+
+/*
+ * PPR (Parallel Protocol Request) Capable
+ *
+ * If the device supports DT mode, then it must be PPR capable.
+ * The PPR message will be used in place of the SDTR and WDTR
+ * messages to negotiate synchronous speed and offset, transfer
+ * width, and protocol options.
+ */
+static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
+                               AdvPortAddr iop_base, unsigned short tidmask)
+{
+       AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
+       adv_dvc->ppr_able |= tidmask;
+       AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
+}
+
+static void
+advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
+{
+       AdvPortAddr iop_base = adv_dvc->iop_base;
+       unsigned short tidmask = 1 << sdev->id;
+
+       if (sdev->lun == 0) {
+               /*
+                * Handle WDTR, SDTR, and Tag Queuing. If the feature
+                * is enabled in the EEPROM and the device supports the
+                * feature, then enable it in the microcode.
+                */
+
+               if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
+                       advansys_wide_enable_wdtr(iop_base, tidmask);
+               if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
+                       advansys_wide_enable_sdtr(iop_base, tidmask);
+               if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
+                       advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
+
+               /*
+                * Tag Queuing is disabled for the BIOS which runs in polled
+                * mode and would see no benefit from Tag Queuing. Also by
+                * disabling Tag Queuing in the BIOS devices with Tag Queuing
+                * bugs will at least work with the BIOS.
+                */
+               if ((adv_dvc->tagqng_able & tidmask) &&
+                   sdev->tagged_supported) {
+                       unsigned short cfg_word;
+                       AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
+                       cfg_word |= tidmask;
+                       AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
+                                        cfg_word);
+                       AdvWriteByteLram(iop_base,
+                                        ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
+                                        adv_dvc->max_dvc_qng);
                }
+       }
+
+       if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
+               scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
+                                       adv_dvc->max_dvc_qng);
        } else {
-               scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
+               scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
        }
-       ASC_DBG4(1,
-                "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
-                (ulong)device, (ulong)boardp, device->id, device->queue_depth);
+}
+
+/*
+ * Set the number of commands to queue per device for the
+ * specified host adapter.
+ */
+static int advansys_slave_configure(struct scsi_device *sdev)
+{
+       asc_board_t *boardp = ASC_BOARDP(sdev->host);
+       boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
+
+       /*
+        * Save a pointer to the sdev and set its initial/maximum
+        * queue depth.  Only save the pointer for a lun0 dev though.
+        */
+       if (sdev->lun == 0)
+               boardp->device[sdev->id] = sdev;
+
+       if (ASC_NARROW_BOARD(boardp))
+               advansys_narrow_slave_configure(sdev,
+                                               &boardp->dvc_var.asc_dvc_var);
+       else
+               advansys_wide_slave_configure(sdev,
+                                               &boardp->dvc_var.adv_dvc_var);
+
        return 0;
 }
 
@@ -4841,7 +4669,6 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp)
        ASC_DBG(2, "asc_scsi_done_list: begin\n");
        while (scp != NULL) {
                asc_board_t *boardp;
-               struct device *dev;
 
                ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
                tscp = REQPNEXT(scp);
@@ -4849,17 +4676,12 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp)
 
                boardp = ASC_BOARDP(scp->device->host);
 
-               if (ASC_NARROW_BOARD(boardp))
-                       dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
-               else
-                       dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
-
                if (scp->use_sg)
-                       dma_unmap_sg(dev,
+                       dma_unmap_sg(boardp->dev,
                                     (struct scatterlist *)scp->request_buffer,
                                     scp->use_sg, scp->sc_data_direction);
                else if (scp->request_bufflen)
-                       dma_unmap_single(dev, scp->SCp.dma_handle,
+                       dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
                                         scp->request_bufflen,
                                         scp->sc_data_direction);
 
@@ -4965,33 +4787,33 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
                case ASC_NOERROR:
                        ASC_STATS(scp->device->host, exe_noerror);
                        /*
-                        * Increment monotonically increasing per device successful
-                        * request counter. Wrapping doesn't matter.
+                        * Increment monotonically increasing per device
+                        * successful request counter. Wrapping doesn't matter.
                         */
                        boardp->reqcnt[scp->device->id]++;
                        asc_enqueue(&boardp->active, scp, ASC_BACK);
-                       ASC_DBG(1,
-                               "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
+                       ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
+                               "ASC_NOERROR\n");
                        break;
                case ASC_BUSY:
                        /*
-                        * Caller will enqueue request on the target's waiting queue
-                        * and retry later.
+                        * Caller will enqueue request on the target's waiting
+                        * queue and retry later.
                         */
                        ASC_STATS(scp->device->host, exe_busy);
                        break;
                case ASC_ERROR:
-                       ASC_PRINT2
-                           ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
-                            boardp->id, asc_dvc_varp->err_code);
+                       ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+                               "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
+                               boardp->id, asc_dvc_varp->err_code);
                        ASC_STATS(scp->device->host, exe_error);
                        scp->result = HOST_BYTE(DID_ERROR);
                        asc_enqueue(&boardp->done, scp, ASC_BACK);
                        break;
                default:
-                       ASC_PRINT2
-                           ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
-                            boardp->id, asc_dvc_varp->err_code);
+                       ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+                               "AscExeScsiQueue() unknown, err_code 0x%x\n",
+                               boardp->id, asc_dvc_varp->err_code);
                        ASC_STATS(scp->device->host, exe_unknown);
                        scp->result = HOST_BYTE(DID_ERROR);
                        asc_enqueue(&boardp->done, scp, ASC_BACK);
@@ -5011,20 +4833,21 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
                 */
                switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
                case ASC_NOERROR:
-                       ASC_DBG(3,
-                               "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
+                       ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
+                               "ASC_NOERROR\n");
                        break;
                case ASC_BUSY:
-                       ASC_DBG(1,
-                               "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
+                       ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
+                               "ASC_BUSY\n");
                        /*
-                        * If busy is returned the request has not been enqueued.
-                        * It will be enqueued by the caller on the target's waiting
-                        * queue and retried later.
+                        * If busy is returned the request has not been
+                        * enqueued.  It will be enqueued by the caller on the
+                        * target's waiting queue and retried later.
                         *
-                        * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
-                        * count wide board busy conditions. They are updated in
-                        * adv_build_req and adv_get_sglist, respectively.
+                        * The asc_stats fields 'adv_build_noreq' and
+                        * 'adv_build_nosg' count wide board busy conditions.
+                        * They are updated in adv_build_req and
+                        * adv_get_sglist, respectively.
                         */
                        return ASC_BUSY;
                case ASC_ERROR:
@@ -5034,8 +4857,8 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
                         * by the caller.
                         */
                default:
-                       ASC_DBG(1,
-                               "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
+                       ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
+                               "ASC_ERROR\n");
                        ASC_STATS(scp->device->host, build_error);
                        return ASC_ERROR;
                }
@@ -5048,33 +4871,33 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
                case ASC_NOERROR:
                        ASC_STATS(scp->device->host, exe_noerror);
                        /*
-                        * Increment monotonically increasing per device successful
-                        * request counter. Wrapping doesn't matter.
+                        * Increment monotonically increasing per device
+                        * successful request counter. Wrapping doesn't matter.
                         */
                        boardp->reqcnt[scp->device->id]++;
                        asc_enqueue(&boardp->active, scp, ASC_BACK);
-                       ASC_DBG(1,
-                               "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
+                       ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
+                               "ASC_NOERROR\n");
                        break;
                case ASC_BUSY:
                        /*
-                        * Caller will enqueue request on the target's waiting queue
-                        * and retry later.
+                        * Caller will enqueue request on the target's waiting
+                        * queue and retry later.
                         */
                        ASC_STATS(scp->device->host, exe_busy);
                        break;
                case ASC_ERROR:
-                       ASC_PRINT2
-                           ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
-                            boardp->id, adv_dvc_varp->err_code);
+                       ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+                               "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
+                               boardp->id, adv_dvc_varp->err_code);
                        ASC_STATS(scp->device->host, exe_error);
                        scp->result = HOST_BYTE(DID_ERROR);
                        asc_enqueue(&boardp->done, scp, ASC_BACK);
                        break;
                default:
-                       ASC_PRINT2
-                           ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
-                            boardp->id, adv_dvc_varp->err_code);
+                       ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+                               "AdvExeScsiQueue() unknown, err_code 0x%x\n",
+                               boardp->id, adv_dvc_varp->err_code);
                        ASC_STATS(scp->device->host, exe_unknown);
                        scp->result = HOST_BYTE(DID_ERROR);
                        asc_enqueue(&boardp->done, scp, ASC_BACK);
@@ -5097,8 +4920,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
  */
 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
 {
-       struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
-
        /*
         * Mutually exclusive access is required to 'asc_scsi_q' and
         * 'asc_sg_head' until after the request is started.
@@ -5117,9 +4938,9 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
         * is supported.
         */
        if (scp->cmd_len > ASC_MAX_CDB_LEN) {
-               ASC_PRINT3
-                   ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
-                    boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
+               ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
+                       "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
+                       ASC_MAX_CDB_LEN);
                scp->result = HOST_BYTE(DID_ERROR);
                asc_enqueue(&boardp->done, scp, ASC_BACK);
                return ASC_ERROR;
@@ -5162,7 +4983,7 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
                 */
                ASC_STATS(scp->device->host, cont_cnt);
                scp->SCp.dma_handle = scp->request_bufflen ?
-                   dma_map_single(dev, scp->request_buffer,
+                   dma_map_single(boardp->dev, scp->request_buffer,
                                   scp->request_bufflen,
                                   scp->sc_data_direction) : 0;
                asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
@@ -5180,15 +5001,14 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
                struct scatterlist *slp;
 
                slp = (struct scatterlist *)scp->request_buffer;
-               use_sg =
-                   dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+               use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
+                                   scp->sc_data_direction);
 
                if (use_sg > scp->device->host->sg_tablesize) {
-                       ASC_PRINT3
-                           ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
-                            boardp->id, use_sg,
-                            scp->device->host->sg_tablesize);
-                       dma_unmap_sg(dev, slp, scp->use_sg,
+                       ASC_PRINT3("asc_build_req: board %d: use_sg %d > "
+                                  "sg_tablesize %d\n", boardp->id, use_sg,
+                                  scp->device->host->sg_tablesize);
+                       dma_unmap_sg(boardp->dev, slp, scp->use_sg,
                                     scp->sc_data_direction);
                        scp->result = HOST_BYTE(DID_ERROR);
                        asc_enqueue(&boardp->done, scp, ASC_BACK);
@@ -5249,7 +5069,6 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
        ADV_SCSI_REQ_Q *scsiqp;
        int i;
        int ret;
-       struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
 
        /*
         * Allocate an adv_req_t structure from the board to execute
@@ -5336,7 +5155,7 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
                if (scp->request_bufflen) {
                        scsiqp->vdata_addr = scp->request_buffer;
                        scp->SCp.dma_handle =
-                           dma_map_single(dev, scp->request_buffer,
+                           dma_map_single(boardp->dev, scp->request_buffer,
                                           scp->request_bufflen,
                                           scp->sc_data_direction);
                } else {
@@ -5357,22 +5176,21 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
                int use_sg;
 
                slp = (struct scatterlist *)scp->request_buffer;
-               use_sg =
-                   dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+               use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
+                                   scp->sc_data_direction);
 
                if (use_sg > ADV_MAX_SG_LIST) {
-                       ASC_PRINT3
-                           ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
-                            boardp->id, use_sg,
-                            scp->device->host->sg_tablesize);
-                       dma_unmap_sg(dev, slp, scp->use_sg,
+                       ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
+                                  "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
+                                  scp->device->host->sg_tablesize);
+                       dma_unmap_sg(boardp->dev, slp, scp->use_sg,
                                     scp->sc_data_direction);
                        scp->result = HOST_BYTE(DID_ERROR);
                        asc_enqueue(&boardp->done, scp, ASC_BACK);
 
                        /*
-                        * Free the 'adv_req_t' structure by adding it back to the
-                        * board free list.
+                        * Free the 'adv_req_t' structure by adding it back
+                        * to the board free list.
                         */
                        reqp->next_reqp = boardp->adv_reqp;
                        boardp->adv_reqp = reqp;
@@ -5380,12 +5198,11 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
                        return ASC_ERROR;
                }
 
-               if ((ret =
-                    adv_get_sglist(boardp, reqp, scp,
-                                   use_sg)) != ADV_SUCCESS) {
+               ret = adv_get_sglist(boardp, reqp, scp, use_sg);
+               if (ret != ADV_SUCCESS) {
                        /*
-                        * Free the adv_req_t structure by adding it back to the
-                        * board free list.
+                        * Free the adv_req_t structure by adding it back to
+                        * the board free list.
                         */
                        reqp->next_reqp = boardp->adv_reqp;
                        boardp->adv_reqp = reqp;
@@ -5532,7 +5349,6 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
        asc_board_t *boardp;
        struct scsi_cmnd *scp;
        struct Scsi_Host *shost;
-       int i;
 
        ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
                 (ulong)asc_dvc_varp, (ulong)qdonep);
@@ -5551,23 +5367,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
        }
        ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
 
-       /*
-        * If the request's host pointer is not valid, display a
-        * message and return.
-        */
        shost = scp->device->host;
-       for (i = 0; i < asc_board_count; i++) {
-               if (asc_host[i] == shost) {
-                       break;
-               }
-       }
-       if (i == asc_board_count) {
-               ASC_PRINT2
-                   ("asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
-                    (ulong)scp, (ulong)shost);
-               return;
-       }
-
        ASC_STATS(shost, callback);
        ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
 
@@ -5593,22 +5393,11 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
                ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
                scp->result = 0;
 
-               /*
-                * If an INQUIRY command completed successfully, then call
-                * the AscInquiryHandling() function to set-up the device.
-                */
-               if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
-                   (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
-                       AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
-                                          (ASC_SCSI_INQUIRY *)scp->
-                                          request_buffer);
-               }
-
                /*
                 * Check for an underrun condition.
                 *
                 * If there was no error and an underrun condition, then
-                * then return the number of underrun bytes.
+                * return the number of underrun bytes.
                 */
                if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
                    qdonep->remain_bytes <= scp->request_bufflen) {
@@ -5706,7 +5495,6 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
        adv_sgblk_t *sgblkp;
        struct scsi_cmnd *scp;
        struct Scsi_Host *shost;
-       int i;
        ADV_DCNT resid_cnt;
 
        ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
@@ -5742,27 +5530,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
        }
        ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
 
-       /*
-        * If the request's host pointer is not valid, display a message
-        * and return.
-        */
        shost = scp->device->host;
-       for (i = 0; i < asc_board_count; i++) {
-               if (asc_host[i] == shost) {
-                       break;
-               }
-       }
-       /*
-        * Note: If the host structure is not found, the adv_req_t request
-        * structure and adv_sgblk_t structure, if any, is dropped.
-        */
-       if (i == asc_board_count) {
-               ASC_PRINT2
-                   ("adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
-                    (ulong)scp, (ulong)shost);
-               return;
-       }
-
        ASC_STATS(shost, callback);
        ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
 
@@ -6907,10 +6675,7 @@ static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
                           boardp->asc_n_io_port);
        ASC_PRT_NEXT();
 
-       /* 'shost->n_io_port' may be truncated because it is only one byte. */
-       len = asc_prt_line(cp, leftlen,
-                          " io_port 0x%x, n_io_port 0x%x\n",
-                          shost->io_port, shost->n_io_port);
+       len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
        ASC_PRT_NEXT();
 
        if (ASC_NARROW_BOARD(boardp)) {
@@ -7511,56 +7276,31 @@ DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
        ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
 }
 
-/*
- * Read a PCI configuration byte.
- */
-static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
-{
-#ifdef CONFIG_PCI
-       uchar byte_data;
-       pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
-       return byte_data;
-#else /* !defined(CONFIG_PCI) */
-       return 0;
-#endif /* !defined(CONFIG_PCI) */
-}
-
-/*
- * Write a PCI configuration byte.
- */
-static void __init
-DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
-{
-#ifdef CONFIG_PCI
-       pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
-#endif /* CONFIG_PCI */
-}
-
 /*
  * Return the BIOS address of the adapter at the specified
  * I/O port and with the specified bus type.
  */
-static ushort __init AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
+static unsigned short __devinit
+AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
 {
-       ushort cfg_lsw;
-       ushort bios_addr;
+       unsigned short cfg_lsw;
+       unsigned short bios_addr;
 
        /*
         * The PCI BIOS is re-located by the motherboard BIOS. Because
         * of this the driver can not determine where a PCI BIOS is
         * loaded and executes.
         */
-       if (bus_type & ASC_IS_PCI) {
-               return (0);
-       }
+       if (bus_type & ASC_IS_PCI)
+               return 0;
+
 #ifdef CONFIG_ISA
        if ((bus_type & ASC_IS_EISA) != 0) {
                cfg_lsw = AscGetEisaChipCfg(iop_base);
                cfg_lsw &= 0x000F;
-               bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
-                                    (cfg_lsw * ASC_BIOS_BANK_SIZE));
-               return (bios_addr);
-       }                       /* if */
+               bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
+               return bios_addr;
+       }
 #endif /* CONFIG_ISA */
 
        cfg_lsw = AscGetChipCfgLsw(iop_base);
@@ -7568,13 +7308,10 @@ static ushort __init AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
        /*
         *  ISA PnP uses the top bit as the 32K BIOS flag
         */
-       if (bus_type == ASC_IS_ISAPNP) {
+       if (bus_type == ASC_IS_ISAPNP)
                cfg_lsw &= 0x7FFF;
-       }
-       /* if */
-       bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
-                            ASC_BIOS_MIN_ADDR);
-       return (bios_addr);
+       bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
+       return bios_addr;
 }
 
 /*
@@ -7609,34 +7346,7 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
 }
 
 /*
- * Read a PCI configuration byte.
- */
-static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
-{
-#ifdef CONFIG_PCI
-       uchar byte_data;
-       pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
-       return byte_data;
-#else /* CONFIG_PCI */
-       return 0;
-#endif /* CONFIG_PCI */
-}
-
-/*
- * Write a PCI configuration byte.
- */
-static void __init
-DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
-{
-#ifdef CONFIG_PCI
-       pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
-#else /* CONFIG_PCI */
-       return;
-#endif /* CONFIG_PCI */
-}
-
-/*
- * --- Tracing and Debugging Functions
+ * --- Tracing and Debugging Functions
  */
 
 #ifdef ADVANSYS_STATS
@@ -7857,8 +7567,8 @@ static void asc_prt_scsi_host(struct Scsi_Host *s)
        printk(" host_busy %u, host_no %d, last_reset %d,\n",
               s->host_busy, s->host_no, (unsigned)s->last_reset);
 
-       printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
-              (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
+       printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
+              (ulong)s->base, (ulong)s->io_port, s->irq);
 
        printk(" dma_channel %d, this_id %d, can_queue %d,\n",
               s->dma_channel, s->this_id, s->can_queue);
@@ -7898,10 +7608,8 @@ static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
 
        printk(" timeout_per_command %d\n", s->timeout_per_command);
 
-       printk
-           (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
-            (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
-            s->result);
+       printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
+               s->scsi_done, s->done, s->host_scribble, s->result);
 
        printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
 }
@@ -7913,34 +7621,31 @@ static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
 {
        printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
 
-       printk
-           (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
-            h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
+       printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
+              "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
 
-       printk
-           (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
-            h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
-            (unsigned)h->init_sdtr);
+       printk(" bus_type %d, isr_callback 0x%p, exe_callback 0x%p, "
+              "init_sdtr 0x%x,\n", h->bus_type, h->isr_callback,
+              h->exe_callback, (unsigned)h->init_sdtr);
 
-       printk
-           (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
-            (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
-            (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
+       printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
+              "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
+              (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
+              (unsigned)h->chip_no);
 
-       printk
-           (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
-            (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
-            (unsigned)h->scsi_reset_wait);
+       printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
+              "%u,\n", (unsigned)h->queue_full_or_busy,
+              (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
 
-       printk
-           (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
-            (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
-            (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
+       printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
+              "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
+              (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
+              (unsigned)h->in_critical_cnt);
 
-       printk
-           (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
-            (unsigned)h->last_q_shortage, (unsigned)h->init_state,
-            (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
+       printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
+              "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
+              (unsigned)h->init_state, (unsigned)h->no_scam,
+              (unsigned)h->pci_fix_asyn_xfer);
 
        printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
 }
@@ -8221,7 +7926,7 @@ static void asc_prt_hex(char *f, uchar *s, int l)
  * --- Asc Library Functions
  */
 
-static ushort __init AscGetEisaChipCfg(PortAddr iop_base)
+static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
 {
        PortAddr eisa_cfg_iop;
 
@@ -8230,7 +7935,7 @@ static ushort __init AscGetEisaChipCfg(PortAddr iop_base)
        return (inpw(eisa_cfg_iop));
 }
 
-static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
+static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
 {
        ushort cfg_lsw;
 
@@ -8244,55 +7949,28 @@ static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
        return (AscGetChipScsiID(iop_base));
 }
 
-static uchar __init AscGetChipScsiCtrl(PortAddr iop_base)
+static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
 {
-       uchar sc;
+       unsigned char sc;
 
        AscSetBank(iop_base, 1);
        sc = inp(iop_base + IOP_REG_SC);
        AscSetBank(iop_base, 0);
-       return (sc);
+       return sc;
 }
 
-static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type)
+static unsigned char __devinit
+AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
 {
-       if ((bus_type & ASC_IS_EISA) != 0) {
+       if (bus_type & ASC_IS_EISA) {
                PortAddr eisa_iop;
-               uchar revision;
+               unsigned char revision;
                eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
                    (PortAddr) ASC_EISA_REV_IOP_MASK;
                revision = inp(eisa_iop);
-               return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
-       }
-       return (AscGetChipVerNo(iop_base));
-}
-
-static ushort __init AscGetChipBusType(PortAddr iop_base)
-{
-       ushort chip_ver;
-
-       chip_ver = AscGetChipVerNo(iop_base);
-       if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
-           && (chip_ver <= ASC_CHIP_MAX_VER_VL)
-           ) {
-               if (((iop_base & 0x0C30) == 0x0C30)
-                   || ((iop_base & 0x0C50) == 0x0C50)
-                   ) {
-                       return (ASC_IS_EISA);
-               }
-               return (ASC_IS_VL);
-       }
-       if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
-           (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
-               if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
-                       return (ASC_IS_ISAPNP);
-               }
-               return (ASC_IS_ISA);
-       } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
-                  (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
-               return (ASC_IS_PCI);
+               return ASC_CHIP_MIN_VER_EISA - 1 + revision;
        }
-       return (0);
+       return AscGetChipVerNo(iop_base);
 }
 
 static ASC_DCNT
@@ -8342,91 +8020,14 @@ static int AscFindSignature(PortAddr iop_base)
        return (0);
 }
 
-static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = {
-       0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
-       ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
-};
-
-#ifdef CONFIG_ISA
-static uchar _isa_pnp_inited __initdata = 0;
-
-static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type)
-{
-       if (bus_type & ASC_IS_VL) {
-               while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
-                       if (AscGetChipVersion(iop_beg, bus_type) <=
-                           ASC_CHIP_MAX_VER_VL) {
-                               return (iop_beg);
-                       }
-               }
-               return (0);
-       }
-       if (bus_type & ASC_IS_ISA) {
-               if (_isa_pnp_inited == 0) {
-                       AscSetISAPNPWaitForKey();
-                       _isa_pnp_inited++;
-               }
-               while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
-                       if ((AscGetChipVersion(iop_beg, bus_type) &
-                            ASC_CHIP_VER_ISA_BIT) != 0) {
-                               return (iop_beg);
-                       }
-               }
-               return (0);
-       }
-       if (bus_type & ASC_IS_EISA) {
-               if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
-                       return (iop_beg);
-               }
-               return (0);
-       }
-       return (0);
-}
-
-static PortAddr __init AscSearchIOPortAddr11(PortAddr s_addr)
-{
-       int i;
-       PortAddr iop_base;
-
-       for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
-               if (_asc_def_iop_base[i] > s_addr) {
-                       break;
-               }
-       }
-       for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
-               iop_base = _asc_def_iop_base[i];
-               if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
-                       ASC_DBG1(1,
-                                "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
-                                iop_base);
-                       continue;
-               }
-               ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n",
-                        iop_base);
-               release_region(iop_base, ASC_IOADR_GAP);
-               if (AscFindSignature(iop_base)) {
-                       return (iop_base);
-               }
-       }
-       return (0);
-}
-
-static void __init AscSetISAPNPWaitForKey(void)
-{
-       outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
-       outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
-       return;
-}
-#endif /* CONFIG_ISA */
-
-static void __init AscToggleIRQAct(PortAddr iop_base)
+static void __devinit AscToggleIRQAct(PortAddr iop_base)
 {
        AscSetChipStatus(iop_base, CIW_IRQ_ACT);
        AscSetChipStatus(iop_base, 0);
        return;
 }
 
-static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
+static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
 {
        ushort cfg_lsw;
        uchar chip_irq;
@@ -8454,7 +8055,7 @@ static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
        return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
 }
 
-static uchar __init
+static uchar __devinit
 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
 {
        ushort cfg_lsw;
@@ -8491,7 +8092,7 @@ AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
 }
 
 #ifdef CONFIG_ISA
-static void __init AscEnableIsaDma(uchar dma_channel)
+static void __devinit AscEnableIsaDma(uchar dma_channel)
 {
        if (dma_channel < 4) {
                outp(0x000B, (ushort)(0xC0 | dma_channel));
@@ -8567,8 +8168,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
                                          (uchar *)&ext_msg,
                                          sizeof(EXT_MSG) >> 1);
 
-               if (ext_msg.msg_type == MS_EXTEND &&
-                   ext_msg.msg_req == MS_SDTR_CODE &&
+               if (ext_msg.msg_type == EXTENDED_MESSAGE &&
+                   ext_msg.msg_req == EXTENDED_SDTR &&
                    ext_msg.msg_len == MS_SDTR_LEN) {
                        sdtr_accept = TRUE;
                        if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
@@ -8650,8 +8251,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
                                         q_cntl);
                        AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
                        return (0);
-               } else if (ext_msg.msg_type == MS_EXTEND &&
-                          ext_msg.msg_req == MS_WDTR_CODE &&
+               } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
+                          ext_msg.msg_req == EXTENDED_WDTR &&
                           ext_msg.msg_len == MS_WDTR_LEN) {
 
                        ext_msg.wdtr_width = 0;
@@ -8744,9 +8345,9 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
                                          (uchar *)&out_msg,
                                          sizeof(EXT_MSG) >> 1);
 
-               if ((out_msg.msg_type == MS_EXTEND) &&
+               if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
                    (out_msg.msg_len == MS_SDTR_LEN) &&
-                   (out_msg.msg_req == MS_SDTR_CODE)) {
+                   (out_msg.msg_req == EXTENDED_SDTR)) {
 
                        asc_dvc->init_sdtr &= ~target_id;
                        asc_dvc->sdtr_done &= ~target_id;
@@ -10239,9 +9840,9 @@ AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
        PortAddr iop_base;
 
        iop_base = asc_dvc->iop_base;
-       sdtr_buf.msg_type = MS_EXTEND;
+       sdtr_buf.msg_type = EXTENDED_MESSAGE;
        sdtr_buf.msg_len = MS_SDTR_LEN;
-       sdtr_buf.msg_req = MS_SDTR_CODE;
+       sdtr_buf.msg_req = EXTENDED_SDTR;
        sdtr_buf.xfer_period = sdtr_period;
        sdtr_offset &= ASC_SYN_MAX_OFFSET;
        sdtr_buf.req_ack_offset = sdtr_offset;
@@ -10389,57 +9990,6 @@ static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
        udelay((nano_sec + 999) / 1000);
 }
 
-#ifdef CONFIG_ISA
-static ASC_DCNT __init AscGetEisaProductID(PortAddr iop_base)
-{
-       PortAddr eisa_iop;
-       ushort product_id_high, product_id_low;
-       ASC_DCNT product_id;
-
-       eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
-       product_id_low = inpw(eisa_iop);
-       product_id_high = inpw(eisa_iop + 2);
-       product_id = ((ASC_DCNT) product_id_high << 16) |
-           (ASC_DCNT) product_id_low;
-       return (product_id);
-}
-
-static PortAddr __init AscSearchIOPortAddrEISA(PortAddr iop_base)
-{
-       ASC_DCNT eisa_product_id;
-
-       if (iop_base == 0) {
-               iop_base = ASC_EISA_MIN_IOP_ADDR;
-       } else {
-               if (iop_base == ASC_EISA_MAX_IOP_ADDR)
-                       return (0);
-               if ((iop_base & 0x0050) == 0x0050) {
-                       iop_base += ASC_EISA_BIG_IOP_GAP;
-               } else {
-                       iop_base += ASC_EISA_SMALL_IOP_GAP;
-               }
-       }
-       while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
-               eisa_product_id = AscGetEisaProductID(iop_base);
-               if ((eisa_product_id == ASC_EISA_ID_740) ||
-                   (eisa_product_id == ASC_EISA_ID_750)) {
-                       if (AscFindSignature(iop_base)) {
-                               inpw(iop_base + 4);
-                               return (iop_base);
-                       }
-               }
-               if (iop_base == ASC_EISA_MAX_IOP_ADDR)
-                       return (0);
-               if ((iop_base & 0x0050) == 0x0050) {
-                       iop_base += ASC_EISA_BIG_IOP_GAP;
-               } else {
-                       iop_base += ASC_EISA_SMALL_IOP_GAP;
-               }
-       }
-       return (0);
-}
-#endif /* CONFIG_ISA */
-
 static int AscStartChip(PortAddr iop_base)
 {
        AscSetChipControl(iop_base, 0);
@@ -10573,7 +10123,7 @@ static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
        return (AscIsChipHalted(iop_base));
 }
 
-static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type)
+static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
 {
        if (bus_type & ASC_IS_ISA)
                return (ASC_MAX_ISA_DMA_COUNT);
@@ -10583,7 +10133,7 @@ static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type)
 }
 
 #ifdef CONFIG_ISA
-static ushort __init AscGetIsaDmaChannel(PortAddr iop_base)
+static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
 {
        ushort channel;
 
@@ -10595,7 +10145,7 @@ static ushort __init AscGetIsaDmaChannel(PortAddr iop_base)
        return (channel + 4);
 }
 
-static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
+static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
 {
        ushort cfg_lsw;
        uchar value;
@@ -10613,7 +10163,7 @@ static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
        return (0);
 }
 
-static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
+static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
 {
        speed_value &= 0x07;
        AscSetBank(iop_base, 1);
@@ -10622,7 +10172,7 @@ static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
        return (AscGetIsaDmaSpeed(iop_base));
 }
 
-static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base)
+static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
 {
        uchar speed_value;
 
@@ -10634,130 +10184,41 @@ static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base)
 }
 #endif /* CONFIG_ISA */
 
-static ushort __init
-AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
-{
-       uchar lsb, msb;
-
-       lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
-       msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
-       return ((ushort)((msb << 8) | lsb));
-}
-
-static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
+static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
 {
-       ushort warn_code;
-       PortAddr iop_base;
-       ushort PCIDeviceID;
-       ushort PCIVendorID;
-       uchar PCIRevisionID;
-       uchar prevCmdRegBits;
+       unsigned short warn_code = 0;
 
-       warn_code = 0;
-       iop_base = asc_dvc->iop_base;
        asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
-       if (asc_dvc->err_code != 0) {
+       if (asc_dvc->err_code != 0)
                return (UW_ERR);
-       }
-       if (asc_dvc->bus_type == ASC_IS_PCI) {
-               PCIVendorID = AscReadPCIConfigWord(asc_dvc,
-                                                  AscPCIConfigVendorIDRegister);
-
-               PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
-                                                  AscPCIConfigDeviceIDRegister);
-
-               PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
-                                                    AscPCIConfigRevisionIDRegister);
-
-               if (PCIVendorID != PCI_VENDOR_ID_ASP) {
-                       warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
-               }
-               prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
-                                                     AscPCIConfigCommandRegister);
-
-               if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
-                   AscPCICmdRegBits_IOMemBusMaster) {
-                       DvcWritePCIConfigByte(asc_dvc,
-                                             AscPCIConfigCommandRegister,
-                                             (prevCmdRegBits |
-                                              AscPCICmdRegBits_IOMemBusMaster));
-
-                       if ((DvcReadPCIConfigByte(asc_dvc,
-                                                 AscPCIConfigCommandRegister)
-                            & AscPCICmdRegBits_IOMemBusMaster)
-                           != AscPCICmdRegBits_IOMemBusMaster) {
-                               warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
-                       }
-               }
-               if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
-                   (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
-                       DvcWritePCIConfigByte(asc_dvc,
-                                             AscPCIConfigLatencyTimer, 0x00);
-                       if (DvcReadPCIConfigByte
-                           (asc_dvc, AscPCIConfigLatencyTimer)
-                           != 0x00) {
-                               warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
-                       }
-               } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
-                       if (DvcReadPCIConfigByte(asc_dvc,
-                                                AscPCIConfigLatencyTimer) <
-                           0x20) {
-                               DvcWritePCIConfigByte(asc_dvc,
-                                                     AscPCIConfigLatencyTimer,
-                                                     0x20);
-
-                               if (DvcReadPCIConfigByte(asc_dvc,
-                                                        AscPCIConfigLatencyTimer)
-                                   < 0x20) {
-                                       warn_code |=
-                                           ASC_WARN_SET_PCI_CONFIG_SPACE;
-                               }
-                       }
-               }
-       }
 
-       if (AscFindSignature(iop_base)) {
+       if (AscFindSignature(asc_dvc->iop_base)) {
                warn_code |= AscInitAscDvcVar(asc_dvc);
                warn_code |= AscInitFromEEP(asc_dvc);
                asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
-               if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
+               if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
                        asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
-               }
        } else {
                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
        }
-       return (warn_code);
+       return warn_code;
 }
 
-static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
+static unsigned short __devinit
+AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc)
 {
-       ushort warn_code = 0;
+       PortAddr iop_base = asc_dvc->iop_base;
+       unsigned short cfg_msw;
+       unsigned short warn_code = 0;
 
        asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
        if (asc_dvc->err_code != 0)
-               return (UW_ERR);
-       if (AscFindSignature(asc_dvc->iop_base)) {
-               warn_code |= AscInitFromAscDvcVar(asc_dvc);
-               asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
-       } else {
+               return UW_ERR;
+       if (!AscFindSignature(asc_dvc->iop_base)) {
                asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
+               return 0;
        }
-       return (warn_code);
-}
-
-static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
-{
-       PortAddr iop_base;
-       ushort cfg_msw;
-       ushort warn_code;
-       ushort pci_device_id = 0;
 
-       iop_base = asc_dvc->iop_base;
-#ifdef CONFIG_PCI
-       if (asc_dvc->cfg->dev)
-               pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
-#endif
-       warn_code = 0;
        cfg_msw = AscGetChipCfgMsw(iop_base);
        if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
                cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
@@ -10778,19 +10239,22 @@ static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
                        asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
                }
        }
+#ifdef CONFIG_PCI
        if (asc_dvc->bus_type & ASC_IS_PCI) {
                cfg_msw &= 0xFFC0;
                AscSetChipCfgMsw(iop_base, cfg_msw);
                if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
                } else {
-                       if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
-                           (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
+                       if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
+                           (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
                                asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
                                asc_dvc->bug_fix_cntl |=
                                    ASC_BUG_FIX_ASYN_USE_SYN;
                        }
                }
-       } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
+       } else
+#endif /* CONFIG_PCI */
+       if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
                if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
                    == ASC_CHIP_VER_ASYN_BUG) {
                        asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
@@ -10806,7 +10270,9 @@ static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
                AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
        }
 #endif /* CONFIG_ISA */
-       return (warn_code);
+
+       asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
+       return warn_code;
 }
 
 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
@@ -10846,7 +10312,7 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
        return (warn_code);
 }
 
-static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
+static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
 {
        int i;
        PortAddr iop_base;
@@ -10938,12 +10404,12 @@ static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
        }
 
        asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
-       if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
-               AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
-               asc_dvc->bus_type = ASC_IS_ISAPNP;
-       }
 #ifdef CONFIG_ISA
        if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
+               if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
+                       AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
+                       asc_dvc->bus_type = ASC_IS_ISAPNP;
+               }
                asc_dvc->cfg->isa_dma_channel =
                    (uchar)AscGetIsaDmaChannel(iop_base);
        }
@@ -10958,7 +10424,7 @@ static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
        return (warn_code);
 }
 
-static ushort __init AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
+static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
 {
        ASCEEP_CONFIG eep_config_buf;
        ASCEEP_CONFIG *eep_config;
@@ -11179,7 +10645,7 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        return (warn_code);
 }
 
-static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
+static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
 {
        PortAddr iop_base;
        ushort q_addr;
@@ -11201,7 +10667,7 @@ static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
        return (sta);
 }
 
-static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
+static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
 {
        uchar read_back;
        int retry;
@@ -11220,7 +10686,7 @@ static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
        }
 }
 
-static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
+static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
 {
        ushort read_back;
        int retry;
@@ -11239,19 +10705,19 @@ static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
        }
 }
 
-static void __init AscWaitEEPRead(void)
+static void __devinit AscWaitEEPRead(void)
 {
        DvcSleepMilliSecond(1);
        return;
 }
 
-static void __init AscWaitEEPWrite(void)
+static void __devinit AscWaitEEPWrite(void)
 {
        DvcSleepMilliSecond(20);
        return;
 }
 
-static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr)
+static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
 {
        ushort read_wval;
        uchar cmd_reg;
@@ -11266,7 +10732,7 @@ static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr)
        return (read_wval);
 }
 
-static ushort __init
+static ushort __devinit
 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
 {
        ushort read_wval;
@@ -11287,7 +10753,7 @@ AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
        return (read_wval);
 }
 
-static ushort __init
+static ushort __devinit
 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
 {
        ushort wval;
@@ -11334,7 +10800,7 @@ AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
        return (sum);
 }
 
-static int __init
+static int __devinit
 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
 {
        int n_error;
@@ -11430,7 +10896,7 @@ AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
        return (n_error);
 }
 
-static int __init
+static int __devinit
 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
 {
        int retry;
@@ -11449,107 +10915,31 @@ AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
        return (n_error);
 }
 
-static void
-AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
+static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
 {
-       uchar dvc_type;
-       ASC_SCSI_BIT_ID_TYPE tid_bits;
-
-       dvc_type = ASC_INQ_DVC_TYPE(inq);
-       tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
+       char type = sdev->type;
+       ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
 
        if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
                if (!(asc_dvc->init_sdtr & tid_bits)) {
-                       if ((dvc_type == TYPE_ROM) &&
-                           (AscCompareString((uchar *)inq->vendor_id,
-                                             (uchar *)"HP ", 3) == 0)) {
+                       if ((type == TYPE_ROM) &&
+                           (strncmp(sdev->vendor, "HP ", 3) == 0)) {
                                asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
                        }
                        asc_dvc->pci_fix_asyn_xfer |= tid_bits;
-                       if ((dvc_type == TYPE_PROCESSOR) ||
-                           (dvc_type == TYPE_SCANNER) ||
-                           (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
+                       if ((type == TYPE_PROCESSOR) ||
+                           (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
+                           (type == TYPE_TAPE)) {
                                asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
                        }
 
                        if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
                                AscSetRunChipSynRegAtID(asc_dvc->iop_base,
-                                                       tid_no,
-                                                       ASYN_SDTR_DATA_FIX_PCI_REV_AB);
-                       }
-               }
-       }
-       return;
-}
-
-static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
-{
-       if ((inq->add_len >= 32) &&
-           (AscCompareString((uchar *)inq->vendor_id,
-                             (uchar *)"QUANTUM XP34301", 15) == 0) &&
-           (AscCompareString((uchar *)inq->product_rev_level,
-                             (uchar *)"1071", 4) == 0)) {
-               return 0;
-       }
-       return 1;
-}
-
-static void
-AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
-{
-       ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
-       ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
-
-       orig_init_sdtr = asc_dvc->init_sdtr;
-       orig_use_tagged_qng = asc_dvc->use_tagged_qng;
-
-       asc_dvc->init_sdtr &= ~tid_bit;
-       asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
-       asc_dvc->use_tagged_qng &= ~tid_bit;
-
-       if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
-               if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
-                       asc_dvc->init_sdtr |= tid_bit;
-               }
-               if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
-                   ASC_INQ_CMD_QUEUE(inq)) {
-                       if (AscTagQueuingSafe(inq)) {
-                               asc_dvc->use_tagged_qng |= tid_bit;
-                               asc_dvc->cfg->can_tagged_qng |= tid_bit;
+                                       sdev->id,
+                                       ASYN_SDTR_DATA_FIX_PCI_REV_AB);
                        }
                }
        }
-       if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
-               AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
-                                asc_dvc->cfg->disc_enable);
-               AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
-                                asc_dvc->use_tagged_qng);
-               AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
-                                asc_dvc->cfg->can_tagged_qng);
-
-               asc_dvc->max_dvc_qng[tid_no] =
-                   asc_dvc->cfg->max_tag_qng[tid_no];
-               AscWriteLramByte(asc_dvc->iop_base,
-                                (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
-                                asc_dvc->max_dvc_qng[tid_no]);
-       }
-       if (orig_init_sdtr != asc_dvc->init_sdtr) {
-               AscAsyncFix(asc_dvc, tid_no, inq);
-       }
-       return;
-}
-
-static int AscCompareString(uchar *str1, uchar *str2, int len)
-{
-       int i;
-       int diff;
-
-       for (i = 0; i < len; i++) {
-               diff = (int)(str1[i] - str2[i]);
-               if (diff != 0)
-                       return (diff);
-       }
-       return (0);
 }
 
 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
@@ -13842,7 +13232,7 @@ static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL;  /* Expanded little-endian
  * on big-endian platforms so char fields read as words are actually being
  * unswapped on big-endian platforms.
  */
-static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = {
+static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
        ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
        0x0000,                 /* cfg_msw */
        0xFFFF,                 /* disc_enable */
@@ -13880,7 +13270,7 @@ static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = {
        0                       /* num_of_err */
 };
 
-static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = {
+static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
        0,                      /* cfg_lsw */
        0,                      /* cfg_msw */
        0,                      /* -disc_enable */
@@ -13918,7 +13308,7 @@ static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = {
        0                       /* num_of_err */
 };
 
-static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = {
+static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
        ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
        0x0000,                 /* 01 cfg_msw */
        0xFFFF,                 /* 02 disc_enable */
@@ -13983,7 +13373,7 @@ static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = {
        0                       /* 63 reserved */
 };
 
-static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = {
+static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
        0,                      /* 00 cfg_lsw */
        0,                      /* 01 cfg_msw */
        0,                      /* 02 disc_enable */
@@ -14048,7 +13438,7 @@ static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = {
        0                       /* 63 reserved */
 };
 
-static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = {
+static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
        ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
        0x0000,                 /* 01 cfg_msw */
        0xFFFF,                 /* 02 disc_enable */
@@ -14113,7 +13503,7 @@ static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = {
        0                       /* 63 reserved */
 };
 
-static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = {
+static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
        0,                      /* 00 cfg_lsw */
        0,                      /* 01 cfg_msw */
        0,                      /* 02 disc_enable */
@@ -14186,57 +13576,15 @@ static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = {
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
  */
-static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
+static int __devinit
+AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc)
 {
-       ushort warn_code;
-       AdvPortAddr iop_base;
-       uchar pci_cmd_reg;
+       unsigned short warn_code = 0;
+       AdvPortAddr iop_base = asc_dvc->iop_base;
+       u16 cmd;
        int status;
 
-       warn_code = 0;
        asc_dvc->err_code = 0;
-       iop_base = asc_dvc->iop_base;
-
-       /*
-        * PCI Command Register
-        *
-        * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
-        * I/O Space Control, Memory Space Control and Bus Master Control bits.
-        */
-
-       if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
-                                                   AscPCIConfigCommandRegister))
-            & AscPCICmdRegBits_BusMastering)
-           != AscPCICmdRegBits_BusMastering) {
-               pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
-
-               DvcAdvWritePCIConfigByte(asc_dvc,
-                                        AscPCIConfigCommandRegister,
-                                        pci_cmd_reg);
-
-               if (((DvcAdvReadPCIConfigByte
-                     (asc_dvc, AscPCIConfigCommandRegister))
-                    & AscPCICmdRegBits_BusMastering)
-                   != AscPCICmdRegBits_BusMastering) {
-                       warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
-               }
-       }
-
-       /*
-        * PCI Latency Timer
-        *
-        * If the "latency timer" register is 0x20 or above, then we don't need
-        * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
-        * comes up less than 0x20).
-        */
-       if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
-               DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
-                                        0x20);
-               if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
-                   0x20) {
-                       warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
-               }
-       }
 
        /*
         * Save the state of the PCI Configuration Command Register
@@ -14245,10 +13593,9 @@ static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
         * DMA parity errors.
         */
        asc_dvc->cfg->control_flag = 0;
-       if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
-             & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
+       pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+       if ((cmd & PCI_COMMAND_PARITY) == 0)
                asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
-       }
 
        asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
            ADV_LIB_VERSION_MINOR;
@@ -14290,19 +13637,11 @@ static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
                                     ADV_CTRL_REG_CMD_WR_IO_REG);
 
                if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
-                       if ((status =
-                            AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
-                               return ADV_ERROR;
-                       }
+                       status = AdvInitFrom38C1600EEP(asc_dvc);
                } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
-                       if ((status =
-                            AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
-                               return ADV_ERROR;
-                       }
+                       status = AdvInitFrom38C0800EEP(asc_dvc);
                } else {
-                       if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
-                               return ADV_ERROR;
-                       }
+                       status = AdvInitFrom3550EEP(asc_dvc);
                }
                warn_code |= status;
        }
@@ -14529,7 +13868,7 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
 
        /*
         * Microcode operating variables for WDTR, SDTR, and command tag
-        * queuing will be set in AdvInquiryHandling() based on what a
+        * queuing will be set in slave_configure() based on what a
         * device reports it is capable of in Inquiry byte 7.
         *
         * If SCSI Bus Resets have been disabled, then directly set
@@ -15180,7 +14519,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
 
        /*
         * Microcode operating variables for WDTR, SDTR, and command tag
-        * queuing will be set in AdvInquiryHandling() based on what a
+        * queuing will be set in slave_configure() based on what a
         * device reports it is capable of in Inquiry byte 7.
         *
         * If SCSI Bus Resets have been disabled, then directly set
@@ -15800,7 +15139,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
 
        /*
         * Microcode operating variables for WDTR, SDTR, and command tag
-        * queuing will be set in AdvInquiryHandling() based on what a
+        * queuing will be set in slave_configure() based on what a
         * device reports it is capable of in Inquiry byte 7.
         *
         * If SCSI Bus Resets have been disabled, then directly set
@@ -16130,7 +15469,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
  *
  * Note: Chip is stopped on entry.
  */
-static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
+static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
 {
        AdvPortAddr iop_base;
        ushort warn_code;
@@ -16284,7 +15623,7 @@ static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
  *
  * Note: Chip is stopped on entry.
  */
-static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
+static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
 {
        AdvPortAddr iop_base;
        ushort warn_code;
@@ -16487,7 +15826,7 @@ static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
  *
  * Note: Chip is stopped on entry.
  */
-static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
+static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
 {
        AdvPortAddr iop_base;
        ushort warn_code;
@@ -16728,7 +16067,7 @@ static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-static ushort __init
+static ushort __devinit
 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 {
        ushort wval, chksum;
@@ -16771,7 +16110,7 @@ AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-static ushort __init
+static ushort __devinit
 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
 {
        ushort wval, chksum;
@@ -16814,7 +16153,7 @@ AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-static ushort __init
+static ushort __devinit
 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
 {
        ushort wval, chksum;
@@ -16855,7 +16194,7 @@ AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
 /*
  * Read the EEPROM from specified location
  */
-static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
+static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
 {
        AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
                             ASC_EEP_CMD_READ | eep_word_addr);
@@ -16866,7 +16205,7 @@ static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
 /*
  * Wait for EEPROM command to complete
  */
-static void __init AdvWaitEEPCmd(AdvPortAddr iop_base)
+static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
 {
        int eep_delay_ms;
 
@@ -16887,7 +16226,7 @@ static void __init AdvWaitEEPCmd(AdvPortAddr iop_base)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __init
+void __devinit
 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -16955,7 +16294,7 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __init
+void __devinit
 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -17023,7 +16362,7 @@ AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __init
+void __devinit
 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -17483,23 +16822,6 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc)
                 */
                scsiq->cntl = 0;
 
-               /*
-                * If the command that completed was a SCSI INQUIRY and
-                * LUN 0 was sent the command, then process the INQUIRY
-                * command information for the device.
-                *
-                * Note: If data returned were either VPD or CmdDt data,
-                * don't process the INQUIRY command information for
-                * the device, otherwise may erroneously set *_able bits.
-                */
-               if (scsiq->done_status == QD_NO_ERROR &&
-                   scsiq->cdb[0] == INQUIRY &&
-                   scsiq->target_lun == 0 &&
-                   (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
-                   == ADV_INQ_RTN_STD_INQUIRY_DATA) {
-                       AdvInquiryHandling(asc_dvc, scsiq);
-               }
-
                /*
                 * Notify the driver of the completed request by passing
                 * the ADV_SCSI_REQ_Q pointer to its callback function.
@@ -17605,165 +16927,121 @@ AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
        return ADV_ERROR;
 }
 
-/*
- * Inquiry Information Byte 7 Handling
- *
- * Handle SCSI Inquiry Command information for a device by setting
- * microcode operating variables that affect WDTR, SDTR, and Tag
- * Queuing.
- */
-static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
+static int __devinit
+advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
 {
-       AdvPortAddr iop_base;
-       uchar tid;
-       ADV_SCSI_INQUIRY *inq;
-       ushort tidmask;
-       ushort cfg_word;
+       int req_cnt = 0;
+       adv_req_t *reqp = NULL;
+       int sg_cnt = 0;
+       adv_sgblk_t *sgp;
+       int warn_code, err_code;
 
        /*
-        * AdvInquiryHandling() requires up to INQUIRY information Byte 7
-        * to be available.
-        *
-        * If less than 8 bytes of INQUIRY information were requested or less
-        * than 8 bytes were transferred, then return. cdb[4] is the request
-        * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
-        * microcode to the transfer residual count.
+        * Allocate buffer carrier structures. The total size
+        * is about 4 KB, so allocate all at once.
         */
+       boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
+       ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
 
-       if (scsiq->cdb[4] < 8 ||
-           (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
-               return;
+       if (!boardp->carrp)
+               goto kmalloc_failed;
+
+       /*
+        * Allocate up to 'max_host_qng' request structures for the Wide
+        * board. The total size is about 16 KB, so allocate all at once.
+        * If the allocation fails decrement and try again.
+        */
+       for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
+               reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
+
+               ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
+                        "bytes %lu\n", reqp, req_cnt,
+                        (ulong)sizeof(adv_req_t) * req_cnt);
+
+               if (reqp)
+                       break;
        }
 
-       iop_base = asc_dvc->iop_base;
-       tid = scsiq->target_id;
+       if (!reqp)
+               goto kmalloc_failed;
 
-       inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
+       boardp->orig_reqp = reqp;
 
        /*
-        * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
+        * Allocate up to ADV_TOT_SG_BLOCK request structures for
+        * the Wide board. Each structure is about 136 bytes.
         */
-       if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
-               return;
-       } else {
-               /*
-                * INQUIRY Byte 7 Handling
-                *
-                * Use a device's INQUIRY byte 7 to determine whether it
-                * supports WDTR, SDTR, and Tag Queuing. If the feature
-                * is enabled in the EEPROM and the device supports the
-                * feature, then enable it in the microcode.
-                */
+       boardp->adv_sgblkp = NULL;
+       for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
+               sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
 
-               tidmask = ADV_TID_TO_TIDMASK(tid);
+               if (!sgp)
+                       break;
 
-               /*
-                * Wide Transfers
-                *
-                * If the EEPROM enabled WDTR for the device and the device
-                * supports wide bus (16 bit) transfers, then turn on the
-                * device's 'wdtr_able' bit and write the new value to the
-                * microcode.
-                */
-               if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
-                       AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
-                       if ((cfg_word & tidmask) == 0) {
-                               cfg_word |= tidmask;
-                               AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
-                                                cfg_word);
+               sgp->next_sgblkp = boardp->adv_sgblkp;
+               boardp->adv_sgblkp = sgp;
 
-                               /*
-                                * Clear the microcode "SDTR negotiation" and "WDTR
-                                * negotiation" done indicators for the target to cause
-                                * it to negotiate with the new setting set above.
-                                * WDTR when accepted causes the target to enter
-                                * asynchronous mode, so SDTR must be negotiated.
-                                */
-                               AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
-                                               cfg_word);
-                               cfg_word &= ~tidmask;
-                               AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
-                                                cfg_word);
-                               AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
-                                               cfg_word);
-                               cfg_word &= ~tidmask;
-                               AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
-                                                cfg_word);
-                       }
-               }
+       }
 
-               /*
-                * Synchronous Transfers
-                *
-                * If the EEPROM enabled SDTR for the device and the device
-                * supports synchronous transfers, then turn on the device's
-                * 'sdtr_able' bit. Write the new value to the microcode.
-                */
-               if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
-                       AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
-                       if ((cfg_word & tidmask) == 0) {
-                               cfg_word |= tidmask;
-                               AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
-                                                cfg_word);
+       ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
+                sg_cnt, sizeof(adv_sgblk_t),
+                (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
 
-                               /*
-                                * Clear the microcode "SDTR negotiation" done indicator
-                                * for the target to cause it to negotiate with the new
-                                * setting set above.
-                                */
-                               AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
-                                               cfg_word);
-                               cfg_word &= ~tidmask;
-                               AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
-                                                cfg_word);
-                       }
-               }
-               /*
-                * If the Inquiry data included enough space for the SPI-3
-                * Clocking field, then check if DT mode is supported.
-                */
-               if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
-                   (scsiq->cdb[4] >= 57 ||
-                    (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
-                       /*
-                        * PPR (Parallel Protocol Request) Capable
-                        *
-                        * If the device supports DT mode, then it must be PPR capable.
-                        * The PPR message will be used in place of the SDTR and WDTR
-                        * messages to negotiate synchronous speed and offset, transfer
-                        * width, and protocol options.
-                        */
-                       if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
-                               AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
-                                               asc_dvc->ppr_able);
-                               asc_dvc->ppr_able |= tidmask;
-                               AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
-                                                asc_dvc->ppr_able);
-                       }
-               }
+       if (!boardp->adv_sgblkp)
+               goto kmalloc_failed;
 
-               /*
-                * If the EEPROM enabled Tag Queuing for the device and the
-                * device supports Tag Queueing, then turn on the device's
-                * 'tagqng_enable' bit in the microcode and set the microcode
-                * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
-                * value.
-                *
-                * Tag Queuing is disabled for the BIOS which runs in polled
-                * mode and would see no benefit from Tag Queuing. Also by
-                * disabling Tag Queuing in the BIOS devices with Tag Queuing
-                * bugs will at least work with the BIOS.
-                */
-               if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
-                       AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
-                       cfg_word |= tidmask;
-                       AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
-                                        cfg_word);
+       adv_dvc_varp->carrier_buf = boardp->carrp;
 
-                       AdvWriteByteLram(iop_base,
-                                        ASC_MC_NUMBER_OF_MAX_CMD + tid,
-                                        asc_dvc->max_dvc_qng);
-               }
+       /*
+        * Point 'adv_reqp' to the request structures and
+        * link them together.
+        */
+       req_cnt--;
+       reqp[req_cnt].next_reqp = NULL;
+       for (; req_cnt > 0; req_cnt--) {
+               reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
+       }
+       boardp->adv_reqp = &reqp[0];
+
+       if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
+               ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
+               warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
+       } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
+               ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
+                          "\n");
+               warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
+       } else {
+               ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
+                          "\n");
+               warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
+       }
+       err_code = adv_dvc_varp->err_code;
+
+       if (warn_code || err_code) {
+               ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
+                          " error 0x%x\n", boardp->id, warn_code, err_code);
+       }
+
+       goto exit;
+
+ kmalloc_failed:
+       ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
+                  "failed\n", boardp->id);
+       err_code = ADV_ERROR;
+ exit:
+       return err_code;
+}
+
+static void advansys_wide_free_mem(asc_board_t *boardp)
+{
+       kfree(boardp->carrp);
+       boardp->carrp = NULL;
+       kfree(boardp->orig_reqp);
+       boardp->orig_reqp = boardp->adv_reqp = NULL;
+       while (boardp->adv_sgblkp) {
+               adv_sgblk_t *sgp = boardp->adv_sgblkp;
+               boardp->adv_sgblkp = sgp->next_sgblkp;
+               kfree(sgp);
        }
 }
 
@@ -17775,35 +17053,25 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
        asc_board_t *boardp;
        ASC_DVC_VAR *asc_dvc_varp = NULL;
        ADV_DVC_VAR *adv_dvc_varp = NULL;
-       adv_sgblk_t *sgp = NULL;
-       int share_irq = FALSE;
-       int iolen = 0;
-       ADV_PADDR pci_memory_address;
+       int share_irq;
        int warn_code, err_code;
        int ret;
 
        /*
-        * Adapter found.
-        *
         * Register the adapter, get its configuration, and
         * initialize it.
         */
-       ASC_DBG(2, "advansys_board_found: scsi_register()\n");
-       shost = scsi_register(&driver_template, sizeof(asc_board_t));
-
+       ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
+       shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
        if (!shost)
                return NULL;
 
-       /* Save a pointer to the Scsi_Host of each board found. */
-       asc_host[asc_board_count++] = shost;
-
        /* Initialize private per board data */
        boardp = ASC_BOARDP(shost);
        memset(boardp, 0, sizeof(asc_board_t));
-       boardp->id = asc_board_count - 1;
-
-       /* Initialize spinlock. */
+       boardp->id = asc_board_count++;
        spin_lock_init(&boardp->lock);
+       boardp->dev = dev;
 
        /*
         * Handle both narrow and wide boards.
@@ -17831,13 +17099,13 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                asc_dvc_varp->iop_base = iop;
                asc_dvc_varp->isr_callback = asc_isr_callback;
        } else {
+#ifdef CONFIG_PCI
                ASC_DBG(1, "advansys_board_found: wide board\n");
                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
                adv_dvc_varp->drv_ptr = boardp;
                adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
                adv_dvc_varp->isr_callback = adv_isr_callback;
                adv_dvc_varp->async_callback = adv_async_callback;
-#ifdef CONFIG_PCI
                if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
                        ASC_DBG(1, "advansys_board_found: ASC-3550\n");
                        adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
@@ -17848,50 +17116,20 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                        ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
                        adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
                }
-#endif /* CONFIG_PCI */
 
-               /*
-                * Map the board's registers into virtual memory for
-                * PCI slave access. Only memory accesses are used to
-                * access the board's registers.
-                *
-                * Note: The PCI register base address is not always
-                * page aligned, but the address passed to ioremap()
-                * must be page aligned. It is guaranteed that the
-                * PCI register base address will not cross a page
-                * boundary.
-                */
-               if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-                       iolen = ADV_3550_IOLEN;
-               } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
-                       iolen = ADV_38C0800_IOLEN;
-               } else {
-                       iolen = ADV_38C1600_IOLEN;
-               }
-#ifdef CONFIG_PCI
-               pci_memory_address = pci_resource_start(pdev, 1);
-               ASC_DBG1(1,
-                        "advansys_board_found: pci_memory_address: 0x%lx\n",
-                        (ulong)pci_memory_address);
-               if ((boardp->ioremap_addr =
-                    ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
+               boardp->asc_n_io_port = pci_resource_len(pdev, 1);
+               boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
+                                              boardp->asc_n_io_port);
+               if (!boardp->ioremap_addr) {
                        ASC_PRINT3
                            ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
-                            boardp->id, pci_memory_address, iolen);
-                       scsi_unregister(shost);
-                       asc_board_count--;
-                       return NULL;
+                            boardp->id, pci_resource_start(pdev, 1),
+                            boardp->asc_n_io_port);
+                       goto err_shost;
                }
-               ASC_DBG1(1,
-                        "advansys_board_found: ioremap_addr: 0x%lx\n",
-                        (ulong)boardp->ioremap_addr);
-               adv_dvc_varp->iop_base = (AdvPortAddr)
-                   (boardp->ioremap_addr +
-                    (pci_memory_address - (pci_memory_address & PAGE_MASK)));
-               ASC_DBG1(1,
-                        "advansys_board_found: iop_base: 0x%lx\n",
+               adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
+               ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
                         adv_dvc_varp->iop_base);
-#endif /* CONFIG_PCI */
 
                /*
                 * Even though it isn't used to access wide boards, other
@@ -17900,9 +17138,10 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                 */
                boardp->ioport = iop;
 
-               ASC_DBG2(1,
-                        "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
-                        (ushort)inp(iop + 1), (ushort)inpw(iop));
+               ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
+                        "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
+                        (ushort)inpw(iop));
+#endif /* CONFIG_PCI */
        }
 
 #ifdef CONFIG_PROC_FS
@@ -17910,18 +17149,15 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
         * Allocate buffer for printing information from
         * /proc/scsi/advansys/[0...].
         */
-       if ((boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
-               ASC_PRINT3
-                   ("advansys_board_found: board %d: kmalloc(%d, %d) returned NULL\n",
-                    boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
-               scsi_unregister(shost);
-               asc_board_count--;
-               return NULL;
+       boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
+       if (!boardp->prtbuf) {
+               ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
+                          "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
+               goto err_unmap;
        }
 #endif /* CONFIG_PROC_FS */
 
        if (ASC_NARROW_BOARD(boardp)) {
-               asc_dvc_varp->cfg->dev = dev;
                /*
                 * Set the board bus type and PCI IRQ before
                 * calling AscInitGetConfig().
@@ -17930,15 +17166,15 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 #ifdef CONFIG_ISA
                case ASC_IS_ISA:
                        shost->unchecked_isa_dma = TRUE;
-                       share_irq = FALSE;
+                       share_irq = 0;
                        break;
                case ASC_IS_VL:
                        shost->unchecked_isa_dma = FALSE;
-                       share_irq = FALSE;
+                       share_irq = 0;
                        break;
                case ASC_IS_EISA:
                        shost->unchecked_isa_dma = FALSE;
-                       share_irq = TRUE;
+                       share_irq = IRQF_SHARED;
                        break;
 #endif /* CONFIG_ISA */
 #ifdef CONFIG_PCI
@@ -17949,7 +17185,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                                         PCI_SLOT(pdev->devfn),
                                         PCI_FUNC(pdev->devfn));
                        shost->unchecked_isa_dma = FALSE;
-                       share_irq = TRUE;
+                       share_irq = IRQF_SHARED;
                        break;
 #endif /* CONFIG_PCI */
                default:
@@ -17957,11 +17193,10 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                            ("advansys_board_found: board %d: unknown adapter type: %d\n",
                             boardp->id, asc_dvc_varp->bus_type);
                        shost->unchecked_isa_dma = TRUE;
-                       share_irq = FALSE;
+                       share_irq = 0;
                        break;
                }
        } else {
-               adv_dvc_varp->cfg->dev = dev;
                /*
                 * For Wide boards set PCI information before calling
                 * AdvInitGetConfig().
@@ -17973,7 +17208,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                                 PCI_SLOT(pdev->devfn),
                                 PCI_FUNC(pdev->devfn));
                shost->unchecked_isa_dma = FALSE;
-               share_irq = TRUE;
+               share_irq = IRQF_SHARED;
 #endif /* CONFIG_PCI */
        }
 
@@ -18030,7 +17265,9 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                }
        } else {
                ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
-               if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
+
+               ret = AdvInitGetConfig(pdev, adv_dvc_varp);
+               if (ret != 0) {
                        ASC_PRINT2
                            ("AdvInitGetConfig: board %d: warning: 0x%x\n",
                             boardp->id, ret);
@@ -18042,14 +17279,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                }
        }
 
-       if (err_code != 0) {
-#ifdef CONFIG_PROC_FS
-               kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-               scsi_unregister(shost);
-               asc_board_count--;
-               return NULL;
-       }
+       if (err_code != 0)
+               goto err_free_proc;
 
        /*
         * Save the EEPROM configuration so that it can be displayed
@@ -18092,7 +17323,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                 * Modify board configuration.
                 */
                ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
-               switch (ret = AscInitSetConfig(asc_dvc_varp)) {
+               switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) {
                case 0: /* No error. */
                        break;
                case ASC_WARN_IO_PORT_ROTATE:
@@ -18131,12 +17362,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                            ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
                             boardp->id,
                             asc_dvc_varp->init_state, asc_dvc_varp->err_code);
-#ifdef CONFIG_PROC_FS
-                       kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-                       scsi_unregister(shost);
-                       asc_board_count--;
-                       return NULL;
+                       goto err_free_proc;
                }
 
                /*
@@ -18239,11 +17465,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                 */
                boardp->init_tidmask |=
                    ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
-
-               /*
-                * Finish initializing the 'Scsi_Host' structure.
-                */
-               shost->irq = adv_dvc_varp->irq_no;
        }
 
        /*
@@ -18273,7 +17494,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                 * PCI Memory Mapped I/O.
                 */
                shost->io_port = iop;
-               boardp->asc_n_io_port = iolen;
 
                shost->this_id = adv_dvc_varp->chip_scsi_id;
 
@@ -18281,15 +17501,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                shost->can_queue = adv_dvc_varp->max_host_qng;
        }
 
-       /*
-        * 'n_io_port' currently is one byte.
-        *
-        * Set a value to 'n_io_port', but never referenced it because
-        * it may be truncated.
-        */
-       shost->n_io_port = boardp->asc_n_io_port <= 255 ?
-           boardp->asc_n_io_port : 255;
-
        /*
         * Following v1.3.89, 'cmd_per_lun' is no longer needed
         * and should be set to zero.
@@ -18340,10 +17551,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 
        /* BIOS start address. */
        if (ASC_NARROW_BOARD(boardp)) {
-               shost->base = ((ulong)
-                            AscGetChipBiosAddress(asc_dvc_varp->
-                                                  iop_base,
-                                                  asc_dvc_varp->bus_type));
+               shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
+                                                   asc_dvc_varp->bus_type);
        } else {
                /*
                 * Fill-in BIOS board variables. The Wide BIOS saves
@@ -18385,30 +17594,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
         * Register Board Resources - I/O Port, DMA, IRQ
         */
 
-       /*
-        * Register I/O port range.
-        *
-        * For Wide boards the I/O ports are not used to access
-        * the board, but request the region anyway.
-        *
-        * 'shost->n_io_port' is not referenced, because it may be truncated.
-        */
-       ASC_DBG2(2,
-                "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
-                (ulong)shost->io_port, boardp->asc_n_io_port);
-       if (request_region(shost->io_port, boardp->asc_n_io_port,
-                          "advansys") == NULL) {
-               ASC_PRINT3
-                   ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
-                    boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
-#ifdef CONFIG_PROC_FS
-               kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-               scsi_unregister(shost);
-               asc_board_count--;
-               return NULL;
-       }
-
        /* Register DMA Channel for Narrow boards. */
        shost->dma_channel = NO_ISA_DMA;        /* Default to no ISA DMA. */
 #ifdef CONFIG_ISA
@@ -18416,19 +17601,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                /* Register DMA channel for ISA bus. */
                if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
                        shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
-                       if ((ret =
-                            request_dma(shost->dma_channel, "advansys")) != 0) {
+                       ret = request_dma(shost->dma_channel, "advansys");
+                       if (ret) {
                                ASC_PRINT3
                                    ("advansys_board_found: board %d: request_dma() %d failed %d\n",
                                     boardp->id, shost->dma_channel, ret);
-                               release_region(shost->io_port,
-                                              boardp->asc_n_io_port);
-#ifdef CONFIG_PROC_FS
-                               kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-                               scsi_unregister(shost);
-                               asc_board_count--;
-                               return NULL;
+                               goto err_free_proc;
                        }
                        AscEnableIsaDma(shost->dma_channel);
                }
@@ -18437,25 +17615,11 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 
        /* Register IRQ Number. */
        ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
-       /*
-        * If request_irq() fails with the IRQF_DISABLED flag set,
-        * then try again without the IRQF_DISABLED flag set. This
-        * allows IRQ sharing to work even with other drivers that
-        * do not set the IRQF_DISABLED flag.
-        *
-        * If IRQF_DISABLED is not set, then interrupts are enabled
-        * before the driver interrupt function is called.
-        */
-       if (((ret = request_irq(shost->irq, advansys_interrupt,
-                               IRQF_DISABLED | (share_irq ==
-                                                TRUE ?
-                                                IRQF_SHARED :
-                                                0), "advansys", boardp)) != 0)
-           &&
-           ((ret =
-             request_irq(shost->irq, advansys_interrupt,
-                         (share_irq == TRUE ? IRQF_SHARED : 0),
-                         "advansys", boardp)) != 0)) {
+
+       ret = request_irq(shost->irq, advansys_interrupt, share_irq,
+                         "advansys", shost);
+
+       if (ret) {
                if (ret == -EBUSY) {
                        ASC_PRINT2
                            ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
@@ -18469,17 +17633,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                            ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
                             boardp->id, shost->irq, ret);
                }
-               release_region(shost->io_port, boardp->asc_n_io_port);
-               iounmap(boardp->ioremap_addr);
-               if (shost->dma_channel != NO_ISA_DMA) {
-                       free_dma(shost->dma_channel);
-               }
-#ifdef CONFIG_PROC_FS
-               kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-               scsi_unregister(shost);
-               asc_board_count--;
-               return NULL;
+               goto err_free_dma;
        }
 
        /*
@@ -18497,512 +17651,251 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                             asc_dvc_varp->init_state, warn_code, err_code);
                }
        } else {
-               ADV_CARR_T *carrp;
-               int req_cnt = 0;
-               adv_req_t *reqp = NULL;
-               int sg_cnt = 0;
-
-               /*
-                * Allocate buffer carrier structures. The total size
-                * is about 4 KB, so allocate all at once.
-                */
-               carrp = (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
-               ASC_DBG1(1, "advansys_board_found: carrp 0x%lx\n", (ulong)carrp);
-
-               if (carrp == NULL) {
-                       goto kmalloc_error;
-               }
-
-               /*
-                * Allocate up to 'max_host_qng' request structures for
-                * the Wide board. The total size is about 16 KB, so
-                * allocate all at once. If the allocation fails decrement
-                * and try again.
-                */
-               for (req_cnt = adv_dvc_varp->max_host_qng;
-                    req_cnt > 0; req_cnt--) {
-
-                       reqp = (adv_req_t *)
-                           kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
-
-                       ASC_DBG3(1,
-                                "advansys_board_found: reqp 0x%lx, req_cnt %d, bytes %lu\n",
-                                (ulong)reqp, req_cnt,
-                                (ulong)sizeof(adv_req_t) * req_cnt);
-
-                       if (reqp != NULL) {
-                               break;
-                       }
-               }
-               if (reqp == NULL) {
-                       goto kmalloc_error;
-               }
-
-               /*
-                * Allocate up to ADV_TOT_SG_BLOCK request structures for
-                * the Wide board. Each structure is about 136 bytes.
-                */
-               boardp->adv_sgblkp = NULL;
-               for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
-
-                       sgp = (adv_sgblk_t *)
-                           kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
-
-                       if (sgp == NULL) {
-                               break;
-                       }
-
-                       sgp->next_sgblkp = boardp->adv_sgblkp;
-                       boardp->adv_sgblkp = sgp;
-
-               }
-               ASC_DBG3(1,
-                        "advansys_board_found: sg_cnt %d * %u = %u bytes\n",
-                        sg_cnt, sizeof(adv_sgblk_t),
-                        (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
-
-               /*
-                * If no request structures or scatter-gather structures could
-                * be allocated, then return an error. Otherwise continue with
-                * initialization.
-                */
- kmalloc_error:
-               if (carrp == NULL) {
-                       ASC_PRINT1
-                           ("advansys_board_found: board %d error: failed to kmalloc() carrier buffer.\n",
-                            boardp->id);
-                       err_code = ADV_ERROR;
-               } else if (reqp == NULL) {
-                       kfree(carrp);
-                       ASC_PRINT1
-                           ("advansys_board_found: board %d error: failed to kmalloc() adv_req_t buffer.\n",
-                            boardp->id);
-                       err_code = ADV_ERROR;
-               } else if (boardp->adv_sgblkp == NULL) {
-                       kfree(carrp);
-                       kfree(reqp);
-                       ASC_PRINT1
-                           ("advansys_board_found: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
-                            boardp->id);
-                       err_code = ADV_ERROR;
-               } else {
-
-                       /* Save carrier buffer pointer. */
-                       boardp->orig_carrp = carrp;
-
-                       /*
-                        * Save original pointer for kfree() in case the
-                        * driver is built as a module and can be unloaded.
-                        */
-                       boardp->orig_reqp = reqp;
-
-                       adv_dvc_varp->carrier_buf = carrp;
-
-                       /*
-                        * Point 'adv_reqp' to the request structures and
-                        * link them together.
-                        */
-                       req_cnt--;
-                       reqp[req_cnt].next_reqp = NULL;
-                       for (; req_cnt > 0; req_cnt--) {
-                               reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
-                       }
-                       boardp->adv_reqp = &reqp[0];
-
-                       if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-                               ASC_DBG(2,
-                                       "advansys_board_found: AdvInitAsc3550Driver()\n");
-                               warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
-                       } else if (adv_dvc_varp->chip_type ==
-                                  ADV_CHIP_ASC38C0800) {
-                               ASC_DBG(2,
-                                       "advansys_board_found: AdvInitAsc38C0800Driver()\n");
-                               warn_code =
-                                   AdvInitAsc38C0800Driver(adv_dvc_varp);
-                       } else {
-                               ASC_DBG(2,
-                                       "advansys_board_found: AdvInitAsc38C1600Driver()\n");
-                               warn_code =
-                                   AdvInitAsc38C1600Driver(adv_dvc_varp);
-                       }
-                       err_code = adv_dvc_varp->err_code;
-
-                       if (warn_code || err_code) {
-                               ASC_PRINT3
-                                   ("advansys_board_found: board %d error: warn 0x%x, error 0x%x\n",
-                                    boardp->id, warn_code, err_code);
-                       }
-               }
+               err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
        }
 
-       if (err_code != 0) {
-               release_region(shost->io_port, boardp->asc_n_io_port);
-               if (ASC_WIDE_BOARD(boardp)) {
-                       iounmap(boardp->ioremap_addr);
-                       kfree(boardp->orig_carrp);
-                       boardp->orig_carrp = NULL;
-                       if (boardp->orig_reqp) {
-                               kfree(boardp->orig_reqp);
-                               boardp->orig_reqp = boardp->adv_reqp = NULL;
-                       }
-                       while ((sgp = boardp->adv_sgblkp) != NULL) {
-                               boardp->adv_sgblkp = sgp->next_sgblkp;
-                               kfree(sgp);
-                       }
-               }
-               if (shost->dma_channel != NO_ISA_DMA) {
-                       free_dma(shost->dma_channel);
-               }
-#ifdef CONFIG_PROC_FS
-               kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-               free_irq(shost->irq, boardp);
-               scsi_unregister(shost);
-               asc_board_count--;
-               return NULL;
-       }
+       if (err_code != 0)
+               goto err_free_wide_mem;
+
        ASC_DBG_PRT_SCSI_HOST(2, shost);
 
+       ret = scsi_add_host(shost, dev);
+       if (ret)
+               goto err_free_wide_mem;
+
+       scsi_scan_host(shost);
        return shost;
+
+ err_free_wide_mem:
+       advansys_wide_free_mem(boardp);
+       free_irq(shost->irq, shost);
+ err_free_dma:
+       if (shost->dma_channel != NO_ISA_DMA)
+               free_dma(shost->dma_channel);
+ err_free_proc:
+       kfree(boardp->prtbuf);
+ err_unmap:
+       if (boardp->ioremap_addr)
+               iounmap(boardp->ioremap_addr);
+ err_shost:
+       scsi_host_put(shost);
+       return NULL;
 }
 
 /*
- * advansys_detect()
- *
- * Detect function for AdvanSys adapters.
- *
- * Argument is a pointer to the host driver's scsi_hosts entry.
- *
- * Return number of adapters found.
+ * advansys_release()
  *
- * Note: Because this function is called during system initialization
- * it must not call SCSI mid-level functions including scsi_malloc()
- * and scsi_free().
+ * Release resources allocated for a single AdvanSys adapter.
  */
-static int __init advansys_detect(struct scsi_host_template *tpnt)
+static int advansys_release(struct Scsi_Host *shost)
 {
-       static int detect_called = ASC_FALSE;
-       int iop;
-       int bus;
-       int ioport = 0;
-       struct device *dev = NULL;
-#ifdef CONFIG_PCI
-       int pci_init_search = 0;
-       struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
-       int pci_card_cnt_max = 0;
-       int pci_card_cnt = 0;
-       struct pci_dev *pdev = NULL;
-       int pci_device_id_cnt = 0;
-       unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
-               PCI_DEVICE_ID_ASP_1200A,
-               PCI_DEVICE_ID_ASP_ABP940,
-               PCI_DEVICE_ID_ASP_ABP940U,
-               PCI_DEVICE_ID_ASP_ABP940UW,
-               PCI_DEVICE_ID_38C0800_REV1,
-               PCI_DEVICE_ID_38C1600_REV1
-       };
-#endif /* CONFIG_PCI */
+       asc_board_t *boardp;
 
-       if (detect_called == ASC_FALSE) {
-               detect_called = ASC_TRUE;
-       } else {
-               printk
-                   ("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
-               return 0;
+       ASC_DBG(1, "advansys_release: begin\n");
+       scsi_remove_host(shost);
+       boardp = ASC_BOARDP(shost);
+       free_irq(shost->irq, shost);
+       if (shost->dma_channel != NO_ISA_DMA) {
+               ASC_DBG(1, "advansys_release: free_dma()\n");
+               free_dma(shost->dma_channel);
+       }
+       if (ASC_WIDE_BOARD(boardp)) {
+               iounmap(boardp->ioremap_addr);
+               advansys_wide_free_mem(boardp);
        }
+       kfree(boardp->prtbuf);
+       scsi_host_put(shost);
+       ASC_DBG(1, "advansys_release: end\n");
+       return 0;
+}
 
-       ASC_DBG(1, "advansys_detect: begin\n");
+static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
+       0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
+       0x0210, 0x0230, 0x0250, 0x0330
+};
 
-       asc_board_count = 0;
+static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
+{
+       PortAddr iop_base = _asc_def_iop_base[id];
+       struct Scsi_Host *shost;
 
-       /*
-        * If I/O port probing has been modified, then verify and
-        * clean-up the 'asc_ioport' list.
-        */
-       if (asc_iopflag == ASC_TRUE) {
-               for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
-                       ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
-                                ioport, asc_ioport[ioport]);
-                       if (asc_ioport[ioport] != 0) {
-                               for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX;
-                                    iop++) {
-                                       if (_asc_def_iop_base[iop] ==
-                                           asc_ioport[ioport]) {
-                                               break;
-                                       }
-                               }
-                               if (iop == ASC_IOADR_TABLE_MAX_IX) {
-                                       printk
-                                           ("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
-                                            asc_ioport[ioport]);
-                                       asc_ioport[ioport] = 0;
-                               }
-                       }
-               }
-               ioport = 0;
+       if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
+               ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
+                        iop_base);
+               return -ENODEV;
        }
+       ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
+       if (!AscFindSignature(iop_base))
+               goto nodev;
+       if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
+               goto nodev;
 
-       for (bus = 0; bus < ASC_NUM_BUS; bus++) {
+       shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
+       if (!shost)
+               goto nodev;
 
-               ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
-                        bus, asc_bus_name[bus]);
-               iop = 0;
+       dev_set_drvdata(dev, shost);
+       return 0;
 
-               while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
+ nodev:
+       release_region(iop_base, ASC_IOADR_GAP);
+       return -ENODEV;
+}
 
-                       ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
-                                asc_board_count);
+static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
+{
+       int ioport = _asc_def_iop_base[id];
+       advansys_release(dev_get_drvdata(dev));
+       release_region(ioport, ASC_IOADR_GAP);
+       return 0;
+}
 
-                       switch (asc_bus[bus]) {
-                       case ASC_IS_ISA:
-                       case ASC_IS_VL:
-#ifdef CONFIG_ISA
-                               if (asc_iopflag == ASC_FALSE) {
-                                       iop =
-                                           AscSearchIOPortAddr(iop,
-                                                               asc_bus[bus]);
-                               } else {
-                                       /*
-                                        * ISA and VL I/O port scanning has either been
-                                        * eliminated or limited to selected ports on
-                                        * the LILO command line, /etc/lilo.conf, or
-                                        * by setting variables when the module was loaded.
-                                        */
-                                       ASC_DBG(1,
-                                               "advansys_detect: I/O port scanning modified\n");
- ioport_try_again:
-                                       iop = 0;
-                                       for (; ioport < ASC_NUM_IOPORT_PROBE;
-                                            ioport++) {
-                                               if ((iop =
-                                                    asc_ioport[ioport]) != 0) {
-                                                       break;
-                                               }
-                                       }
-                                       if (iop) {
-                                               ASC_DBG1(1,
-                                                        "advansys_detect: probing I/O port 0x%x...\n",
-                                                        iop);
-                                               if (!request_region
-                                                   (iop, ASC_IOADR_GAP,
-                                                    "advansys")) {
-                                                       printk
-                                                           ("AdvanSys SCSI: specified I/O Port 0x%X is busy\n",
-                                                            iop);
-                                                       /* Don't try this I/O port twice. */
-                                                       asc_ioport[ioport] = 0;
-                                                       goto ioport_try_again;
-                                               } else if (AscFindSignature(iop)
-                                                          == ASC_FALSE) {
-                                                       printk
-                                                           ("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n",
-                                                            iop);
-                                                       /* Don't try this I/O port twice. */
-                                                       release_region(iop,
-                                                                      ASC_IOADR_GAP);
-                                                       asc_ioport[ioport] = 0;
-                                                       goto ioport_try_again;
-                                               } else {
-                                                       /*
-                                                        * If this isn't an ISA board, then it must be
-                                                        * a VL board. If currently looking an ISA
-                                                        * board is being looked for then try for
-                                                        * another ISA board in 'asc_ioport'.
-                                                        */
-                                                       if (asc_bus[bus] ==
-                                                           ASC_IS_ISA
-                                                           &&
-                                                           (AscGetChipVersion
-                                                            (iop,
-                                                             ASC_IS_ISA) &
-                                                            ASC_CHIP_VER_ISA_BIT)
-                                                           == 0) {
-                                                               /*
-                                                                * Don't clear 'asc_ioport[ioport]'. Try
-                                                                * this board again for VL. Increment
-                                                                * 'ioport' past this board.
-                                                                */
-                                                               ioport++;
-                                                               release_region
-                                                                   (iop,
-                                                                    ASC_IOADR_GAP);
-                                                               goto ioport_try_again;
-                                                       }
-                                               }
-                                               /*
-                                                * This board appears good, don't try the I/O port
-                                                * again by clearing its value. Increment 'ioport'
-                                                * for the next iteration.
-                                                */
-                                               asc_ioport[ioport++] = 0;
-                                       }
-                               }
-#endif /* CONFIG_ISA */
-                               break;
+static struct isa_driver advansys_isa_driver = {
+       .probe          = advansys_isa_probe,
+       .remove         = __devexit_p(advansys_isa_remove),
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "advansys",
+       },
+};
 
-                       case ASC_IS_EISA:
-#ifdef CONFIG_ISA
-                               iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
-#endif /* CONFIG_ISA */
-                               break;
+static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
+{
+       PortAddr iop_base = _asc_def_iop_base[id];
+       struct Scsi_Host *shost;
 
-                       case ASC_IS_PCI:
-#ifdef CONFIG_PCI
-                               if (pci_init_search == 0) {
-                                       int i, j;
-
-                                       pci_init_search = 1;
-
-                                       /* Find all PCI cards. */
-                                       while (pci_device_id_cnt <
-                                              ASC_PCI_DEVICE_ID_CNT) {
-                                               if ((pdev =
-                                                    pci_find_device
-                                                    (PCI_VENDOR_ID_ASP,
-                                                     pci_device_id
-                                                     [pci_device_id_cnt],
-                                                     pdev)) == NULL) {
-                                                       pci_device_id_cnt++;
-                                               } else {
-                                                       if (pci_enable_device
-                                                           (pdev) == 0) {
-                                                               pci_devicep
-                                                                   [pci_card_cnt_max++]
-                                                                   = pdev;
-                                                       }
-                                               }
-                                       }
+       if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
+               ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
+                        iop_base);
+               return -ENODEV;
+       }
+       ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
+       if (!AscFindSignature(iop_base))
+               goto nodev;
+       /*
+        * I don't think this condition can actually happen, but the old
+        * driver did it, and the chances of finding a VLB setup in 2007
+        * to do testing with is slight to none.
+        */
+       if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
+               goto nodev;
 
-                                       /*
-                                        * Sort PCI cards in ascending order by PCI Bus, Slot,
-                                        * and Device Number.
-                                        */
-                                       for (i = 0; i < pci_card_cnt_max - 1;
-                                            i++) {
-                                               for (j = i + 1;
-                                                    j < pci_card_cnt_max;
-                                                    j++) {
-                                                       if ((pci_devicep[j]->
-                                                            bus->number <
-                                                            pci_devicep[i]->
-                                                            bus->number)
-                                                           ||
-                                                           ((pci_devicep[j]->
-                                                             bus->number ==
-                                                             pci_devicep[i]->
-                                                             bus->number)
-                                                            &&
-                                                            (pci_devicep[j]->
-                                                             devfn <
-                                                             pci_devicep[i]->
-                                                             devfn))) {
-                                                               pdev =
-                                                                   pci_devicep
-                                                                   [i];
-                                                               pci_devicep[i] =
-                                                                   pci_devicep
-                                                                   [j];
-                                                               pci_devicep[j] =
-                                                                   pdev;
-                                                       }
-                                               }
-                                       }
+       shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
+       if (!shost)
+               goto nodev;
 
-                                       pci_card_cnt = 0;
-                               } else {
-                                       pci_card_cnt++;
-                               }
+       dev_set_drvdata(dev, shost);
+       return 0;
 
-                               if (pci_card_cnt == pci_card_cnt_max) {
-                                       iop = 0;
-                               } else {
-                                       pdev = pci_devicep[pci_card_cnt];
-
-                                       ASC_DBG2(2,
-                                                "advansys_detect: devfn %d, bus number %d\n",
-                                                pdev->devfn,
-                                                pdev->bus->number);
-                                       iop = pci_resource_start(pdev, 0);
-                                       ASC_DBG2(1,
-                                                "advansys_detect: vendorID %X, deviceID %X\n",
-                                                pdev->vendor,
-                                                pdev->device);
-                                       ASC_DBG2(2,
-                                                "advansys_detect: iop %X, irqLine %d\n",
-                                                iop, pdev->irq);
-                               }
-                               if (pdev)
-                                       dev = &pdev->dev;
+ nodev:
+       release_region(iop_base, ASC_IOADR_GAP);
+       return -ENODEV;
+}
 
-#endif /* CONFIG_PCI */
-                               break;
+static struct isa_driver advansys_vlb_driver = {
+       .probe          = advansys_vlb_probe,
+       .remove         = __devexit_p(advansys_isa_remove),
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "advansys",
+       },
+};
 
-                       default:
-                               ASC_PRINT1
-                                   ("advansys_detect: unknown bus type: %d\n",
-                                    asc_bus[bus]);
-                               break;
-                       }
-                       ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
+static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
+       { "ABP7401" },
+       { "ABP7501" },
+       { "" }
+};
 
-                       /*
-                        * Adapter not found, try next bus type.
-                        */
-                       if (iop == 0) {
-                               break;
-                       }
+MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
+
+/*
+ * EISA is a little more tricky than PCI; each EISA device may have two
+ * channels, and this driver is written to make each channel its own Scsi_Host
+ */
+struct eisa_scsi_data {
+       struct Scsi_Host *host[2];
+};
 
-                       advansys_board_found(iop, dev, asc_bus[bus]);
+static int __devinit advansys_eisa_probe(struct device *dev)
+{
+       int i, ioport;
+       int err;
+       struct eisa_device *edev = to_eisa_device(dev);
+       struct eisa_scsi_data *data;
+
+       err = -ENOMEM;
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               goto fail;
+       ioport = edev->base_addr + 0xc30;
+
+       err = -ENODEV;
+       for (i = 0; i < 2; i++, ioport += 0x20) {
+               if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
+                       printk(KERN_WARNING "Region %x-%x busy\n", ioport,
+                              ioport + ASC_IOADR_GAP - 1);
+                       continue;
                }
+               if (!AscFindSignature(ioport)) {
+                       release_region(ioport, ASC_IOADR_GAP);
+                       continue;
+               }
+
+               /*
+                * I don't know why we need to do this for EISA chips, but
+                * not for any others.  It looks to be equivalent to
+                * AscGetChipCfgMsw, but I may have overlooked something,
+                * so I'm not converting it until I get an EISA board to
+                * test with.
+                */
+               inw(ioport + 4);
+               data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
+               if (data->host[i]) {
+                       err = 0;
+               } else {
+                       release_region(ioport, ASC_IOADR_GAP);
+               }
+       }
+
+       if (err) {
+               kfree(data);
+       } else {
+               dev_set_drvdata(dev, data);
        }
 
-       ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n",
-                asc_board_count);
-       return asc_board_count;
+ fail:
+       return err;
 }
 
-/*
- * advansys_release()
- *
- * Release resources allocated for a single AdvanSys adapter.
- */
-static int advansys_release(struct Scsi_Host *shost)
+static __devexit int advansys_eisa_remove(struct device *dev)
 {
-       asc_board_t *boardp;
+       int i;
+       struct eisa_scsi_data *data = dev_get_drvdata(dev);
 
-       ASC_DBG(1, "advansys_release: begin\n");
-       boardp = ASC_BOARDP(shost);
-       free_irq(shost->irq, boardp);
-       if (shost->dma_channel != NO_ISA_DMA) {
-               ASC_DBG(1, "advansys_release: free_dma()\n");
-               free_dma(shost->dma_channel);
+       for (i = 0; i < 2; i++) {
+               int ioport;
+               struct Scsi_Host *shost = data->host[i];
+               if (!shost)
+                       continue;
+               ioport = shost->io_port;
+               advansys_release(shost);
+               release_region(ioport, ASC_IOADR_GAP);
        }
-       release_region(shost->io_port, boardp->asc_n_io_port);
-       if (ASC_WIDE_BOARD(boardp)) {
-               adv_sgblk_t *sgp = NULL;
 
-               iounmap(boardp->ioremap_addr);
-               kfree(boardp->orig_carrp);
-               boardp->orig_carrp = NULL;
-               if (boardp->orig_reqp) {
-                       kfree(boardp->orig_reqp);
-                       boardp->orig_reqp = boardp->adv_reqp = NULL;
-               }
-               while ((sgp = boardp->adv_sgblkp) != NULL) {
-                       boardp->adv_sgblkp = sgp->next_sgblkp;
-                       kfree(sgp);
-               }
-       }
-#ifdef CONFIG_PROC_FS
-       ASC_ASSERT(boardp->prtbuf != NULL);
-       kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-       scsi_unregister(shost);
-       ASC_DBG(1, "advansys_release: end\n");
+       kfree(data);
        return 0;
 }
 
-#ifdef CONFIG_PCI
+static struct eisa_driver advansys_eisa_driver = {
+       .id_table =             advansys_eisa_table,
+       .driver = {
+               .name =         "advansys",
+               .probe =        advansys_eisa_probe,
+               .remove =       __devexit_p(advansys_eisa_remove),
+       }
+};
+
 /* PCI Devices supported by this driver */
 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
        {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
@@ -19021,6 +17914,113 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
 };
 
 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
-#endif /* CONFIG_PCI */
+
+static void __devinit advansys_set_latency(struct pci_dev *pdev)
+{
+       if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) ||
+           (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) {
+               pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0);
+       } else {
+               u8 latency;
+               pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
+               if (latency < 0x20)
+                       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20);
+       }
+}
+
+static int __devinit
+advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       int err, ioport;
+       struct Scsi_Host *shost;
+
+       err = pci_enable_device(pdev);
+       if (err)
+               goto fail;
+       err = pci_request_regions(pdev, "advansys");
+       if (err)
+               goto disable_device;
+       pci_set_master(pdev);
+       advansys_set_latency(pdev);
+
+       if (pci_resource_len(pdev, 0) == 0)
+               goto nodev;
+
+       ioport = pci_resource_start(pdev, 0);
+       shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
+
+       if (!shost)
+               goto nodev;
+
+       pci_set_drvdata(pdev, shost);
+       return 0;
+
+ nodev:
+       err = -ENODEV;
+       pci_release_regions(pdev);
+ disable_device:
+       pci_disable_device(pdev);
+ fail:
+       return err;
+}
+
+static void __devexit advansys_pci_remove(struct pci_dev *pdev)
+{
+       advansys_release(pci_get_drvdata(pdev));
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+}
+
+static struct pci_driver advansys_pci_driver = {
+       .name =         "advansys",
+       .id_table =     advansys_pci_tbl,
+       .probe =        advansys_pci_probe,
+       .remove =       __devexit_p(advansys_pci_remove),
+};
+
+static int __init advansys_init(void)
+{
+       int error;
+
+       error = isa_register_driver(&advansys_isa_driver,
+                                   ASC_IOADR_TABLE_MAX_IX);
+       if (error)
+               goto fail;
+
+       error = isa_register_driver(&advansys_vlb_driver,
+                                   ASC_IOADR_TABLE_MAX_IX);
+       if (error)
+               goto unregister_isa;
+
+       error = eisa_driver_register(&advansys_eisa_driver);
+       if (error)
+               goto unregister_vlb;
+
+       error = pci_register_driver(&advansys_pci_driver);
+       if (error)
+               goto unregister_eisa;
+
+       return 0;
+
+ unregister_eisa:
+       eisa_driver_unregister(&advansys_eisa_driver);
+ unregister_vlb:
+       isa_unregister_driver(&advansys_vlb_driver);
+ unregister_isa:
+       isa_unregister_driver(&advansys_isa_driver);
+ fail:
+       return error;
+}
+
+static void __exit advansys_exit(void)
+{
+       pci_unregister_driver(&advansys_pci_driver);
+       eisa_driver_unregister(&advansys_eisa_driver);
+       isa_unregister_driver(&advansys_vlb_driver);
+       isa_unregister_driver(&advansys_isa_driver);
+}
+
+module_init(advansys_init);
+module_exit(advansys_exit);
 
 MODULE_LICENSE("GPL");