diff options
Diffstat (limited to 'drivers/hid/hidraw.c')
| -rw-r--r-- | drivers/hid/hidraw.c | 32 | 
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 7685ae6808c..73244962897 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -208,7 +208,7 @@ static int hidraw_release(struct inode * inode, struct file * file)  	list_del(&list->node);  	dev = hidraw_table[minor]; -	if (!dev->open--) { +	if (!--dev->open) {  		if (list->hidraw->exist)  			dev->hid->ll_driver->close(dev->hid);  		else @@ -265,6 +265,34 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,  				break;  			}  		default: +			{ +				struct hid_device *hid = dev->hid; +				if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) +					return -EINVAL; + +				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) { +					int len; +					if (!hid->name) +						return 0; +					len = strlen(hid->name) + 1; +					if (len > _IOC_SIZE(cmd)) +						len = _IOC_SIZE(cmd); +					return copy_to_user(user_arg, hid->name, len) ? +						-EFAULT : len; +				} + +				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) { +					int len; +					if (!hid->phys) +						return 0; +					len = strlen(hid->phys) + 1; +					if (len > _IOC_SIZE(cmd)) +						len = _IOC_SIZE(cmd); +					return copy_to_user(user_arg, hid->phys, len) ? +						-EFAULT : len; +				} +                } +  			ret = -ENOTTY;  	}  	unlock_kernel(); @@ -329,7 +357,7 @@ int hidraw_connect(struct hid_device *hid)  		goto out;  	} -	dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor), +	dev->dev = device_create(hidraw_class, &hid->dev, MKDEV(hidraw_major, minor),  				 NULL, "%s%d", "hidraw", minor);  	if (IS_ERR(dev->dev)) {  | 
