sym53c8xx reboot notifier and minor nits
PATCH 1/1 sym53c8xx reboot notifier and minor nits
Gerard and all,
This patch adds areboot notifier to the sym53c8xx driver, and fixes a couple minor issues. The host list is now spinlocked, and the unmap pci_mem (which icalled by a non-init function) is now non-init.
Please let me know if there are any problems with this patch for general inclusion. (reboot notifier by asun)
Tim
Signature · 4 lines
Tim Hockin Systems Software Engineer Sun Microsystems, Cobalt Server Appliances [email protected]
drivers/scsi/sym53c8xx.c +57 -11
@@ -113,6 +113,8 @@#elif LINUX_VERSION_CODE >=LinuxVersionCode (2 ,1 ,93 )#include <asm/spinlock.h> #endif +#include <linux/notifier.h> +#include <linux/reboot.h> #include <linux/delay.h> #include <linux/signal.h> #include <linux/sched.h>
@@ -634,8 +636,11 @@#if LINUX_VERSION_CODE >=LinuxVersionCode (2 ,1 ,93 )spinlock_t sym53c8xx_lock =SPIN_LOCK_UNLOCKED ; +spinlock_t sym53c8xx_host_lock =SPIN_LOCK_UNLOCKED ;#define NCR_LOCK_DRIVER (flags) spin_lock_irqsave(&sym53c8xx_lock, flags)#define NCR_UNLOCK_DRIVER (flags) spin_unlock_irqrestore(&sym53c8xx_lock,flags) +#define NCR_LOCK_HOSTS (flags) spin_lock_irqsave(&sym53c8xx_host_lock, flags) +#define NCR_UNLOCK_HOSTS (flags) spin_unlock_irqrestore(&sym53c8xx_host_lock,flags)#define NCR_INIT_LOCK_NCB (np) spin_lock_init(&np->smp_lock);#define NCR_LOCK_NCB (np, flags) spin_lock_irqsave(&np->smp_lock, flags)
@@ -650,6 +655,8 @@#define NCR_LOCK_DRIVER (flags) do { save_flags(flags); cli(); } while (0)#define NCR_UNLOCK_DRIVER (flags) do { restore_flags(flags); } while (0) +#define NCR_LOCK_HOSTS (flags) do { save_flags(flags); cli(); } while (0) +#define NCR_UNLOCK_HOSTS (flags) do { restore_flags(flags); } while (0)#define NCR_INIT_LOCK_NCB (np) do { } while (0)#define NCR_LOCK_NCB (np, flags) do { save_flags(flags); cli(); } while (0)
@@ -695,7 +702,7 @@return page_remapped? (page_remapped + page_offs) :0UL ; } -static void __init unmap_pci_mem (u_long vaddr,u_long size) +static void unmap_pci_mem (u_long vaddr,u_long size) {if (vaddr)iounmap ((void *) (vaddr &PAGE_MASK ));
@@ -1301,6 +1308,15 @@ int length, int hostno, int func);#endif +/* +** reset the scsi controller on a "reboot." it should be way at the +** end. +*/ +static int sym53c8xx_halt (struct notifier_block *,ulong ,void *); +static struct notifier_block sym53c8xx_notifier = { + sym53c8xx_halt,NULL ,0 +}; +/* ** Driver setup. **
@@ -13043,7 +13046,8 @@ }m_free (devtbl,PAGE_SIZE ,"devtbl" ); - +if (attach_count) +register_reboot_notifier (&sym53c8xx_notifier);return attach_count; }
@@ -13775,19 +13779,49 @@ } +static int sym53c8xx_halt (struct notifier_block *block,ulong event,void *buf) +{ +unsigned long flags; +struct Scsi_Host *host, *next; + +switch (event) { +case SYS_RESTART : +case SYS_HALT : +case SYS_POWER_OFF : +break ; +default : +return NOTIFY_DONE ; + } + +printk (KERN_INFO "resetting sym53c8xx scsi bus(es)\n" ); +NCR_LOCK_HOSTS (flags); + next = first_host; +while ((host = next)) { +struct host_data *data = (struct host_data *)host->hostdata; + + next = host->next; +if (data && data->ncb) +ncr_detach (data->ncb); + } +NCR_UNLOCK_HOSTS (flags); + +return NOTIFY_OK ; +} +#ifdef MODULE int sym53c8xx_release (struct Scsi_Host *host) {#ifdef DEBUG_SYM53C8XX printk ("sym53c8xx : release\n" );#endif +if (first_host) +unregister_reboot_notifier (&sym53c8xx_notifier);ncr_detach (((struct host_data *) host->hostdata)->ncb);return 1 ; }#endif -/* ** Scsi command waiting list management. **
@@ -14182,13 +14216,15 @@ {struct Scsi_Host *host;struct host_data *host_data; +unsigned long flags;ncb_p ncb =0 ; -int retv; +int retv = -EINVAL ;#ifdef DEBUG_PROC_INFO printk ("sym53c8xx_proc_info: hostno=%d, func=%d\n" , hostno, func);#endif +NCR_LOCK_HOSTS (flags);for (host = first_host; host; host = host->next) {if (host->hostt != first_host->hostt)continue ;
@@ -14200,25 +14236,22 @@ }if (!ncb) -return -EINVAL ; + goto proc_done;if (func) {#ifdef SCSI_NCR_USER_COMMAND_SUPPORT retv =ncr_user_command (ncb, buffer, length); -#else - retv = -EINVAL ;#endif - } -else { + }else {if (start) *start = buffer;#ifdef SCSI_NCR_USER_INFO_SUPPORT retv =ncr_host_info (ncb, buffer, offset, length); -#else - retv = -EINVAL ;#endif } +NCR_UNLOCK_HOSTS (flags); +proc_done:return retv; }