diff options
author | Christoph Hellwig <hch@lst.de> | 2007-10-02 16:49:35 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:55:20 -0400 |
commit | 706a5d456762e77e199903e55377a9c00814c007 (patch) | |
tree | bedad50e1adef5b7e00b5c2c0ba3a7b08969cad7 /drivers/scsi | |
parent | aed91cb520747d08dd5cb0220d0dd3492bead220 (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')
-rw-r--r-- | drivers/scsi/gdth.c | 285 |
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, | |||
444 | static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); | 444 | static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); |
445 | static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); | 445 | static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); |
446 | 446 | ||
447 | static int gdth_search_eisa(ushort eisa_adr); | ||
448 | static int gdth_search_pci(gdth_pci_str *pcistr); | 447 | static int gdth_search_pci(gdth_pci_str *pcistr); |
449 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 448 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, |
450 | ushort vendor, ushort dev); | 449 | ushort vendor, ushort dev); |
451 | static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); | 450 | static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); |
452 | static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha); | ||
453 | static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); | 451 | static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); |
454 | 452 | ||
455 | static void gdth_enable_int(int hanum); | 453 | static 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 |
478 | static int gdth_isa_probe_one(struct scsi_host_template *, ulong32); | 476 | static int gdth_isa_probe_one(struct scsi_host_template *, ulong32); |
479 | #endif | 477 | #endif |
478 | #ifdef CONFIG_EISA | ||
479 | static int gdth_eisa_probe_one(struct scsi_host_template *, ushort); | ||
480 | #endif | ||
480 | 481 | ||
481 | #ifdef DEBUG_GDTH | 482 | #ifdef DEBUG_GDTH |
482 | static unchar DebugState = DEBUG_GDTH; | 483 | static unchar DebugState = DEBUG_GDTH; |
@@ -588,8 +589,9 @@ static struct timer_list gdth_timer; | |||
588 | #ifdef CONFIG_ISA | 589 | #ifdef CONFIG_ISA |
589 | static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ | 590 | static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ |
590 | #endif | 591 | #endif |
591 | 592 | #ifdef CONFIG_EISA | |
592 | static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ | 593 | static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ |
594 | #endif | ||
593 | static unchar gdth_polling; /* polling if TRUE */ | 595 | static unchar gdth_polling; /* polling if TRUE */ |
594 | static unchar gdth_from_wait = FALSE; /* gdth_wait() */ | 596 | static unchar gdth_from_wait = FALSE; /* gdth_wait() */ |
595 | static int wait_index,wait_hanum; /* gdth_wait() */ | 597 | static 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 | |
828 | static int __init gdth_search_eisa(ushort eisa_adr) | 830 | static 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 |
846 | static int __init gdth_search_isa(ulong32 bios_adr) | 849 | static 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 | |
979 | static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) | 982 | static 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 |
1072 | static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | 1076 | static 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 | ||
5596 | static 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 |