aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/gdth.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-10-02 16:49:35 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:55:20 -0400
commit706a5d456762e77e199903e55377a9c00814c007 (patch)
treebedad50e1adef5b7e00b5c2c0ba3a7b08969cad7 /drivers/scsi/gdth.c
parentaed91cb520747d08dd5cb0220d0dd3492bead220 (diff)
[SCSI] gdth: split out eisa probing
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 <hch@lst.de> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/gdth.c')
-rw-r--r--drivers/scsi/gdth.c285
1 files changed, 159 insertions, 126 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index add2ebbc2939..05108ea1d833 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -444,12 +444,10 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
444static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); 444static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp);
445static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); 445static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive);
446 446
447static int gdth_search_eisa(ushort eisa_adr);
448static int gdth_search_pci(gdth_pci_str *pcistr); 447static int gdth_search_pci(gdth_pci_str *pcistr);
449static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, 448static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
450 ushort vendor, ushort dev); 449 ushort vendor, ushort dev);
451static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); 450static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt);
452static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha);
453static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); 451static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha);
454 452
455static void gdth_enable_int(int hanum); 453static void gdth_enable_int(int hanum);
@@ -477,6 +475,9 @@ static void gdth_scsi_done(struct scsi_cmnd *scp);
477#ifdef CONFIG_ISA 475#ifdef CONFIG_ISA
478static int gdth_isa_probe_one(struct scsi_host_template *, ulong32); 476static int gdth_isa_probe_one(struct scsi_host_template *, ulong32);
479#endif 477#endif
478#ifdef CONFIG_EISA
479static int gdth_eisa_probe_one(struct scsi_host_template *, ushort);
480#endif
480 481
481#ifdef DEBUG_GDTH 482#ifdef DEBUG_GDTH
482static unchar DebugState = DEBUG_GDTH; 483static unchar DebugState = DEBUG_GDTH;
@@ -588,8 +589,9 @@ static struct timer_list gdth_timer;
588#ifdef CONFIG_ISA 589#ifdef CONFIG_ISA
589static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ 590static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */
590#endif 591#endif
591 592#ifdef CONFIG_EISA
592static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ 593static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */
594#endif
593static unchar gdth_polling; /* polling if TRUE */ 595static unchar gdth_polling; /* polling if TRUE */
594static unchar gdth_from_wait = FALSE; /* gdth_wait() */ 596static unchar gdth_from_wait = FALSE; /* gdth_wait() */
595static int wait_index,wait_hanum; /* gdth_wait() */ 597static int wait_index,wait_hanum; /* gdth_wait() */
@@ -824,7 +826,7 @@ static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs
824} 826}
825 827
826/* controller search and initialization functions */ 828/* controller search and initialization functions */
827 829#ifdef CONFIG_EISA
828static int __init gdth_search_eisa(ushort eisa_adr) 830static int __init gdth_search_eisa(ushort eisa_adr)
829{ 831{
830 ulong32 id; 832 ulong32 id;
@@ -841,6 +843,7 @@ static int __init gdth_search_eisa(ushort eisa_adr)
841 843
842 return 0; 844 return 0;
843} 845}
846#endif /* CONFIG_EISA */
844 847
845#ifdef CONFIG_ISA 848#ifdef CONFIG_ISA
846static int __init gdth_search_isa(ulong32 bios_adr) 849static int __init gdth_search_isa(ulong32 bios_adr)
@@ -975,7 +978,7 @@ static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt)
975 } while (changed); 978 } while (changed);
976} 979}
977 980
978 981#ifdef CONFIG_EISA
979static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) 982static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)
980{ 983{
981 ulong32 retries,id; 984 ulong32 retries,id;
@@ -1067,6 +1070,7 @@ static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)
1067 ha->dma64_support = 0; 1070 ha->dma64_support = 0;
1068 return 1; 1071 return 1;
1069} 1072}
1073#endif /* CONFIG_EISA */
1070 1074
1071#ifdef CONFIG_ISA 1075#ifdef CONFIG_ISA
1072static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) 1076static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
@@ -4296,7 +4300,6 @@ static int __init gdth_detect(Scsi_Host_Template *shtp)
4296 struct Scsi_Host *shp; 4300 struct Scsi_Host *shp;
4297 gdth_pci_str pcistr[MAXHA]; 4301 gdth_pci_str pcistr[MAXHA];
4298 gdth_ha_str *ha; 4302 gdth_ha_str *ha;
4299 ushort eisa_slot;
4300 int i,hanum,cnt,ctr,err; 4303 int i,hanum,cnt,ctr,err;
4301 unchar b; 4304 unchar b;
4302 4305
@@ -4341,128 +4344,16 @@ static int __init gdth_detect(Scsi_Host_Template *shtp)
4341 gdth_isa_probe_one(shtp, isa_bios); 4344 gdth_isa_probe_one(shtp, isa_bios);
4342 } 4345 }
4343#endif 4346#endif
4344 4347#ifdef CONFIG_EISA
4345 for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) { 4348 {
4346 dma_addr_t scratch_dma_handle; 4349 ushort eisa_slot;
4347 scratch_dma_handle = 0; 4350 for (eisa_slot = 0x1000; eisa_slot <= 0x8000; eisa_slot += 0x1000) {
4348 4351 if (gdth_ctr_count >= MAXHA)
4349 if (gdth_ctr_count >= MAXHA)
4350 break; 4352 break;
4351 if (gdth_search_eisa(eisa_slot)) { /* controller found */ 4353 gdth_eisa_probe_one(shtp, eisa_slot);
4352 shp = scsi_register(shtp,sizeof(gdth_ext_str));
4353 if (shp == NULL)
4354 continue;
4355
4356 ha = HADATA(shp);
4357 if (!gdth_init_eisa(eisa_slot,ha)) {
4358 scsi_unregister(shp);
4359 continue;
4360 }
4361 /* controller found and initialized */
4362 printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
4363 eisa_slot>>12,ha->irq);
4364
4365 if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) {
4366 printk("GDT-EISA: Unable to allocate IRQ\n");
4367 scsi_unregister(shp);
4368 continue;
4369 }
4370 shp->unchecked_isa_dma = 0;
4371 shp->irq = ha->irq;
4372 shp->dma_channel = 0xff;
4373 hanum = gdth_ctr_count;
4374 gdth_ctr_tab[gdth_ctr_count++] = shp;
4375 gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4376
4377 NUMDATA(shp)->hanum = (ushort)hanum;
4378 NUMDATA(shp)->busnum= 0;
4379 TRACE2(("EISA detect Bus 0: hanum %d\n",
4380 NUMDATA(shp)->hanum));
4381
4382 ha->pccb = CMDDATA(shp);
4383 ha->ccb_phys = 0L;
4384
4385 ha->pdev = NULL;
4386 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
4387 &scratch_dma_handle);
4388 ha->scratch_phys = scratch_dma_handle;
4389 ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str),
4390 &scratch_dma_handle);
4391 ha->msg_phys = scratch_dma_handle;
4392#ifdef INT_COAL
4393 ha->coal_stat = (gdth_coal_status *)
4394 pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) *
4395 MAXOFFSETS, &scratch_dma_handle);
4396 ha->coal_stat_phys = scratch_dma_handle;
4397#endif
4398 ha->ccb_phys =
4399 pci_map_single(ha->pdev,ha->pccb,
4400 sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
4401 ha->scratch_busy = FALSE;
4402 ha->req_first = NULL;
4403 ha->tid_cnt = MAX_HDRIVES;
4404 if (max_ids > 0 && max_ids < ha->tid_cnt)
4405 ha->tid_cnt = max_ids;
4406 for (i=0; i<GDTH_MAXCMDS; ++i)
4407 ha->cmd_tab[i].cmnd = UNUSED_CMND;
4408 ha->scan_mode = rescan ? 0x10 : 0;
4409
4410 if (ha->pscratch == NULL || ha->pmsg == NULL ||
4411 !gdth_search_drives(hanum)) {
4412 printk("GDT-EISA: Error during device scan\n");
4413 --gdth_ctr_count;
4414 --gdth_ctr_vcount;
4415#ifdef INT_COAL
4416 if (ha->coal_stat)
4417 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
4418 MAXOFFSETS, ha->coal_stat,
4419 ha->coal_stat_phys);
4420#endif
4421 if (ha->pscratch)
4422 pci_free_consistent(ha->pdev, GDTH_SCRATCH,
4423 ha->pscratch, ha->scratch_phys);
4424 if (ha->pmsg)
4425 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str),
4426 ha->pmsg, ha->msg_phys);
4427 if (ha->ccb_phys)
4428 pci_unmap_single(ha->pdev,ha->ccb_phys,
4429 sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
4430 free_irq(ha->irq,ha);
4431 scsi_unregister(shp);
4432 continue;
4433 }
4434 if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
4435 hdr_channel = ha->bus_cnt;
4436 ha->virt_bus = hdr_channel;
4437
4438#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \
4439 LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
4440 shp->highmem_io = 0;
4441#endif
4442 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT)
4443 shp->max_cmd_len = 16;
4444
4445 shp->max_id = ha->tid_cnt;
4446 shp->max_lun = MAXLUN;
4447 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
4448 if (virt_ctr) {
4449 virt_ctr = 1;
4450 /* register addit. SCSI channels as virtual controllers */
4451 for (b = 1; b < ha->bus_cnt + 1; ++b) {
4452 shp = scsi_register(shtp,sizeof(gdth_num_str));
4453 shp->unchecked_isa_dma = 0;
4454 shp->irq = ha->irq;
4455 shp->dma_channel = 0xff;
4456 gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
4457 NUMDATA(shp)->hanum = (ushort)hanum;
4458 NUMDATA(shp)->busnum = b;
4459 }
4460 }
4461
4462 spin_lock_init(&ha->smp_lock);
4463 gdth_enable_int(hanum);
4464 }
4465 } 4354 }
4355 }
4356#endif
4466 } 4357 }
4467 4358
4468 /* scanning for PCI controllers */ 4359 /* scanning for PCI controllers */
@@ -5701,6 +5592,148 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios)
5701} 5592}
5702#endif /* CONFIG_ISA */ 5593#endif /* CONFIG_ISA */
5703 5594
5595#ifdef CONFIG_EISA
5596static int gdth_eisa_probe_one(struct scsi_host_template *shtp,
5597 ushort eisa_slot)
5598{
5599 struct Scsi_Host *shp;
5600 gdth_ha_str *ha;
5601 dma_addr_t scratch_dma_handle = 0;
5602 int error, hanum, i;
5603 u8 b;
5604
5605 if (!gdth_search_eisa(eisa_slot))
5606 return -ENXIO;
5607
5608 shp = scsi_register(shtp,sizeof(gdth_ext_str));
5609 if (!shp)
5610 return -ENOMEM;
5611 ha = HADATA(shp);
5612
5613 error = -ENODEV;
5614 if (!gdth_init_eisa(eisa_slot,ha))
5615 goto out_host_put;
5616
5617 /* controller found and initialized */
5618 printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
5619 eisa_slot >> 12, ha->irq);
5620
5621 error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha);
5622 if (error) {
5623 printk("GDT-EISA: Unable to allocate IRQ\n");
5624 goto out_host_put;
5625 }
5626
5627 shp->unchecked_isa_dma = 0;
5628 shp->irq = ha->irq;
5629 shp->dma_channel = 0xff;
5630 hanum = gdth_ctr_count;
5631 gdth_ctr_tab[gdth_ctr_count++] = shp;
5632 gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
5633
5634 NUMDATA(shp)->hanum = (ushort)hanum;
5635 NUMDATA(shp)->busnum= 0;
5636 TRACE2(("EISA detect Bus 0: hanum %d\n",
5637 NUMDATA(shp)->hanum));
5638
5639 ha->pccb = CMDDATA(shp);
5640 ha->ccb_phys = 0L;
5641
5642 error = -ENOMEM;
5643
5644 ha->pdev = NULL;
5645 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
5646 &scratch_dma_handle);
5647 if (!ha->pscratch)
5648 goto out_free_irq;
5649 ha->scratch_phys = scratch_dma_handle;
5650
5651 ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str),
5652 &scratch_dma_handle);
5653 if (!ha->pmsg)
5654 goto out_free_pscratch;
5655 ha->msg_phys = scratch_dma_handle;
5656
5657#ifdef INT_COAL
5658 ha->coal_stat = pci_alloc_consistent(ha->pdev,
5659 sizeof(gdth_coal_status) * MAXOFFSETS,
5660 &scratch_dma_handle);
5661 if (!ha->coal_stat)
5662 goto out_free_pmsg;
5663 ha->coal_stat_phys = scratch_dma_handle;
5664#endif
5665
5666 ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb,
5667 sizeof(gdth_cmd_str), PCI_DMA_BIDIRECTIONAL);
5668 if (!ha->ccb_phys)
5669 goto out_free_coal_stat;
5670
5671 ha->scratch_busy = FALSE;
5672 ha->req_first = NULL;
5673 ha->tid_cnt = MAX_HDRIVES;
5674 if (max_ids > 0 && max_ids < ha->tid_cnt)
5675 ha->tid_cnt = max_ids;
5676 for (i = 0; i < GDTH_MAXCMDS; ++i)
5677 ha->cmd_tab[i].cmnd = UNUSED_CMND;
5678 ha->scan_mode = rescan ? 0x10 : 0;
5679
5680 if (!gdth_search_drives(hanum)) {
5681 printk("GDT-EISA: Error during device scan\n");
5682 error = -ENODEV;
5683 goto out_free_ccb_phys;
5684 }
5685
5686 if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
5687 hdr_channel = ha->bus_cnt;
5688 ha->virt_bus = hdr_channel;
5689
5690 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT)
5691 shp->max_cmd_len = 16;
5692
5693 shp->max_id = ha->tid_cnt;
5694 shp->max_lun = MAXLUN;
5695 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
5696 if (virt_ctr) {
5697 virt_ctr = 1;
5698 /* register addit. SCSI channels as virtual controllers */
5699 for (b = 1; b < ha->bus_cnt + 1; ++b) {
5700 shp = scsi_register(shtp,sizeof(gdth_num_str));
5701 shp->unchecked_isa_dma = 0;
5702 shp->irq = ha->irq;
5703 shp->dma_channel = 0xff;
5704 gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
5705 NUMDATA(shp)->hanum = (ushort)hanum;
5706 NUMDATA(shp)->busnum = b;
5707 }
5708 }
5709
5710 spin_lock_init(&ha->smp_lock);
5711 gdth_enable_int(hanum);
5712 return 0;
5713
5714 out_free_ccb_phys:
5715 pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str),
5716 PCI_DMA_BIDIRECTIONAL);
5717 out_free_coal_stat:
5718#ifdef INT_COAL
5719 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS,
5720 ha->coal_stat, ha->coal_stat_phys);
5721 out_free_pmsg:
5722#endif
5723 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str),
5724 ha->pmsg, ha->msg_phys);
5725 out_free_pscratch:
5726 pci_free_consistent(ha->pdev, GDTH_SCRATCH,
5727 ha->pscratch, ha->scratch_phys);
5728 out_free_irq:
5729 free_irq(ha->irq, ha);
5730 gdth_ctr_count--;
5731 gdth_ctr_vcount--;
5732 out_host_put:
5733 scsi_unregister(shp);
5734 return error;
5735}
5736#endif /* CONFIG_EISA */
5704 5737
5705#include "scsi_module.c" 5738#include "scsi_module.c"
5706#ifndef MODULE 5739#ifndef MODULE