X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fscsi%2Fgdth.c;h=822d5214692bfe3663b5acb8987ffec5a0ec0cd5;hb=948769a5ba304ed3329a2f42ee3561f04a0b5692;hp=c6d6e7c6559a6664008cbcf9fe75ae106577b476;hpb=e43fe686e48835ca027559a068bbe0b6d264a254;p=linux-2.6 diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index c6d6e7c655..822d521469 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -120,6 +120,7 @@ #include #include #include +#include #ifdef GDTH_RTC #include @@ -465,7 +466,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, scp->request = (struct request *)&wait; scp->timeout_per_command = timeout*HZ; scp->cmd_len = 12; - memcpy(scp->cmnd, cmnd, 12); + scp->cmnd = cmnd; cmndinfo.priority = IOCTL_PRI; cmndinfo.internal_cmd_str = gdtcmd; cmndinfo.internal_command = 1; @@ -550,7 +551,6 @@ static int __init gdth_search_isa(ulong32 bios_adr) #endif /* CONFIG_ISA */ #ifdef CONFIG_PCI -static bool gdth_pci_registered; static bool gdth_search_vortex(ushort device) { @@ -3724,6 +3724,8 @@ static void gdth_log_event(gdth_evt_data *dvr, char *buffer) } #ifdef GDTH_STATISTICS +static unchar gdth_timer_running; + static void gdth_timeout(ulong data) { ulong32 i; @@ -3731,7 +3733,10 @@ static void gdth_timeout(ulong data) gdth_ha_str *ha; ulong flags; - BUG_ON(list_empty(&gdth_instances)); + if(unlikely(list_empty(&gdth_instances))) { + gdth_timer_running = 0; + return; + } ha = list_first_entry(&gdth_instances, gdth_ha_str, list); spin_lock_irqsave(&ha->smp_lock, flags); @@ -3751,6 +3756,22 @@ static void gdth_timeout(ulong data) add_timer(&gdth_timer); spin_unlock_irqrestore(&ha->smp_lock, flags); } + +static void gdth_timer_init(void) +{ + if (gdth_timer_running) + return; + gdth_timer_running = 1; + TRACE2(("gdth_detect(): Initializing timer !\n")); + gdth_timer.expires = jiffies + HZ; + gdth_timer.data = 0L; + gdth_timer.function = gdth_timeout; + add_timer(&gdth_timer); +} +#else +static inline void gdth_timer_init(void) +{ +} #endif static void __init internal_setup(char *str,int *ints) @@ -3999,10 +4020,12 @@ static int gdth_open(struct inode *inode, struct file *filep) { gdth_ha_str *ha; + lock_kernel(); list_for_each_entry(ha, &gdth_instances, list) { if (!ha->sdev) ha->sdev = scsi_get_host_dev(ha->shost); } + unlock_kernel(); TRACE(("gdth_open()\n")); return 0; @@ -4735,6 +4758,7 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios) if (error) goto out_free_coal_stat; list_add_tail(&ha->list, &gdth_instances); + gdth_timer_init(); scsi_scan_host(shp); @@ -4865,6 +4889,7 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) if (error) goto out_free_coal_stat; list_add_tail(&ha->list, &gdth_instances); + gdth_timer_init(); scsi_scan_host(shp); @@ -5011,6 +5036,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, list_add_tail(&ha->list, &gdth_instances); pci_set_drvdata(ha->pdev, ha); + gdth_timer_init(); scsi_scan_host(shp); @@ -5110,6 +5136,7 @@ static int __init gdth_init(void) /* initializations */ gdth_polling = TRUE; gdth_clear_events(); + init_timer(&gdth_timer); /* As default we do not probe for EISA or ISA controllers */ if (probe_eisa_isa) { @@ -5132,23 +5159,17 @@ static int __init gdth_init(void) #ifdef CONFIG_PCI /* scanning for PCI controllers */ - if (pci_register_driver(&gdth_pci_driver) == 0) - gdth_pci_registered = true; + if (pci_register_driver(&gdth_pci_driver)) { + gdth_ha_str *ha; + + list_for_each_entry(ha, &gdth_instances, list) + gdth_remove_one(ha); + return -ENODEV; + } #endif /* CONFIG_PCI */ TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); - if (list_empty(&gdth_instances)) - return -ENODEV; - -#ifdef GDTH_STATISTICS - TRACE2(("gdth_detect(): Initializing timer !\n")); - init_timer(&gdth_timer); - gdth_timer.expires = jiffies + HZ; - gdth_timer.data = 0L; - gdth_timer.function = gdth_timeout; - add_timer(&gdth_timer); -#endif major = register_chrdev(0,"gdth", &gdth_fops); register_reboot_notifier(&gdth_notifier); gdth_polling = FALSE; @@ -5167,8 +5188,7 @@ static void __exit gdth_exit(void) #endif #ifdef CONFIG_PCI - if (gdth_pci_registered) - pci_unregister_driver(&gdth_pci_driver); + pci_unregister_driver(&gdth_pci_driver); #endif list_for_each_entry(ha, &gdth_instances, list)