Split eisa probing into it's own helper, and do proper error unwinding.
Protect EISA probind by the proper CONFIG_EISA symbol.


Signed-off-by: Christoph Hellwig <[EMAIL PROTECTED]>

Index: linux-2.6/drivers/scsi/gdth.c
===================================================================
--- linux-2.6.orig/drivers/scsi/gdth.c  2007-07-21 12:16:55.000000000 +0200
+++ linux-2.6/drivers/scsi/gdth.c       2007-07-21 12:17:57.000000000 +0200
@@ -479,6 +479,9 @@ static void gdth_scsi_done(struct scsi_c
 #ifdef CONFIG_ISA
 static int gdth_isa_probe_one(struct scsi_host_template *, ulong32);
 #endif
+#ifdef CONFIG_EISA
+static int gdth_eisa_probe_one(struct scsi_host_template *, ushort);
+#endif
 
 #ifdef DEBUG_GDTH
 static unchar   DebugState = DEBUG_GDTH;
@@ -4335,129 +4338,14 @@ static int __init gdth_detect(Scsi_Host_
                gdth_isa_probe_one(shtp, isa_bios);
        }
 #endif
-
-        for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) {
-            dma_addr_t scratch_dma_handle;
-            scratch_dma_handle = 0;
-
-            if (gdth_ctr_count >= MAXHA) 
-                break;
-            if (gdth_search_eisa(eisa_slot)) {      /* controller found */
-                shp = scsi_register(shtp,sizeof(gdth_ext_str));
-                if (shp == NULL)
-                    continue;  
-
-                ha = HADATA(shp);
-                if (!gdth_init_eisa(eisa_slot,ha)) {
-                    scsi_unregister(shp);
-                    continue;
-                }
-                /* controller found and initialized */
-                printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
-                       eisa_slot>>12,ha->irq);
-
-                if 
(request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) {
-                    printk("GDT-EISA: Unable to allocate IRQ\n");
-                    scsi_unregister(shp);
-                    continue;
-                }
-                shp->unchecked_isa_dma = 0;
-                shp->irq = ha->irq;
-                shp->dma_channel = 0xff;
-                hanum = gdth_ctr_count;
-                gdth_ctr_tab[gdth_ctr_count++] = shp;
-                gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
-
-                NUMDATA(shp)->hanum = (ushort)hanum;
-                NUMDATA(shp)->busnum= 0;
-                TRACE2(("EISA detect Bus 0: hanum %d\n",
-                        NUMDATA(shp)->hanum));
-
-                ha->pccb = CMDDATA(shp);
-                ha->ccb_phys = 0L; 
-
-                ha->pdev = NULL;
-                ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
-                                                    &scratch_dma_handle);
-                ha->scratch_phys = scratch_dma_handle;
-                ha->pmsg = pci_alloc_consistent(ha->pdev, 
sizeof(gdth_msg_str), 
-                                                &scratch_dma_handle);
-                ha->msg_phys = scratch_dma_handle;
-#ifdef INT_COAL
-                ha->coal_stat = (gdth_coal_status *)
-                    pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) *
-                                         MAXOFFSETS, &scratch_dma_handle);
-                ha->coal_stat_phys = scratch_dma_handle;
-#endif
-                ha->ccb_phys = 
-                    pci_map_single(ha->pdev,ha->pccb,
-                                   sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-                ha->scratch_busy = FALSE;
-                ha->req_first = NULL;
-                ha->tid_cnt = MAX_HDRIVES;
-                if (max_ids > 0 && max_ids < ha->tid_cnt)
-                    ha->tid_cnt = max_ids;
-                for (i=0; i<GDTH_MAXCMDS; ++i)
-                    ha->cmd_tab[i].cmnd = UNUSED_CMND;
-                ha->scan_mode = rescan ? 0x10 : 0;
-
-                if (ha->pscratch == NULL || ha->pmsg == NULL || 
-                    !gdth_search_drives(hanum)) {
-                    printk("GDT-EISA: Error during device scan\n");
-                    --gdth_ctr_count;
-                    --gdth_ctr_vcount;
-#ifdef INT_COAL
-                    if (ha->coal_stat)
-                        pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) 
*
-                                            MAXOFFSETS, ha->coal_stat,
-                                            ha->coal_stat_phys);
-#endif
-                    if (ha->pscratch)
-                        pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
-                                            ha->pscratch, ha->scratch_phys);
-                    if (ha->pmsg)
-                        pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 
-                                            ha->pmsg, ha->msg_phys);
-                    if (ha->ccb_phys)
-                        pci_unmap_single(ha->pdev,ha->ccb_phys,
-                                        
sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-                    free_irq(ha->irq,ha);
-                    scsi_unregister(shp);
-                    continue;
-                }
-                if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
-                    hdr_channel = ha->bus_cnt;
-                ha->virt_bus = hdr_channel;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \
-    LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-                shp->highmem_io  = 0;
-#endif
-                if (ha->cache_feat & ha->raw_feat & ha->screen_feat & 
GDT_64BIT) 
-                    shp->max_cmd_len = 16;
-
-                shp->max_id      = ha->tid_cnt;
-                shp->max_lun     = MAXLUN;
-                shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
-                if (virt_ctr) {
-                    virt_ctr = 1;
-                    /* register addit. SCSI channels as virtual controllers */
-                    for (b = 1; b < ha->bus_cnt + 1; ++b) {
-                        shp = scsi_register(shtp,sizeof(gdth_num_str));
-                        shp->unchecked_isa_dma = 0;
-                        shp->irq = ha->irq;
-                        shp->dma_channel = 0xff;
-                        gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
-                        NUMDATA(shp)->hanum = (ushort)hanum;
-                        NUMDATA(shp)->busnum = b;
-                    }
-                }  
-
-                spin_lock_init(&ha->smp_lock);
-                gdth_enable_int(hanum);
-            }
-        }
+#ifdef CONFIG_EISA
+       for (eisa_slot = 0x1000; eisa_slot <= 0x8000; eisa_slot += 0x1000) {
+               if (gdth_ctr_count >= MAXHA)
+                       break;
+               gdth_eisa_probe_one(shtp, eisa_slot);
+       }
     }
+#endif
 
     /* scanning for PCI controllers */
     cnt = gdth_search_pci(pcistr);
@@ -5695,6 +5583,148 @@ static int gdth_isa_probe_one(struct scs
 }
 #endif /* CONFIG_ISA */
 
+#ifdef CONFIG_EISA
+static int gdth_eisa_probe_one(struct scsi_host_template *shtp,
+               ushort eisa_slot)
+{
+       struct Scsi_Host *shp;
+       gdth_ha_str *ha;
+       dma_addr_t scratch_dma_handle = 0;
+       int error, hanum, i;
+       u8 b;
+
+       if (!gdth_search_eisa(eisa_slot))
+               return -ENXIO;
+
+       shp = scsi_register(shtp,sizeof(gdth_ext_str));
+       if (!shp)
+               return -ENOMEM;
+       ha = HADATA(shp);
+
+       error = -ENODEV;
+       if (!gdth_init_eisa(eisa_slot,ha))
+               goto out_host_put;
+
+       /* controller found and initialized */
+       printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
+               eisa_slot >> 12, ha->irq);
+
+       error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha);
+       if (error) {
+               printk("GDT-EISA: Unable to allocate IRQ\n");
+               goto out_host_put;
+       }
+
+       shp->unchecked_isa_dma = 0;
+       shp->irq = ha->irq;
+       shp->dma_channel = 0xff;
+       hanum = gdth_ctr_count;
+       gdth_ctr_tab[gdth_ctr_count++] = shp;
+       gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
+
+       NUMDATA(shp)->hanum = (ushort)hanum;
+       NUMDATA(shp)->busnum= 0;
+       TRACE2(("EISA detect Bus 0: hanum %d\n",
+               NUMDATA(shp)->hanum));
+
+       ha->pccb = CMDDATA(shp);
+       ha->ccb_phys = 0L;
+
+       error = -ENOMEM;
+
+       ha->pdev = NULL;
+       ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
+                                               &scratch_dma_handle);
+       if (!ha->pscratch)
+               goto out_free_irq;
+       ha->scratch_phys = scratch_dma_handle;
+
+       ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str),
+                                               &scratch_dma_handle);
+       if (!ha->pmsg)
+               goto out_free_pscratch;
+       ha->msg_phys = scratch_dma_handle;
+
+#ifdef INT_COAL
+       ha->coal_stat = pci_alloc_consistent(ha->pdev,
+                       sizeof(gdth_coal_status) * MAXOFFSETS,
+                       &scratch_dma_handle);
+       if (!ha->coal_stat)
+               goto out_free_pmsg;
+       ha->coal_stat_phys = scratch_dma_handle;
+#endif
+
+       ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb,
+                       sizeof(gdth_cmd_str), PCI_DMA_BIDIRECTIONAL);
+       if (!ha->ccb_phys)
+               goto out_free_coal_stat;
+
+       ha->scratch_busy = FALSE;
+       ha->req_first = NULL;
+       ha->tid_cnt = MAX_HDRIVES;
+       if (max_ids > 0 && max_ids < ha->tid_cnt)
+               ha->tid_cnt = max_ids;
+       for (i = 0; i < GDTH_MAXCMDS; ++i)
+               ha->cmd_tab[i].cmnd = UNUSED_CMND;
+       ha->scan_mode = rescan ? 0x10 : 0;
+
+       if (!gdth_search_drives(hanum)) {
+               printk("GDT-EISA: Error during device scan\n");
+               error = -ENODEV;
+               goto out_free_ccb_phys;
+       }
+
+       if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
+               hdr_channel = ha->bus_cnt;
+       ha->virt_bus = hdr_channel;
+
+       if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT)
+               shp->max_cmd_len = 16;
+
+       shp->max_id      = ha->tid_cnt;
+       shp->max_lun     = MAXLUN;
+       shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
+       if (virt_ctr) {
+               virt_ctr = 1;
+               /* register addit. SCSI channels as virtual controllers */
+               for (b = 1; b < ha->bus_cnt + 1; ++b) {
+                       shp = scsi_register(shtp,sizeof(gdth_num_str));
+                       shp->unchecked_isa_dma = 0;
+                       shp->irq = ha->irq;
+                       shp->dma_channel = 0xff;
+                       gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
+                       NUMDATA(shp)->hanum = (ushort)hanum;
+                       NUMDATA(shp)->busnum = b;
+               }
+       }
+
+       spin_lock_init(&ha->smp_lock);
+       gdth_enable_int(hanum);
+       return 0;
+
+ out_free_ccb_phys:
+       pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str),
+                       PCI_DMA_BIDIRECTIONAL);
+ out_free_coal_stat:
+#ifdef INT_COAL
+       pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS,
+                               ha->coal_stat, ha->coal_stat_phys);
+ out_free_pmsg:
+#endif
+       pci_free_consistent(ha->pdev, sizeof(gdth_msg_str),
+                               ha->pmsg, ha->msg_phys);
+ out_free_pscratch:
+       pci_free_consistent(ha->pdev, GDTH_SCRATCH,
+                               ha->pscratch, ha->scratch_phys);
+ out_free_irq:
+       free_irq(ha->irq, ha);
+       gdth_ctr_count--;
+       gdth_ctr_vcount--;
+ out_host_put:
+       scsi_unregister(shp);
+       return error;
+}
+#endif /* CONFIG_EISA */
 
 #include "scsi_module.c"
 #ifndef MODULE
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to