diff options
Diffstat (limited to 'drivers/char/ipmi')
-rw-r--r-- | drivers/char/ipmi/ipmi_devintf.c | 15 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 74 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 51 |
3 files changed, 92 insertions, 48 deletions
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index d8ec92a..1fc8876 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -44,7 +44,6 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/compat.h> -#include <linux/smp_lock.h> struct ipmi_file_private { @@ -59,6 +58,7 @@ struct ipmi_file_private unsigned int default_retry_time_ms; }; +static DEFINE_MUTEX(ipmi_mutex); static void file_receive_handler(struct ipmi_recv_msg *msg, void *handler_data) { @@ -102,9 +102,9 @@ static int ipmi_fasync(int fd, struct file *file, int on) struct ipmi_file_private *priv = file->private_data; int result; - lock_kernel(); /* could race against open() otherwise */ + mutex_lock(&ipmi_mutex); /* could race against open() otherwise */ result = fasync_helper(fd, file, on, &priv->fasync_queue); - unlock_kernel(); + mutex_unlock(&ipmi_mutex); return (result); } @@ -125,7 +125,7 @@ static int ipmi_open(struct inode *inode, struct file *file) if (!priv) return -ENOMEM; - lock_kernel(); + mutex_lock(&ipmi_mutex); priv->file = file; rv = ipmi_create_user(if_num, @@ -150,7 +150,7 @@ static int ipmi_open(struct inode *inode, struct file *file) priv->default_retry_time_ms = 0; out: - unlock_kernel(); + mutex_unlock(&ipmi_mutex); return rv; } @@ -639,9 +639,9 @@ static long ipmi_unlocked_ioctl(struct file *file, { int ret; - lock_kernel(); + mutex_lock(&ipmi_mutex); ret = ipmi_ioctl(file, cmd, data); - unlock_kernel(); + mutex_unlock(&ipmi_mutex); return ret; } @@ -850,6 +850,7 @@ static const struct file_operations ipmi_fops = { .release = ipmi_release, .fasync = ipmi_fasync, .poll = ipmi_poll, + .llseek = noop_llseek, }; #define DEVICE_NAME "ipmidev" diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 2a84379..e537610d 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -305,6 +305,9 @@ static int num_force_kipmid; #ifdef CONFIG_PCI static int pci_registered; #endif +#ifdef CONFIG_ACPI +static int pnp_registered; +#endif #ifdef CONFIG_PPC_OF static int of_registered; #endif @@ -1804,9 +1807,12 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) info->irq_setup = std_irq_setup; info->slave_addr = ipmb; - if (!add_smi(info)) + if (!add_smi(info)) { if (try_smi_init(info)) cleanup_one_si(info); + } else { + kfree(info); + } } else { /* remove */ struct smi_info *e, *tmp_e; @@ -1890,9 +1896,12 @@ static __devinit void hardcode_find_bmc(void) info->irq_setup = std_irq_setup; info->slave_addr = slave_addrs[i]; - if (!add_smi(info)) + if (!add_smi(info)) { if (try_smi_init(info)) cleanup_one_si(info); + } else { + kfree(info); + } } } @@ -2012,18 +2021,12 @@ struct SPMITable { static __devinit int try_init_spmi(struct SPMITable *spmi) { struct smi_info *info; - u8 addr_space; if (spmi->IPMIlegacy != 1) { printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy); return -ENODEV; } - if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) - addr_space = IPMI_MEM_ADDR_SPACE; - else - addr_space = IPMI_IO_ADDR_SPACE; - info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); @@ -2087,7 +2090,13 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) } info->io.addr_data = spmi->addr.address; - add_smi(info); + pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n", + (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", + info->io.addr_data, info->io.regsize, info->io.regspacing, + info->irq); + + if (add_smi(info)) + kfree(info); return 0; } @@ -2119,7 +2128,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, { struct acpi_device *acpi_dev; struct smi_info *info; - struct resource *res; + struct resource *res, *res_second; acpi_handle handle; acpi_status status; unsigned long long tmp; @@ -2175,13 +2184,13 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, info->io.addr_data = res->start; info->io.regspacing = DEFAULT_REGSPACING; - res = pnp_get_resource(dev, + res_second = pnp_get_resource(dev, (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? IORESOURCE_IO : IORESOURCE_MEM, 1); - if (res) { - if (res->start > info->io.addr_data) - info->io.regspacing = res->start - info->io.addr_data; + if (res_second) { + if (res_second->start > info->io.addr_data) + info->io.regspacing = res_second->start - info->io.addr_data; } info->io.regsize = DEFAULT_REGSPACING; info->io.regshift = 0; @@ -2203,7 +2212,10 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, res, info->io.regsize, info->io.regspacing, info->irq); - return add_smi(info); + if (add_smi(info)) + goto err_free; + + return 0; err_free: kfree(info); @@ -2361,7 +2373,13 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) if (info->irq) info->irq_setup = std_irq_setup; - add_smi(info); + pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n", + (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", + info->io.addr_data, info->io.regsize, info->io.regspacing, + info->irq); + + if (add_smi(info)) + kfree(info); } static void __devinit dmi_find_bmc(void) @@ -2467,7 +2485,10 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, &pdev->resource[0], info->io.regsize, info->io.regspacing, info->irq); - return add_smi(info); + if (add_smi(info)) + kfree(info); + + return 0; } static void __devexit ipmi_pci_remove(struct pci_dev *pdev) @@ -2509,7 +2530,7 @@ static struct pci_driver ipmi_pci_driver = { #ifdef CONFIG_PPC_OF -static int __devinit ipmi_of_probe(struct of_device *dev, +static int __devinit ipmi_of_probe(struct platform_device *dev, const struct of_device_id *match) { struct smi_info *info; @@ -2580,10 +2601,15 @@ static int __devinit ipmi_of_probe(struct of_device *dev, dev_set_drvdata(&dev->dev, info); - return add_smi(info); + if (add_smi(info)) { + kfree(info); + return -EBUSY; + } + + return 0; } -static int __devexit ipmi_of_remove(struct of_device *dev) +static int __devexit ipmi_of_remove(struct platform_device *dev) { cleanup_one_si(dev_get_drvdata(&dev->dev)); return 0; @@ -3013,6 +3039,8 @@ static __devinit void default_find_bmc(void) info->io.addr_data); } else cleanup_one_si(info); + } else { + kfree(info); } } } @@ -3040,7 +3068,7 @@ static int add_smi(struct smi_info *new_smi) si_to_str[new_smi->si_type]); mutex_lock(&smi_infos_lock); if (!is_new_interface(new_smi)) { - printk(KERN_CONT PFX "duplicate interface\n"); + printk(KERN_CONT " duplicate interface\n"); rv = -EBUSY; goto out_err; } @@ -3333,6 +3361,7 @@ static __devinit int init_ipmi_si(void) #ifdef CONFIG_ACPI pnp_register_driver(&ipmi_pnp_driver); + pnp_registered = 1; #endif #ifdef CONFIG_DMI @@ -3500,7 +3529,8 @@ static __exit void cleanup_ipmi_si(void) pci_unregister_driver(&ipmi_pci_driver); #endif #ifdef CONFIG_ACPI - pnp_unregister_driver(&ipmi_pnp_driver); + if (pnp_registered) + pnp_unregister_driver(&ipmi_pnp_driver); #endif #ifdef CONFIG_PPC_OF diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 82bcdb2..f4d334f 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -35,7 +35,7 @@ #include <linux/moduleparam.h> #include <linux/ipmi.h> #include <linux/ipmi_smi.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h> #include <linux/watchdog.h> #include <linux/miscdevice.h> #include <linux/init.h> @@ -149,6 +149,7 @@ #define WDIOC_GET_PRETIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 22, int) #endif +static DEFINE_MUTEX(ipmi_watchdog_mutex); static int nowayout = WATCHDOG_NOWAYOUT; static ipmi_user_t watchdog_user; @@ -196,7 +197,7 @@ static void ipmi_unregister_watchdog(int ipmi_intf); */ static int start_now; -static int set_param_int(const char *val, struct kernel_param *kp) +static int set_param_timeout(const char *val, const struct kernel_param *kp) { char *endp; int l; @@ -215,10 +216,11 @@ static int set_param_int(const char *val, struct kernel_param *kp) return rv; } -static int get_param_int(char *buffer, struct kernel_param *kp) -{ - return sprintf(buffer, "%i", *((int *)kp->arg)); -} +static struct kernel_param_ops param_ops_timeout = { + .set = set_param_timeout, + .get = param_get_int, +}; +#define param_check_timeout param_check_int typedef int (*action_fn)(const char *intval, char *outval); @@ -227,7 +229,7 @@ static int preaction_op(const char *inval, char *outval); static int preop_op(const char *inval, char *outval); static void check_parms(void); -static int set_param_str(const char *val, struct kernel_param *kp) +static int set_param_str(const char *val, const struct kernel_param *kp) { action_fn fn = (action_fn) kp->arg; int rv = 0; @@ -251,7 +253,7 @@ static int set_param_str(const char *val, struct kernel_param *kp) return rv; } -static int get_param_str(char *buffer, struct kernel_param *kp) +static int get_param_str(char *buffer, const struct kernel_param *kp) { action_fn fn = (action_fn) kp->arg; int rv; @@ -263,7 +265,7 @@ static int get_param_str(char *buffer, struct kernel_param *kp) } -static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp) +static int set_param_wdog_ifnum(const char *val, const struct kernel_param *kp) { int rv = param_set_int(val, kp); if (rv) @@ -276,27 +278,38 @@ static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp) return 0; } -module_param_call(ifnum_to_use, set_param_wdog_ifnum, get_param_int, - &ifnum_to_use, 0644); +static struct kernel_param_ops param_ops_wdog_ifnum = { + .set = set_param_wdog_ifnum, + .get = param_get_int, +}; + +#define param_check_wdog_ifnum param_check_int + +static struct kernel_param_ops param_ops_str = { + .set = set_param_str, + .get = get_param_str, +}; + +module_param(ifnum_to_use, wdog_ifnum, 0644); MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " "timer. Setting to -1 defaults to the first registered " "interface"); -module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644); +module_param(timeout, timeout, 0644); MODULE_PARM_DESC(timeout, "Timeout value in seconds."); -module_param_call(pretimeout, set_param_int, get_param_int, &pretimeout, 0644); +module_param(pretimeout, timeout, 0644); MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds."); -module_param_call(action, set_param_str, get_param_str, action_op, 0644); +module_param_cb(action, ¶m_ops_str, action_op, 0644); MODULE_PARM_DESC(action, "Timeout action. One of: " "reset, none, power_cycle, power_off."); -module_param_call(preaction, set_param_str, get_param_str, preaction_op, 0644); +module_param_cb(preaction, ¶m_ops_str, preaction_op, 0644); MODULE_PARM_DESC(preaction, "Pretimeout action. One of: " "pre_none, pre_smi, pre_nmi, pre_int."); -module_param_call(preop, set_param_str, get_param_str, preop_op, 0644); +module_param_cb(preop, ¶m_ops_str, preop_op, 0644); MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " "preop_none, preop_panic, preop_give_data."); @@ -736,9 +749,9 @@ static long ipmi_unlocked_ioctl(struct file *file, { int ret; - lock_kernel(); + mutex_lock(&ipmi_watchdog_mutex); ret = ipmi_ioctl(file, cmd, arg); - unlock_kernel(); + mutex_unlock(&ipmi_watchdog_mutex); return ret; } @@ -832,7 +845,6 @@ static int ipmi_open(struct inode *ino, struct file *filep) if (test_and_set_bit(0, &ipmi_wdog_open)) return -EBUSY; - cycle_kernel_lock(); /* * Don't start the timer now, let it start on the @@ -897,6 +909,7 @@ static const struct file_operations ipmi_wdog_fops = { .open = ipmi_open, .release = ipmi_close, .fasync = ipmi_fasync, + .llseek = no_llseek, }; static struct miscdevice ipmi_wdog_miscdev = { |