/*
  * Error code values are set in ASC_DVC_VAR  'err_code'.
  */
-#define ASC_IERR_WRITE_EEPROM         0x0001
 #define ASC_IERR_MCODE_CHKSUM         0x0002
 #define ASC_IERR_SET_PC_ADDR          0x0004
 #define ASC_IERR_START_STOP_CHIP      0x0008
-#define ASC_IERR_IRQ_NO               0x0010
-#define ASC_IERR_SET_IRQ_NO           0x0020
-#define ASC_IERR_CHIP_VERSION         0x0040
 #define ASC_IERR_SET_SCSI_ID          0x0080
-#define ASC_IERR_GET_PHY_ADDR         0x0100
 #define ASC_IERR_BAD_SIGNATURE        0x0200
 #define ASC_IERR_NO_BUS_TYPE          0x0400
-#define ASC_IERR_SCAM                 0x0800
-#define ASC_IERR_SET_SDTR             0x1000
-#define ASC_IERR_RW_LRAM              0x8000
 
-#define ASC_MAX_IRQ_NO  15
-#define ASC_MIN_IRQ_NO  10
 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
 #define ASC_MIN_FREE_Q        (0x02)
        uchar max_total_qng;
        uchar cur_total_qng;
        uchar in_critical_cnt;
-       uchar irq_no;
        uchar last_q_shortage;
        ushort init_state;
        uchar cur_dvc_qng[ASC_MAX_TID + 1];
 /*
  * Error code values are set in ADV_DVC_VAR 'err_code'.
  */
-#define ASC_IERR_WRITE_EEPROM       0x0001     /* write EEPROM error */
 #define ASC_IERR_MCODE_CHKSUM       0x0002     /* micro code check sum error */
 #define ASC_IERR_NO_CARRIER         0x0004     /* No more carrier memory. */
 #define ASC_IERR_START_STOP_CHIP    0x0008     /* start/stop chip failed */
-#define ASC_IERR_CHIP_VERSION       0x0040     /* wrong chip version */
 #define ASC_IERR_SET_SCSI_ID        0x0080     /* set SCSI ID failed */
 #define ASC_IERR_HVD_DEVICE         0x0100     /* HVD attached to LVD connector. */
 #define ASC_IERR_BAD_SIGNATURE      0x0200     /* signature not found */
        uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
        uchar chip_no;          /* should be assigned by caller */
        uchar max_host_qng;     /* maximum number of Q'ed command allowed */
-       uchar irq_no;           /* IRQ number */
        ushort no_scam;         /* scam_tolerant of EEPROM */
        struct asc_board *drv_ptr;      /* driver pointer to private structure */
        uchar chip_scsi_id;     /* chip SCSI target ID */
        struct device *dev;
        int id;                 /* Board Id */
        uint flags;             /* Board flags */
+       unsigned int irq;
        union {
                ASC_DVC_VAR asc_dvc_var;        /* Narrow board */
                ADV_DVC_VAR adv_dvc_var;        /* Wide board */
               s->host_busy, s->host_no, (unsigned)s->last_reset);
 
        printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
-              (ulong)s->base, (ulong)s->io_port, s->irq);
+              (ulong)s->base, (ulong)s->io_port, boardp->irq);
 
        printk(" dma_channel %d, this_id %d, can_queue %d,\n",
               s->dma_channel, s->this_id, s->can_queue);
               (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);
+       printk(" cfg 0x%lx\n", (ulong)h->cfg);
 }
 
 /*
               (ulong)h->isr_callback, (unsigned)h->sdtr_able,
               (unsigned)h->wdtr_able);
 
-       printk("  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
-              (unsigned)h->start_motor,
-              (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
+       printk("  start_motor 0x%x, scsi_reset_wait 0x%x\n",
+              (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
 
        printk("  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
               (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
                                ASC_VERSION, busname,
                                (ulong)shost->io_port,
                                (ulong)shost->io_port + ASC_IOADR_GAP - 1,
-                               shost->irq, shost->dma_channel);
+                               boardp->irq, shost->dma_channel);
                } else {
                        if (asc_dvc_varp->bus_type & ASC_IS_VL) {
                                busname = "VL";
                                "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
                                ASC_VERSION, busname, (ulong)shost->io_port,
                                (ulong)shost->io_port + ASC_IOADR_GAP - 1,
-                               shost->irq);
+                               boardp->irq);
                }
        } else {
                /*
                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 + boardp->asc_n_io_port - 1, shost->irq);
+                       (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq);
        }
        BUG_ON(strlen(info) >= ASC_INFO_SIZE);
        ASC_DBG(1, "advansys_info: end\n");
        return AscGetChipVerNo(iop_base);
 }
 
-static void __devinit AscToggleIRQAct(PortAddr iop_base)
-{
-       AscSetChipStatus(iop_base, CIW_IRQ_ACT);
-       AscSetChipStatus(iop_base, 0);
-       return;
-}
-
-static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
-{
-       ushort cfg_lsw;
-       uchar chip_irq;
-
-       if ((bus_type & ASC_IS_EISA) != 0) {
-               cfg_lsw = AscGetEisaChipCfg(iop_base);
-               chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
-               if ((chip_irq == 13) || (chip_irq > 15)) {
-                       return (0);
-               }
-               return (chip_irq);
-       }
-       if ((bus_type & ASC_IS_VL) != 0) {
-               cfg_lsw = AscGetChipCfgLsw(iop_base);
-               chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
-               if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
-                       return (0);
-               }
-               return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
-       }
-       cfg_lsw = AscGetChipCfgLsw(iop_base);
-       chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
-       if (chip_irq == 3)
-               chip_irq += (uchar)2;
-       return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
-}
-
-static uchar __devinit
-AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
-{
-       ushort cfg_lsw;
-
-       if ((bus_type & ASC_IS_VL) != 0) {
-               if (irq_no != 0) {
-                       if ((irq_no < ASC_MIN_IRQ_NO)
-                           || (irq_no > ASC_MAX_IRQ_NO)) {
-                               irq_no = 0;
-                       } else {
-                               irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
-                       }
-               }
-               cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
-               cfg_lsw |= (ushort)0x0010;
-               AscSetChipCfgLsw(iop_base, cfg_lsw);
-               AscToggleIRQAct(iop_base);
-               cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
-               cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
-               AscSetChipCfgLsw(iop_base, cfg_lsw);
-               AscToggleIRQAct(iop_base);
-               return (AscGetChipIRQ(iop_base, bus_type));
-       }
-       if ((bus_type & (ASC_IS_ISA)) != 0) {
-               if (irq_no == 15)
-                       irq_no -= (uchar)2;
-               irq_no -= (uchar)ASC_MIN_IRQ_NO;
-               cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
-               cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
-               AscSetChipCfgLsw(iop_base, cfg_lsw);
-               return (AscGetChipIRQ(iop_base, bus_type));
-       }
-       return (0);
-}
-
 #ifdef CONFIG_ISA
 static void __devinit AscEnableIsaDma(uchar dma_channel)
 {
                eep_config->disc_enable = eep_config->use_cmd_qng;
                warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
        }
-       if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
-               asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
-       }
        ASC_EEP_SET_CHIP_ID(eep_config,
                            ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
        asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
        if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
                warn_code |= ASC_WARN_AUTO_CONFIG;
        }
-       if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
-               if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
-                   != asc_dvc->irq_no) {
-                       asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
-               }
-       }
 #ifdef CONFIG_PCI
        if (asc_dvc->bus_type & ASC_IS_PCI) {
                cfg_msw &= 0xFFC0;
        }
 }
 
-static struct Scsi_Host *__devinit
-advansys_board_found(int iop, struct device *dev, int bus_type)
+static int __devinit advansys_board_found(struct Scsi_Host *shost,
+                                         unsigned int iop, int bus_type)
 {
-       struct Scsi_Host *shost;
-       struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
+       struct pci_dev *pdev;
        asc_board_t *boardp;
        ASC_DVC_VAR *asc_dvc_varp = NULL;
        ADV_DVC_VAR *adv_dvc_varp = NULL;
-       int share_irq;
-       int warn_code, err_code;
-       int ret;
-
-       /*
-        * Register the adapter, get its configuration, and
-        * initialize it.
-        */
-       ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
-       shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
-       if (!shost)
-               return NULL;
+       int share_irq, warn_code, ret;
 
-       /* Initialize private per board data */
        boardp = ASC_BOARDP(shost);
-       memset(boardp, 0, sizeof(asc_board_t));
        boardp->id = asc_board_count++;
        spin_lock_init(&boardp->lock);
-       boardp->dev = dev;
-
-       /*
-        * Handle both narrow and wide boards.
-        *
-        * If a Wide board was detected, set the board structure
-        * wide board flag. Set-up the board structure based on
-        * the board type.
-        */
-#ifdef CONFIG_PCI
-       if (bus_type == ASC_IS_PCI &&
-           (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
-            pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
-            pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
-               boardp->flags |= ASC_IS_WIDE_BOARD;
-       }
-#endif /* CONFIG_PCI */
+       pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL;
 
        if (ASC_NARROW_BOARD(boardp)) {
                ASC_DBG(1, "advansys_board_found: narrow board\n");
                            ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
                             boardp->id, pci_resource_start(pdev, 1),
                             boardp->asc_n_io_port);
+                       ret = -ENODEV;
                        goto err_shost;
                }
                adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
        if (!boardp->prtbuf) {
                ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
                           "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
+               ret = -ENOMEM;
                goto err_unmap;
        }
 #endif /* CONFIG_PROC_FS */
 #endif /* CONFIG_ISA */
 #ifdef CONFIG_PCI
                case ASC_IS_PCI:
-                       shost->irq = asc_dvc_varp->irq_no = pdev->irq;
                        shost->unchecked_isa_dma = FALSE;
                        share_irq = IRQF_SHARED;
                        break;
                 * referenced only use the bit-wise AND operator "&".
                 */
                ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
-               err_code = AscInitGetConfig(boardp);
+               ret = AscInitGetConfig(boardp) ? -ENODEV : 0;
        } else {
 #ifdef CONFIG_PCI
                /*
                 * For Wide boards set PCI information before calling
                 * AdvInitGetConfig().
                 */
-               shost->irq = adv_dvc_varp->irq_no = pdev->irq;
                shost->unchecked_isa_dma = FALSE;
                share_irq = IRQF_SHARED;
                ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
 
-               err_code = AdvInitGetConfig(pdev, boardp);
+               ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0;
 #endif /* CONFIG_PCI */
        }
 
-       if (err_code != 0)
+       if (ret)
                goto err_free_proc;
 
        /*
                 * Modify board configuration.
                 */
                ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
-               err_code = AscInitSetConfig(pdev, boardp);
-               if (err_code)
+               ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0;
+               if (ret)
                        goto err_free_proc;
-
-               /*
-                * Finish initializing the 'Scsi_Host' structure.
-                */
-               /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
-               if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
-                       shost->irq = asc_dvc_varp->irq_no;
-               }
        } else {
                ADVEEP_3550_CONFIG *ep_3550;
                ADVEEP_38C0800_CONFIG *ep_38C0800;
 #endif /* CONFIG_ISA */
 
        /* Register IRQ Number. */
-       ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
+       ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", boardp->irq);
 
-       ret = request_irq(shost->irq, advansys_interrupt, share_irq,
+       ret = request_irq(boardp->irq, advansys_interrupt, share_irq,
                          DRV_NAME, shost);
 
        if (ret) {
                if (ret == -EBUSY) {
                        ASC_PRINT2
                            ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
-                            boardp->id, shost->irq);
+                            boardp->id, boardp->irq);
                } else if (ret == -EINVAL) {
                        ASC_PRINT2
                            ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
-                            boardp->id, shost->irq);
+                            boardp->id, boardp->irq);
                } else {
                        ASC_PRINT3
                            ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
-                            boardp->id, shost->irq, ret);
+                            boardp->id, boardp->irq, ret);
                }
                goto err_free_dma;
        }
        if (ASC_NARROW_BOARD(boardp)) {
                ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
-               err_code = asc_dvc_varp->err_code;
 
-               if (warn_code || err_code) {
-                       ASC_PRINT4
-                           ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
-                            boardp->id,
-                            asc_dvc_varp->init_state, warn_code, err_code);
+               if (warn_code || asc_dvc_varp->err_code) {
+                       ASC_PRINT4("advansys_board_found: board %d error: "
+                                  "init_state 0x%x, warn 0x%x, error 0x%x\n",
+                                  boardp->id, asc_dvc_varp->init_state,
+                                  warn_code, asc_dvc_varp->err_code);
+                       if (asc_dvc_varp->err_code)
+                               ret = -ENODEV;
                }
        } else {
-               err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
+               if (advansys_wide_init_chip(boardp, adv_dvc_varp))
+                       ret = -ENODEV;
        }
 
-       if (err_code != 0)
+       if (ret)
                goto err_free_wide_mem;
 
        ASC_DBG_PRT_SCSI_HOST(2, shost);
 
-       ret = scsi_add_host(shost, dev);
+       ret = scsi_add_host(shost, boardp->dev);
        if (ret)
                goto err_free_wide_mem;
 
        scsi_scan_host(shost);
-       return shost;
+       return 0;
 
  err_free_wide_mem:
        advansys_wide_free_mem(boardp);
-       free_irq(shost->irq, shost);
+       free_irq(boardp->irq, shost);
  err_free_dma:
        if (shost->dma_channel != NO_ISA_DMA)
                free_dma(shost->dma_channel);
        if (boardp->ioremap_addr)
                iounmap(boardp->ioremap_addr);
  err_shost:
-       scsi_host_put(shost);
-       return NULL;
+       return ret;
 }
 
 /*
        ASC_DBG(1, "advansys_release: begin\n");
        scsi_remove_host(shost);
        boardp = ASC_BOARDP(shost);
-       free_irq(shost->irq, shost);
+       free_irq(boardp->irq, shost);
        if (shost->dma_channel != NO_ISA_DMA) {
                ASC_DBG(1, "advansys_release: free_dma()\n");
                free_dma(shost->dma_channel);
        0x0210, 0x0230, 0x0250, 0x0330
 };
 
+/*
+ * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw.  It decodes as:
+ * 00: 10
+ * 01: 11
+ * 10: 12
+ * 11: 15
+ */
+static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base)
+{
+       unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
+       unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10;
+       if (chip_irq == 13)
+               chip_irq = 15;
+       return chip_irq;
+}
+
 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
 {
+       int err = -ENODEV;
        PortAddr iop_base = _asc_def_iop_base[id];
        struct Scsi_Host *shost;
+       struct asc_board *board;
 
        if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
                ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
        }
        ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
        if (!AscFindSignature(iop_base))
-               goto nodev;
+               goto release_region;
        if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
-               goto nodev;
+               goto release_region;
 
-       shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
+       err = -ENOMEM;
+       shost = scsi_host_alloc(&advansys_template, sizeof(*board));
        if (!shost)
-               goto nodev;
+               goto release_region;
+
+       board = ASC_BOARDP(shost);
+       board->irq = advansys_isa_irq_no(iop_base);
+       board->dev = dev;
+
+       err = advansys_board_found(shost, iop_base, ASC_IS_ISA);
+       if (err)
+               goto free_host;
 
        dev_set_drvdata(dev, shost);
        return 0;
 
- nodev:
+ free_host:
+       scsi_host_put(shost);
+ release_region:
        release_region(iop_base, ASC_IOADR_GAP);
-       return -ENODEV;
+       return err;
 }
 
 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
        },
 };
 
+/*
+ * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw.  It decodes as:
+ * 000: invalid
+ * 001: 10
+ * 010: 11
+ * 011: 12
+ * 100: invalid
+ * 101: 14
+ * 110: 15
+ * 111: invalid
+ */
+static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base)
+{
+       unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base);
+       unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9;
+       if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15))
+               return 0;
+       return chip_irq;
+}
+
 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
 {
+       int err = -ENODEV;
        PortAddr iop_base = _asc_def_iop_base[id];
        struct Scsi_Host *shost;
+       struct asc_board *board;
 
        if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) {
                ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
        }
        ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
        if (!AscFindSignature(iop_base))
-               goto nodev;
+               goto release_region;
        /*
         * 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;
+               goto release_region;
 
-       shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
+       err = -ENOMEM;
+       shost = scsi_host_alloc(&advansys_template, sizeof(*board));
        if (!shost)
-               goto nodev;
+               goto release_region;
+
+       board = ASC_BOARDP(shost);
+       board->irq = advansys_vlb_irq_no(iop_base);
+       board->dev = dev;
+
+       err = advansys_board_found(shost, iop_base, ASC_IS_VL);
+       if (err)
+               goto free_host;
 
        dev_set_drvdata(dev, shost);
        return 0;
 
- nodev:
+ free_host:
+       scsi_host_put(shost);
+ release_region:
        release_region(iop_base, ASC_IOADR_GAP);
        return -ENODEV;
 }
        struct Scsi_Host *host[2];
 };
 
+/*
+ * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw.  It decodes as:
+ * 000: 10
+ * 001: 11
+ * 010: 12
+ * 011: invalid
+ * 100: 14
+ * 101: 15
+ * 110: invalid
+ * 111: invalid
+ */
+static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev)
+{
+       unsigned short cfg_lsw = inw(edev->base_addr + 0xc86);
+       unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10;
+       if ((chip_irq == 13) || (chip_irq > 15))
+               return 0;
+       return chip_irq;
+}
+
 static int __devinit advansys_eisa_probe(struct device *dev)
 {
-       int i, ioport;
+       int i, ioport, irq = 0;
        int err;
        struct eisa_device *edev = to_eisa_device(dev);
        struct eisa_scsi_data *data;
 
        err = -ENODEV;
        for (i = 0; i < 2; i++, ioport += 0x20) {
+               struct asc_board *board;
+               struct Scsi_Host *shost;
                if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) {
                        printk(KERN_WARNING "Region %x-%x busy\n", ioport,
                               ioport + ASC_IOADR_GAP - 1);
                 * 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 (!irq)
+                       irq = advansys_eisa_irq_no(edev);
+
+               err = -ENOMEM;
+               shost = scsi_host_alloc(&advansys_template, sizeof(*board));
+               if (!shost)
+                       goto release_region;
+
+               board = ASC_BOARDP(shost);
+               board->irq = irq;
+               board->dev = dev;
+
+               err = advansys_board_found(shost, ioport, ASC_IS_EISA);
+               if (!err) {
+                       data->host[i] = shost;
+                       continue;
                }
-       }
 
-       if (err) {
-               kfree(data);
-       } else {
-               dev_set_drvdata(dev, data);
+               scsi_host_put(shost);
+ release_region:
+               release_region(ioport, ASC_IOADR_GAP);
+               break;
        }
 
+       if (err)
+               goto free_data;
+       dev_set_drvdata(dev, data);
+       return 0;
+
+ free_data:
+       kfree(data->host[0]);
+       kfree(data->host[1]);
+       kfree(data);
  fail:
        return err;
 }
 {
        int err, ioport;
        struct Scsi_Host *shost;
+       struct asc_board *board;
 
        err = pci_enable_device(pdev);
        if (err)
        pci_set_master(pdev);
        advansys_set_latency(pdev);
 
+       err = -ENODEV;
        if (pci_resource_len(pdev, 0) == 0)
-               goto nodev;
+               goto release_region;
 
        ioport = pci_resource_start(pdev, 0);
-       shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
 
+       err = -ENOMEM;
+       shost = scsi_host_alloc(&advansys_template, sizeof(*board));
        if (!shost)
-               goto nodev;
+               goto release_region;
+
+       board = ASC_BOARDP(shost);
+       board->irq = pdev->irq;
+       board->dev = &pdev->dev;
+
+       if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
+           pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
+           pdev->device == PCI_DEVICE_ID_38C1600_REV1) {
+               board->flags |= ASC_IS_WIDE_BOARD;
+       }
+
+       err = advansys_board_found(shost, ioport, ASC_IS_PCI);
+       if (err)
+               goto free_host;
 
        pci_set_drvdata(pdev, shost);
        return 0;
 
- nodev:
-       err = -ENODEV;
+ free_host:
+       scsi_host_put(shost);
+ release_region:
        pci_release_regions(pdev);
  disable_device:
        pci_disable_device(pdev);