2323#include <linux/init.h>
2424#include <linux/kernel.h>
2525#include <linux/list.h>
26- #include <linux/miscdevice.h>
2726#include <linux/module.h>
2827#include <linux/platform_device.h>
2928#include <linux/slab.h>
3029#include <linux/sysfs.h>
3130#include <linux/types.h>
32- #include <linux/uaccess.h>
3331#include <linux/uuid.h>
3432#include <linux/wmi.h>
3533#include <linux/fs.h>
36- #include <uapi/linux/wmi.h>
3734
3835MODULE_AUTHOR ("Carlos Corbacho" );
3936MODULE_DESCRIPTION ("ACPI-WMI Mapping Driver" );
@@ -66,12 +63,9 @@ struct wmi_block {
6663 struct wmi_device dev ;
6764 struct list_head list ;
6865 struct guid_block gblock ;
69- struct miscdevice char_dev ;
70- struct mutex char_mutex ;
7166 struct acpi_device * acpi_device ;
7267 wmi_notify_handler handler ;
7368 void * handler_data ;
74- u64 req_buf_size ;
7569 unsigned long flags ;
7670};
7771
@@ -256,26 +250,6 @@ static void wmi_device_put(struct wmi_device *wdev)
256250 * Exported WMI functions
257251 */
258252
259- /**
260- * set_required_buffer_size - Sets the buffer size needed for performing IOCTL
261- * @wdev: A wmi bus device from a driver
262- * @length: Required buffer size
263- *
264- * Allocates memory needed for buffer, stores the buffer size in that memory.
265- *
266- * Return: 0 on success or a negative error code for failure.
267- */
268- int set_required_buffer_size (struct wmi_device * wdev , u64 length )
269- {
270- struct wmi_block * wblock ;
271-
272- wblock = container_of (wdev , struct wmi_block , dev );
273- wblock -> req_buf_size = length ;
274-
275- return 0 ;
276- }
277- EXPORT_SYMBOL_GPL (set_required_buffer_size );
278-
279253/**
280254 * wmi_instance_count - Get number of WMI object instances
281255 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
@@ -884,167 +858,30 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
884858
885859 return 0 ;
886860}
887- static int wmi_char_open (struct inode * inode , struct file * filp )
888- {
889- /*
890- * The miscdevice already stores a pointer to itself
891- * inside filp->private_data
892- */
893- struct wmi_block * wblock = container_of (filp -> private_data , struct wmi_block , char_dev );
894-
895- filp -> private_data = wblock ;
896-
897- return nonseekable_open (inode , filp );
898- }
899-
900- static ssize_t wmi_char_read (struct file * filp , char __user * buffer ,
901- size_t length , loff_t * offset )
902- {
903- struct wmi_block * wblock = filp -> private_data ;
904-
905- return simple_read_from_buffer (buffer , length , offset ,
906- & wblock -> req_buf_size ,
907- sizeof (wblock -> req_buf_size ));
908- }
909-
910- static long wmi_ioctl (struct file * filp , unsigned int cmd , unsigned long arg )
911- {
912- struct wmi_ioctl_buffer __user * input =
913- (struct wmi_ioctl_buffer __user * ) arg ;
914- struct wmi_block * wblock = filp -> private_data ;
915- struct wmi_ioctl_buffer * buf ;
916- struct wmi_driver * wdriver ;
917- int ret ;
918-
919- if (_IOC_TYPE (cmd ) != WMI_IOC )
920- return - ENOTTY ;
921-
922- /* make sure we're not calling a higher instance than exists*/
923- if (_IOC_NR (cmd ) >= wblock -> gblock .instance_count )
924- return - EINVAL ;
925-
926- mutex_lock (& wblock -> char_mutex );
927- buf = wblock -> handler_data ;
928- if (get_user (buf -> length , & input -> length )) {
929- dev_dbg (& wblock -> dev .dev , "Read length from user failed\n" );
930- ret = - EFAULT ;
931- goto out_ioctl ;
932- }
933- /* if it's too small, abort */
934- if (buf -> length < wblock -> req_buf_size ) {
935- dev_err (& wblock -> dev .dev ,
936- "Buffer %lld too small, need at least %lld\n" ,
937- buf -> length , wblock -> req_buf_size );
938- ret = - EINVAL ;
939- goto out_ioctl ;
940- }
941- /* if it's too big, warn, driver will only use what is needed */
942- if (buf -> length > wblock -> req_buf_size )
943- dev_warn (& wblock -> dev .dev ,
944- "Buffer %lld is bigger than required %lld\n" ,
945- buf -> length , wblock -> req_buf_size );
946-
947- /* copy the structure from userspace */
948- if (copy_from_user (buf , input , wblock -> req_buf_size )) {
949- dev_dbg (& wblock -> dev .dev , "Copy %llu from user failed\n" ,
950- wblock -> req_buf_size );
951- ret = - EFAULT ;
952- goto out_ioctl ;
953- }
954-
955- /* let the driver do any filtering and do the call */
956- wdriver = drv_to_wdrv (wblock -> dev .dev .driver );
957- if (!try_module_get (wdriver -> driver .owner )) {
958- ret = - EBUSY ;
959- goto out_ioctl ;
960- }
961- ret = wdriver -> filter_callback (& wblock -> dev , cmd , buf );
962- module_put (wdriver -> driver .owner );
963- if (ret )
964- goto out_ioctl ;
965-
966- /* return the result (only up to our internal buffer size) */
967- if (copy_to_user (input , buf , wblock -> req_buf_size )) {
968- dev_dbg (& wblock -> dev .dev , "Copy %llu to user failed\n" ,
969- wblock -> req_buf_size );
970- ret = - EFAULT ;
971- }
972-
973- out_ioctl :
974- mutex_unlock (& wblock -> char_mutex );
975- return ret ;
976- }
977-
978- static const struct file_operations wmi_fops = {
979- .owner = THIS_MODULE ,
980- .read = wmi_char_read ,
981- .open = wmi_char_open ,
982- .unlocked_ioctl = wmi_ioctl ,
983- .compat_ioctl = compat_ptr_ioctl ,
984- };
985861
986862static int wmi_dev_probe (struct device * dev )
987863{
988864 struct wmi_block * wblock = dev_to_wblock (dev );
989865 struct wmi_driver * wdriver = drv_to_wdrv (dev -> driver );
990866 int ret = 0 ;
991- char * buf ;
992867
993868 if (ACPI_FAILURE (wmi_method_enable (wblock , true)))
994869 dev_warn (dev , "failed to enable device -- probing anyway\n" );
995870
996871 if (wdriver -> probe ) {
997872 ret = wdriver -> probe (dev_to_wdev (dev ),
998873 find_guid_context (wblock , wdriver ));
999- if (ret != 0 )
1000- goto probe_failure ;
1001- }
1002-
1003- /* driver wants a character device made */
1004- if (wdriver -> filter_callback ) {
1005- /* check that required buffer size declared by driver or MOF */
1006- if (!wblock -> req_buf_size ) {
1007- dev_err (& wblock -> dev .dev ,
1008- "Required buffer size not set\n" );
1009- ret = - EINVAL ;
1010- goto probe_failure ;
1011- }
874+ if (!ret ) {
875+ if (ACPI_FAILURE (wmi_method_enable (wblock , false)))
876+ dev_warn (dev , "Failed to disable device\n" );
1012877
1013- wblock -> handler_data = kmalloc (wblock -> req_buf_size ,
1014- GFP_KERNEL );
1015- if (!wblock -> handler_data ) {
1016- ret = - ENOMEM ;
1017- goto probe_failure ;
1018- }
1019-
1020- buf = kasprintf (GFP_KERNEL , "wmi/%s" , wdriver -> driver .name );
1021- if (!buf ) {
1022- ret = - ENOMEM ;
1023- goto probe_string_failure ;
1024- }
1025- wblock -> char_dev .minor = MISC_DYNAMIC_MINOR ;
1026- wblock -> char_dev .name = buf ;
1027- wblock -> char_dev .fops = & wmi_fops ;
1028- wblock -> char_dev .mode = 0444 ;
1029- ret = misc_register (& wblock -> char_dev );
1030- if (ret ) {
1031- dev_warn (dev , "failed to register char dev: %d\n" , ret );
1032- ret = - ENOMEM ;
1033- goto probe_misc_failure ;
878+ return ret ;
1034879 }
1035880 }
1036881
1037882 set_bit (WMI_PROBED , & wblock -> flags );
1038- return 0 ;
1039883
1040- probe_misc_failure :
1041- kfree (buf );
1042- probe_string_failure :
1043- kfree (wblock -> handler_data );
1044- probe_failure :
1045- if (ACPI_FAILURE (wmi_method_enable (wblock , false)))
1046- dev_warn (dev , "failed to disable device\n" );
1047- return ret ;
884+ return 0 ;
1048885}
1049886
1050887static void wmi_dev_remove (struct device * dev )
@@ -1054,12 +891,6 @@ static void wmi_dev_remove(struct device *dev)
1054891
1055892 clear_bit (WMI_PROBED , & wblock -> flags );
1056893
1057- if (wdriver -> filter_callback ) {
1058- misc_deregister (& wblock -> char_dev );
1059- kfree (wblock -> char_dev .name );
1060- kfree (wblock -> handler_data );
1061- }
1062-
1063894 if (wdriver -> remove )
1064895 wdriver -> remove (dev_to_wdev (dev ));
1065896
@@ -1131,7 +962,6 @@ static int wmi_create_device(struct device *wmi_bus_dev,
1131962
1132963 if (wblock -> gblock .flags & ACPI_WMI_METHOD ) {
1133964 wblock -> dev .dev .type = & wmi_type_method ;
1134- mutex_init (& wblock -> char_mutex );
1135965 goto out_init ;
1136966 }
1137967
0 commit comments