]> err.no Git - linux-2.6/blobdiff - drivers/scsi/advansys.c
[SCSI] advansys: Convert to EISA driver model
[linux-2.6] / drivers / scsi / advansys.c
index 8ace30ed4186fcf302cd00417f56714532e7f205..e096f19e4dd9b23f2f618c8d4c99f3a2b3d9d67c 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/blkdev.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
@@ -865,12 +862,8 @@ typedef unsigned char uchar;
 #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)
@@ -1791,16 +1784,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
@@ -1947,8 +1934,6 @@ 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);
@@ -3422,7 +3407,7 @@ typedef struct {
 
 #define ASC_NUM_BOARD_SUPPORTED 16
 #define ASC_NUM_IOPORT_PROBE    4
-#define ASC_NUM_BUS             4
+#define ASC_NUM_BUS             2
 
 /* Reference Scsi_Host hostdata */
 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
@@ -3526,11 +3511,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,7 +3773,7 @@ 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.
  */
@@ -3825,10 +3805,8 @@ 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 */
@@ -3845,7 +3823,7 @@ typedef struct asc_board {
         */
        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,60 +3833,11 @@ 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 int asc_board_count;
+
+/* Number of boards detected by advansys_detect */
+static int asc_legacy_count;
 static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
 
 /* Overrun buffer used by all narrow boards. */
@@ -3920,12 +3849,10 @@ 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. */
+/* List of bus types probed in advansys_detect. */
 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;
@@ -3935,8 +3862,6 @@ static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
 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;
@@ -3951,7 +3876,6 @@ static PortAddr _asc_def_iop_base[];
  * 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 *);
@@ -4031,9 +3955,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 +3980,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 +3994,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,7 +4013,7 @@ 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,
@@ -4121,7 +4032,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 +4049,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 +4068,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 +4085,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,7 +4102,8 @@ 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,
@@ -4213,9 +4125,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);
@@ -4647,17 +4559,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 +4572,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 +4586,6 @@ static struct scsi_host_template driver_template = {
        .use_clustering = ENABLE_CLUSTERING,
 };
 
-#include "scsi_module.c"
-
 /*
  * --- Miscellaneous Driver Functions
  */
@@ -4696,89 +4601,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,7 +4682,7 @@ 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;
 }
 
 /*
@@ -5532,7 +5424,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 +5442,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);
 
@@ -5706,7 +5581,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 +5616,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);
 
@@ -7514,7 +7368,7 @@ DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
 /*
  * Read a PCI configuration byte.
  */
-static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
+static uchar __devinit DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
 {
 #ifdef CONFIG_PCI
        uchar byte_data;
@@ -7528,7 +7382,7 @@ static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
 /*
  * Write a PCI configuration byte.
  */
-static void __init
+static void __devinit
 DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
 {
 #ifdef CONFIG_PCI
@@ -7540,7 +7394,7 @@ DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
  * 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 ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
 {
        ushort cfg_lsw;
        ushort bios_addr;
@@ -7611,7 +7465,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)
+static uchar __devinit DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
 {
 #ifdef CONFIG_PCI
        uchar byte_data;
@@ -7625,7 +7479,7 @@ static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
 /*
  * Write a PCI configuration byte.
  */
-static void __init
+static void __devinit
 DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
 {
 #ifdef CONFIG_PCI
@@ -8221,7 +8075,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 +8084,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,7 +8098,7 @@ static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
        return (AscGetChipScsiID(iop_base));
 }
 
-static uchar __init AscGetChipScsiCtrl(PortAddr iop_base)
+static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base)
 {
        uchar sc;
 
@@ -8254,7 +8108,7 @@ static uchar __init AscGetChipScsiCtrl(PortAddr iop_base)
        return (sc);
 }
 
-static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type)
+static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type)
 {
        if ((bus_type & ASC_IS_EISA) != 0) {
                PortAddr eisa_iop;
@@ -8267,7 +8121,7 @@ static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type)
        return (AscGetChipVerNo(iop_base));
 }
 
-static ushort __init AscGetChipBusType(PortAddr iop_base)
+static ushort __devinit AscGetChipBusType(PortAddr iop_base)
 {
        ushort chip_ver;
 
@@ -8374,12 +8228,6 @@ static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type)
                }
                return (0);
        }
-       if (bus_type & ASC_IS_EISA) {
-               if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
-                       return (iop_beg);
-               }
-               return (0);
-       }
        return (0);
 }
 
@@ -8419,14 +8267,14 @@ static void __init AscSetISAPNPWaitForKey(void)
 }
 #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 +8302,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 +8339,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));
@@ -10389,57 +10237,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 +10370,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 +10380,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 +10392,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 +10410,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 +10419,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,7 +10431,7 @@ static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base)
 }
 #endif /* CONFIG_ISA */
 
-static ushort __init
+static ushort __devinit
 AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
 {
        uchar lsb, msb;
@@ -10644,7 +10441,7 @@ AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
        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;
@@ -10729,7 +10526,7 @@ static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
        return (warn_code);
 }
 
-static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
+static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
 {
        ushort warn_code = 0;
 
@@ -10745,7 +10542,7 @@ static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
        return (warn_code);
 }
 
-static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
+static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
 {
        PortAddr iop_base;
        ushort cfg_msw;
@@ -10846,7 +10643,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;
@@ -10958,7 +10755,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 +10976,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 +10998,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 +11017,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 +11036,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 +11063,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 +11084,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 +11131,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 +11227,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;
@@ -13842,7 +13639,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 +13677,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 +13715,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 +13780,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 +13845,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 +13910,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,7 +13983,7 @@ 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(ADV_DVC_VAR *asc_dvc)
 {
        ushort warn_code;
        AdvPortAddr iop_base;
@@ -16130,7 +15927,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 +16081,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 +16284,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 +16525,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 +16568,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 +16611,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 +16652,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 +16663,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 +16684,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 +16752,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 +16820,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;
@@ -17767,6 +17564,124 @@ 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)
+{
+       int req_cnt = 0;
+       adv_req_t *reqp = NULL;
+       int sg_cnt = 0;
+       adv_sgblk_t *sgp;
+       int warn_code, err_code;
+
+       /*
+        * 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 (!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;
+       }
+
+       if (!reqp)
+               goto kmalloc_failed;
+
+       boardp->orig_reqp = reqp;
+
+       /*
+        * 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 = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
+
+               if (!sgp)
+                       break;
+
+               sgp->next_sgblkp = boardp->adv_sgblkp;
+               boardp->adv_sgblkp = sgp;
+
+       }
+
+       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));
+
+       if (!boardp->adv_sgblkp)
+               goto kmalloc_failed;
+
+       adv_dvc_varp->carrier_buf = boardp->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_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);
+       }
+}
+
 static struct Scsi_Host *__devinit
 advansys_board_found(int iop, struct device *dev, int bus_type)
 {
@@ -17775,8 +17690,7 @@ 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 share_irq;
        int iolen = 0;
        ADV_PADDR pci_memory_address;
        int warn_code, err_code;
@@ -17788,19 +17702,16 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
         * 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;
+       boardp->id = asc_board_count++;
 
        /* Initialize spinlock. */
        spin_lock_init(&boardp->lock);
@@ -17878,9 +17789,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                        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;
+                       goto err_shost;
                }
                ASC_DBG1(1,
                         "advansys_board_found: ioremap_addr: 0x%lx\n",
@@ -17910,13 +17819,11 @@ 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 */
 
@@ -17930,15 +17837,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 +17856,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,7 +17864,7 @@ 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 {
@@ -17973,7 +17880,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 */
        }
 
@@ -18042,14 +17949,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
@@ -18131,12 +18032,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;
                }
 
                /*
@@ -18340,10 +18236,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
@@ -18401,12 +18295,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
                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;
+               goto err_free_proc;
        }
 
        /* Register DMA Channel for Narrow boards. */
@@ -18416,19 +18305,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_region;
                        }
                        AscEnableIsaDma(shost->dma_channel);
                }
@@ -18437,25 +18319,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 +18337,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,173 +18355,37 @@ 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_region:
+       release_region(shost->io_port, boardp->asc_n_io_port);
+ err_free_proc:
+       kfree(boardp->prtbuf);
+ err_unmap:
+       if (boardp->ioremap_addr)
+               iounmap(boardp->ioremap_addr);
+ err_shost:
+       scsi_host_put(shost);
+       return NULL;
 }
 
 /*
@@ -18679,41 +18401,16 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
  * it must not call SCSI mid-level functions including scsi_malloc()
  * and scsi_free().
  */
-static int __init advansys_detect(struct scsi_host_template *tpnt)
+static int __init advansys_detect(void)
 {
-       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 */
-
-       if (detect_called == ASC_FALSE) {
-               detect_called = ASC_TRUE;
-       } else {
-               printk
-                   ("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
-               return 0;
-       }
+       struct Scsi_Host *shost;
 
        ASC_DBG(1, "advansys_detect: begin\n");
 
-       asc_board_count = 0;
+       asc_legacy_count = 0;
 
        /*
         * If I/O port probing has been modified, then verify and
@@ -18748,10 +18445,10 @@ static int __init advansys_detect(struct scsi_host_template *tpnt)
                         bus, asc_bus_name[bus]);
                iop = 0;
 
-               while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
+               while (asc_legacy_count < ASC_NUM_BOARD_SUPPORTED) {
 
-                       ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
-                                asc_board_count);
+                       ASC_DBG1(2, "advansys_detect: asc_legacy_count %d\n",
+                                asc_legacy_count);
 
                        switch (asc_bus[bus]) {
                        case ASC_IS_ISA:
@@ -18840,103 +18537,6 @@ static int __init advansys_detect(struct scsi_host_template *tpnt)
 #endif /* CONFIG_ISA */
                                break;
 
-                       case ASC_IS_EISA:
-#ifdef CONFIG_ISA
-                               iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
-#endif /* CONFIG_ISA */
-                               break;
-
-                       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;
-                                                       }
-                                               }
-                                       }
-
-                                       /*
-                                        * 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;
-                                                       }
-                                               }
-                                       }
-
-                                       pci_card_cnt = 0;
-                               } else {
-                                       pci_card_cnt++;
-                               }
-
-                               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;
-
-#endif /* CONFIG_PCI */
-                               break;
-
                        default:
                                ASC_PRINT1
                                    ("advansys_detect: unknown bus type: %d\n",
@@ -18948,17 +18548,19 @@ static int __init advansys_detect(struct scsi_host_template *tpnt)
                        /*
                         * Adapter not found, try next bus type.
                         */
-                       if (iop == 0) {
+                       if (iop == 0)
                                break;
-                       }
 
-                       advansys_board_found(iop, dev, asc_bus[bus]);
+                       shost = advansys_board_found(iop, NULL, asc_bus[bus]);
+                       if (shost) {
+                               asc_host[asc_legacy_count++] = shost;
+                       }
                }
        }
 
-       ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n",
-                asc_board_count);
-       return asc_board_count;
+       ASC_DBG1(1, "advansys_detect: done: asc_legacy_count %d\n",
+                asc_legacy_count);
+       return asc_legacy_count;
 }
 
 /*
@@ -18971,38 +18573,105 @@ static int advansys_release(struct Scsi_Host *shost)
        asc_board_t *boardp;
 
        ASC_DBG(1, "advansys_release: begin\n");
+       scsi_remove_host(shost);
        boardp = ASC_BOARDP(shost);
-       free_irq(shost->irq, boardp);
+       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);
        }
        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);
-               }
+               advansys_wide_free_mem(boardp);
        }
-#ifdef CONFIG_PROC_FS
-       ASC_ASSERT(boardp->prtbuf != NULL);
        kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-       scsi_unregister(shost);
+       scsi_host_put(shost);
        ASC_DBG(1, "advansys_release: end\n");
        return 0;
 }
 
-#ifdef CONFIG_PCI
+static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
+       { "ABP7401" },
+       { "ABP7501" },
+       { "" }
+};
+
+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];
+};
+
+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 (!AscFindSignature(ioport))
+                       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;
+       }
+
+       if (err) {
+               kfree(data);
+       } else {
+               dev_set_drvdata(dev, data);
+       }
+
+ fail:
+       return err;
+}
+
+static __devexit int advansys_eisa_remove(struct device *dev)
+{
+       int i;
+       struct eisa_scsi_data *data = dev_get_drvdata(dev);
+
+       for (i = 0; i < 2; i++) {
+               struct Scsi_Host *shost = data->host[i];
+               if (!shost)
+                       continue;
+               advansys_release(shost);
+       }
+
+       kfree(data);
+       return 0;
+}
+
+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 +18690,85 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
 };
 
 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
-#endif /* CONFIG_PCI */
+
+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;
+
+       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_disable_device(pdev);
+ fail:
+       return err;
+}
+
+static void __devexit advansys_pci_remove(struct pci_dev *pdev)
+{
+       advansys_release(pci_get_drvdata(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 i, error;
+       advansys_detect();
+
+       error = eisa_driver_register(&advansys_eisa_driver);
+       if (error)
+               goto fail;
+
+       error = pci_register_driver(&advansys_pci_driver);
+       if (error)
+               goto unregister_eisa;
+
+       return 0;
+
+ unregister_eisa:
+       eisa_driver_unregister(&advansys_eisa_driver);
+ fail:
+       for (i = 0; i < asc_legacy_count; i++)
+               advansys_release(asc_host[i]);
+
+       return error;
+}
+
+static void __exit advansys_exit(void)
+{
+       int i;
+
+       pci_unregister_driver(&advansys_pci_driver);
+       eisa_driver_unregister(&advansys_eisa_driver);
+
+       for (i = 0; i < asc_legacy_count; i++)
+               advansys_release(asc_host[i]);
+}
+
+module_init(advansys_init);
+module_exit(advansys_exit);
 
 MODULE_LICENSE("GPL");