[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>

+26 -12
+26 -12
drivers/scsi/gdth.c
··· 3724 3724 } 3725 3725 3726 3726 #ifdef GDTH_STATISTICS 3727 + static unchar gdth_timer_running; 3728 + 3727 3729 static void gdth_timeout(ulong data) 3728 3730 { 3729 3731 ulong32 i; ··· 3733 3731 gdth_ha_str *ha; 3734 3732 ulong flags; 3735 3733 3736 - BUG_ON(list_empty(&gdth_instances)); 3734 + if(unlikely(list_empty(&gdth_instances))) { 3735 + gdth_timer_running = 0; 3736 + return; 3737 + } 3737 3738 3738 3739 ha = list_first_entry(&gdth_instances, gdth_ha_str, list); 3739 3740 spin_lock_irqsave(&ha->smp_lock, flags); ··· 3755 3750 gdth_timer.expires = jiffies + 30 * HZ; 3756 3751 add_timer(&gdth_timer); 3757 3752 spin_unlock_irqrestore(&ha->smp_lock, flags); 3753 + } 3754 + 3755 + static void gdth_timer_init(void) 3756 + { 3757 + if (gdth_timer_running) 3758 + return; 3759 + gdth_timer_running = 1; 3760 + TRACE2(("gdth_detect(): Initializing timer !\n")); 3761 + gdth_timer.expires = jiffies + HZ; 3762 + gdth_timer.data = 0L; 3763 + gdth_timer.function = gdth_timeout; 3764 + add_timer(&gdth_timer); 3765 + } 3766 + #else 3767 + static inline void gdth_timer_init(void) 3768 + { 3758 3769 } 3759 3770 #endif 3760 3771 ··· 4756 4735 if (error) 4757 4736 goto out_free_coal_stat; 4758 4737 list_add_tail(&ha->list, &gdth_instances); 4738 + gdth_timer_init(); 4759 4739 4760 4740 scsi_scan_host(shp); 4761 4741 ··· 4887 4865 if (error) 4888 4866 goto out_free_coal_stat; 4889 4867 list_add_tail(&ha->list, &gdth_instances); 4868 + gdth_timer_init(); 4890 4869 4891 4870 scsi_scan_host(shp); 4892 4871 ··· 5034 5011 list_add_tail(&ha->list, &gdth_instances); 5035 5012 5036 5013 pci_set_drvdata(ha->pdev, ha); 5014 + gdth_timer_init(); 5037 5015 5038 5016 scsi_scan_host(shp); 5039 5017 ··· 5134 5110 /* initializations */ 5135 5111 gdth_polling = TRUE; 5136 5112 gdth_clear_events(); 5113 + init_timer(&gdth_timer); 5137 5114 5138 5115 /* As default we do not probe for EISA or ISA controllers */ 5139 5116 if (probe_eisa_isa) { ··· 5163 5138 5164 5139 TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); 5165 5140 5166 - if (list_empty(&gdth_instances)) 5167 - return -ENODEV; 5168 - 5169 - #ifdef GDTH_STATISTICS 5170 - TRACE2(("gdth_detect(): Initializing timer !\n")); 5171 - init_timer(&gdth_timer); 5172 - gdth_timer.expires = jiffies + HZ; 5173 - gdth_timer.data = 0L; 5174 - gdth_timer.function = gdth_timeout; 5175 - add_timer(&gdth_timer); 5176 - #endif 5177 5141 major = register_chrdev(0,"gdth", &gdth_fops); 5178 5142 register_reboot_notifier(&gdth_notifier); 5179 5143 gdth_polling = FALSE;