aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2008-05-04 23:34:49 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-05-08 11:01:39 -0400
commit2d6f0d0cd94f9b8b24102300d8dd9cbbd1688826 (patch)
treee3149988098d59586e6170bbef7d9a140dfdb655 /drivers/scsi
parent3de2403e6659d71b36ec820dc9b942762ddfe6eb (diff)
[SCSI] gdth: fix timer handling
The global timer handling is problematic in that if someone unbinds a PCI gdth instance, the BUG_ON() in the timer will cause a panic. Fix this by making the timer start and stop depending on whether there are instances present. This should also permit binding and unbinding to work. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/gdth.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 8e2e964af66..16785a2ad03 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3724,6 +3724,8 @@ static void gdth_log_event(gdth_evt_data *dvr, char *buffer)
3724} 3724}
3725 3725
3726#ifdef GDTH_STATISTICS 3726#ifdef GDTH_STATISTICS
3727static unchar gdth_timer_running;
3728
3727static void gdth_timeout(ulong data) 3729static void gdth_timeout(ulong data)
3728{ 3730{
3729 ulong32 i; 3731 ulong32 i;
@@ -3731,7 +3733,10 @@ static void gdth_timeout(ulong data)
3731 gdth_ha_str *ha; 3733 gdth_ha_str *ha;
3732 ulong flags; 3734 ulong flags;
3733 3735
3734 BUG_ON(list_empty(&gdth_instances)); 3736 if(unlikely(list_empty(&gdth_instances))) {
3737 gdth_timer_running = 0;
3738 return;
3739 }
3735 3740
3736 ha = list_first_entry(&gdth_instances, gdth_ha_str, list); 3741 ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
3737 spin_lock_irqsave(&ha->smp_lock, flags); 3742 spin_lock_irqsave(&ha->smp_lock, flags);
@@ -3751,6 +3756,22 @@ static void gdth_timeout(ulong data)
3751 add_timer(&gdth_timer); 3756 add_timer(&gdth_timer);
3752 spin_unlock_irqrestore(&ha->smp_lock, flags); 3757 spin_unlock_irqrestore(&ha->smp_lock, flags);
3753} 3758}
3759
3760static void gdth_timer_init(void)
3761{
3762 if (gdth_timer_running)
3763 return;
3764 gdth_timer_running = 1;
3765 TRACE2(("gdth_detect(): Initializing timer !\n"));
3766 gdth_timer.expires = jiffies + HZ;
3767 gdth_timer.data = 0L;
3768 gdth_timer.function = gdth_timeout;
3769 add_timer(&gdth_timer);
3770}
3771#else
3772static inline void gdth_timer_init(void)
3773{
3774}
3754#endif 3775#endif
3755 3776
3756static void __init internal_setup(char *str,int *ints) 3777static void __init internal_setup(char *str,int *ints)
@@ -4735,6 +4756,7 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios)
4735 if (error) 4756 if (error)
4736 goto out_free_coal_stat; 4757 goto out_free_coal_stat;
4737 list_add_tail(&ha->list, &gdth_instances); 4758 list_add_tail(&ha->list, &gdth_instances);
4759 gdth_timer_init();
4738 4760
4739 scsi_scan_host(shp); 4761 scsi_scan_host(shp);
4740 4762
@@ -4865,6 +4887,7 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot)
4865 if (error) 4887 if (error)
4866 goto out_free_coal_stat; 4888 goto out_free_coal_stat;
4867 list_add_tail(&ha->list, &gdth_instances); 4889 list_add_tail(&ha->list, &gdth_instances);
4890 gdth_timer_init();
4868 4891
4869 scsi_scan_host(shp); 4892 scsi_scan_host(shp);
4870 4893
@@ -5011,6 +5034,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr,
5011 list_add_tail(&ha->list, &gdth_instances); 5034 list_add_tail(&ha->list, &gdth_instances);
5012 5035
5013 pci_set_drvdata(ha->pdev, ha); 5036 pci_set_drvdata(ha->pdev, ha);
5037 gdth_timer_init();
5014 5038
5015 scsi_scan_host(shp); 5039 scsi_scan_host(shp);
5016 5040
@@ -5110,6 +5134,7 @@ static int __init gdth_init(void)
5110 /* initializations */ 5134 /* initializations */
5111 gdth_polling = TRUE; 5135 gdth_polling = TRUE;
5112 gdth_clear_events(); 5136 gdth_clear_events();
5137 init_timer(&gdth_timer);
5113 5138
5114 /* As default we do not probe for EISA or ISA controllers */ 5139 /* As default we do not probe for EISA or ISA controllers */
5115 if (probe_eisa_isa) { 5140 if (probe_eisa_isa) {
@@ -5138,17 +5163,6 @@ static int __init gdth_init(void)
5138 5163
5139 TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); 5164 TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
5140 5165
5141 if (list_empty(&gdth_instances))
5142 return -ENODEV;
5143
5144#ifdef GDTH_STATISTICS
5145 TRACE2(("gdth_detect(): Initializing timer !\n"));
5146 init_timer(&gdth_timer);
5147 gdth_timer.expires = jiffies + HZ;
5148 gdth_timer.data = 0L;
5149 gdth_timer.function = gdth_timeout;
5150 add_timer(&gdth_timer);
5151#endif
5152 major = register_chrdev(0,"gdth", &gdth_fops); 5166 major = register_chrdev(0,"gdth", &gdth_fops);
5153 register_reboot_notifier(&gdth_notifier); 5167 register_reboot_notifier(&gdth_notifier);
5154 gdth_polling = FALSE; 5168 gdth_polling = FALSE;