event.c revision a192a9580bcc41692be1f36b77c3b681827f566a
1bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo/* 2bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo * event.c - exporting ACPI events via procfs 3bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo * 4bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo * 7bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo */ 8bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 9bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include <linux/spinlock.h> 10bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include <linux/proc_fs.h> 11bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include <linux/init.h> 12bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include <linux/poll.h> 13bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include <acpi/acpi_drivers.h> 14bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include <net/netlink.h> 15bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include <net/genetlink.h> 16bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 17bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#include "internal.h" 18bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 19bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#define _COMPONENT ACPI_SYSTEM_COMPONENT 20bdcd81707973cf8aa9305337166f8ee842a050d4Kalle ValoACPI_MODULE_NAME("event"); 21bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 22bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#ifdef CONFIG_ACPI_PROC_EVENT 236765d0aa5ff5b92098f5e571f26904106eae6ff3Vasanthakumar Thiagarajan/* Global vars for handling event proc entry */ 24bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic DEFINE_SPINLOCK(acpi_system_event_lock); 256765d0aa5ff5b92098f5e571f26904106eae6ff3Vasanthakumar Thiagarajanint event_is_open = 0; 26bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoextern struct list_head acpi_bus_event_list; 27bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoextern wait_queue_head_t acpi_bus_event_queue; 28bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 29f5938f249a08a4e6c9046fa095be00db664158ccVasanthakumar Thiagarajanstatic int acpi_system_open_event(struct inode *inode, struct file *file) 30bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 31bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo spin_lock_irq(&acpi_system_event_lock); 32bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 33bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (event_is_open) 34bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo goto out_busy; 35bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 36bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event_is_open = 1; 37bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 38bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo spin_unlock_irq(&acpi_system_event_lock); 39bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return 0; 40bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 41bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo out_busy: 42bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo spin_unlock_irq(&acpi_system_event_lock); 43bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return -EBUSY; 44bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 45bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 46bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic ssize_t 47bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoacpi_system_read_event(struct file *file, char __user * buffer, size_t count, 48bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo loff_t * ppos) 49bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 50bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo int result = 0; 51bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo struct acpi_bus_event event; 52bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo static char str[ACPI_MAX_STRING]; 53bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo static int chars_remaining = 0; 54bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo static char *ptr; 55bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 56bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (!chars_remaining) { 57bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo memset(&event, 0, sizeof(struct acpi_bus_event)); 58bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 59bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if ((file->f_flags & O_NONBLOCK) 60bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo && (list_empty(&acpi_bus_event_list))) 61bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return -EAGAIN; 62bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 63bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo result = acpi_bus_receive_event(&event); 64bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (result) 653c774bbab78435e349de2c88fc6e054716f8f2eaJouni Malinen return result; 663c774bbab78435e349de2c88fc6e054716f8f2eaJouni Malinen 67bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo chars_remaining = sprintf(str, "%s %s %08x %08x\n", 68bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event.device_class ? event. 69bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo device_class : "<unknown>", 70bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event.bus_id ? event. 71bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo bus_id : "<unknown>", event.type, 72bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event.data); 73bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo ptr = str; 74bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo } 75bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 76bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (chars_remaining < count) { 77bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo count = chars_remaining; 78bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo } 79bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 80bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (copy_to_user(buffer, ptr, count)) 81bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return -EFAULT; 82bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 83bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo *ppos += count; 84bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo chars_remaining -= count; 85bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo ptr += count; 86bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 87bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return count; 88bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 89bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 90bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic int acpi_system_close_event(struct inode *inode, struct file *file) 91bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 92bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo spin_lock_irq(&acpi_system_event_lock); 93bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event_is_open = 0; 94bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo spin_unlock_irq(&acpi_system_event_lock); 95bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return 0; 96bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 97bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 98bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic unsigned int acpi_system_poll_event(struct file *file, poll_table * wait) 99bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 100bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo poll_wait(file, &acpi_bus_event_queue, wait); 101bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (!list_empty(&acpi_bus_event_list)) 102bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return POLLIN | POLLRDNORM; 103bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return 0; 104bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 105bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 106bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic const struct file_operations acpi_system_event_ops = { 107bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .owner = THIS_MODULE, 108bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .open = acpi_system_open_event, 109bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .read = acpi_system_read_event, 110bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .release = acpi_system_close_event, 111bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .poll = acpi_system_poll_event, 112bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo}; 113bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#endif /* CONFIG_ACPI_PROC_EVENT */ 114bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 115bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo/* ACPI notifier chain */ 116bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic BLOCKING_NOTIFIER_HEAD(acpi_chain_head); 117bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 118bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoint acpi_notifier_call_chain(struct acpi_device *dev, u32 type, u32 data) 119bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 120bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo struct acpi_bus_event event; 121bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 122bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo strcpy(event.device_class, dev->pnp.device_class); 123bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo strcpy(event.bus_id, dev->pnp.bus_id); 124bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event.type = type; 125bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event.data = data; 126bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return (blocking_notifier_call_chain(&acpi_chain_head, 0, (void *)&event) 127bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo == NOTIFY_BAD) ? -EINVAL : 0; 128bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 129bdcd81707973cf8aa9305337166f8ee842a050d4Kalle ValoEXPORT_SYMBOL(acpi_notifier_call_chain); 130bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 131bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoint register_acpi_notifier(struct notifier_block *nb) 132bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 133bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return blocking_notifier_chain_register(&acpi_chain_head, nb); 134bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 135bdcd81707973cf8aa9305337166f8ee842a050d4Kalle ValoEXPORT_SYMBOL(register_acpi_notifier); 136bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 137bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoint unregister_acpi_notifier(struct notifier_block *nb) 138bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 139bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return blocking_notifier_chain_unregister(&acpi_chain_head, nb); 140bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 141bdcd81707973cf8aa9305337166f8ee842a050d4Kalle ValoEXPORT_SYMBOL(unregister_acpi_notifier); 142bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 143bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#ifdef CONFIG_NET 144bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic unsigned int acpi_event_seqnum; 145bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostruct acpi_genl_event { 146bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo acpi_device_class device_class; 147bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo char bus_id[15]; 148bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo u32 type; 149bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo u32 data; 150bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo}; 151bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 152bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo/* attributes of acpi_genl_family */ 153bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoenum { 154bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo ACPI_GENL_ATTR_UNSPEC, 155bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo ACPI_GENL_ATTR_EVENT, /* ACPI event info needed by user space */ 156bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo __ACPI_GENL_ATTR_MAX, 157bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo}; 158bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1) 159bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 160bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo/* commands supported by the acpi_genl_family */ 161bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoenum { 162bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo ACPI_GENL_CMD_UNSPEC, 163bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo ACPI_GENL_CMD_EVENT, /* kernel->user notifications for ACPI events */ 164bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo __ACPI_GENL_CMD_MAX, 165bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo}; 166bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1) 167bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 168bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#define ACPI_GENL_FAMILY_NAME "acpi_event" 169bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#define ACPI_GENL_VERSION 0x01 170bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group" 171bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 172bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic struct genl_family acpi_event_genl_family = { 173bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .id = GENL_ID_GENERATE, 174bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .name = ACPI_GENL_FAMILY_NAME, 175bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .version = ACPI_GENL_VERSION, 176bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .maxattr = ACPI_GENL_ATTR_MAX, 177bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo}; 178bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 179bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic struct genl_multicast_group acpi_event_mcgrp = { 180bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo .name = ACPI_GENL_MCAST_GROUP_NAME, 181bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo}; 182bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 183b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajanint acpi_bus_generate_netlink_event(const char *device_class, 184bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo const char *bus_id, 185bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo u8 type, int data) 186bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 187bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo struct sk_buff *skb; 188bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo struct nlattr *attr; 189bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo struct acpi_genl_event *event; 190bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo void *msg_header; 191bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo int size; 192bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo int result; 193b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan 194b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan /* allocate memory */ 195b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan size = nla_total_size(sizeof(struct acpi_genl_event)) + 196bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo nla_total_size(0); 197b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan 198bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo skb = genlmsg_new(size, GFP_ATOMIC); 199bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (!skb) 200bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return -ENOMEM; 201bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 202bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo /* add the genetlink message header */ 203bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++, 204b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan &acpi_event_genl_family, 0, 205bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo ACPI_GENL_CMD_EVENT); 206bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (!msg_header) { 207bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo nlmsg_free(skb); 208bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return -ENOMEM; 209bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo } 210bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 211bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo /* fill the data */ 212bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo attr = 213bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo nla_reserve(skb, ACPI_GENL_ATTR_EVENT, 214bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo sizeof(struct acpi_genl_event)); 215bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (!attr) { 216bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo nlmsg_free(skb); 217bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return -EINVAL; 218bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo } 219bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 220bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event = nla_data(attr); 221bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (!event) { 222b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan nlmsg_free(skb); 223b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan return -EINVAL; 224b142b91401b8e39671db74bd4fe89f281f4c2978Vasanthakumar Thiagarajan } 225bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 226bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo memset(event, 0, sizeof(struct acpi_genl_event)); 227bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 228bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo strcpy(event->device_class, device_class); 229bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo strcpy(event->bus_id, bus_id); 230bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event->type = type; 231bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo event->data = data; 232bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 233bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo /* send multicast genetlink message */ 234bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo result = genlmsg_end(skb, msg_header); 235bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (result < 0) { 236bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo nlmsg_free(skb); 237addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo return result; 238addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo } 239bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 240addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC); 241bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return 0; 242addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo} 243bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 244bdcd81707973cf8aa9305337166f8ee842a050d4Kalle ValoEXPORT_SYMBOL(acpi_bus_generate_netlink_event); 245addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo 246addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valostatic int acpi_event_genetlink_init(void) 247addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo{ 248bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo int result; 249bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 250addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo result = genl_register_family(&acpi_event_genl_family); 251addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo if (result) 252addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo return result; 253addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo 254addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo result = genl_register_mc_group(&acpi_event_genl_family, 255addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo &acpi_event_mcgrp); 256bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo if (result) 257bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo genl_unregister_family(&acpi_event_genl_family); 258addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo 259bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo return result; 260bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 261bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 262bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#else 263bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valoint acpi_bus_generate_netlink_event(const char *device_class, 264bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo const char *bus_id, 265f9ea0753a18448a5e92369317b6ac061fe1275bfVasanthakumar Thiagarajan u8 type, int data) 266bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 267addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo return 0; 268bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo} 269bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 270addb44be036dd5fc814be770ec4b90f08c820e76Kalle ValoEXPORT_SYMBOL(acpi_bus_generate_netlink_event); 271addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo 272addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valostatic int acpi_event_genetlink_init(void) 273addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo{ 274addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo return -ENODEV; 275addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo} 276bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#endif 277bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 278bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valostatic int __init acpi_event_init(void) 279bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo{ 280addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo#ifdef CONFIG_ACPI_PROC_EVENT 281bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo struct proc_dir_entry *entry; 282bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo#endif 283addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo int error = 0; 284bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 285addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo if (acpi_disabled) 286addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo return 0; 287bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo 288addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo /* create genetlink for acpi event */ 289addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo error = acpi_event_genetlink_init(); 290addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo if (error) 291addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo printk(KERN_WARNING PREFIX 292addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo "Failed to create genetlink family for ACPI event\n"); 293addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo 294addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo#ifdef CONFIG_ACPI_PROC_EVENT 295bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo /* 'event' [R] */ 296bdcd81707973cf8aa9305337166f8ee842a050d4Kalle Valo entry = proc_create("event", S_IRUSR, acpi_root_dir, 297addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo &acpi_system_event_ops); 298addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo if (!entry) 299addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo return -ENODEV; 300addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo#endif 301addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo 302f9ea0753a18448a5e92369317b6ac061fe1275bfVasanthakumar Thiagarajan return 0; 303f9ea0753a18448a5e92369317b6ac061fe1275bfVasanthakumar Thiagarajan} 304addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo 305addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valofs_initcall(acpi_event_init); 306addb44be036dd5fc814be770ec4b90f08c820e76Kalle Valo