aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hidraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hidraw.c')
-rw-r--r--drivers/hid/hidraw.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 8ecd77525103..c40f0403edaf 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -105,6 +105,7 @@ out:
105static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 105static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
106{ 106{
107 unsigned int minor = iminor(file->f_path.dentry->d_inode); 107 unsigned int minor = iminor(file->f_path.dentry->d_inode);
108 /* FIXME: What stops hidraw_table going NULL */
108 struct hid_device *dev = hidraw_table[minor]->hid; 109 struct hid_device *dev = hidraw_table[minor]->hid;
109 __u8 *buf; 110 __u8 *buf;
110 int ret = 0; 111 int ret = 0;
@@ -216,35 +217,38 @@ static int hidraw_release(struct inode * inode, struct file * file)
216 return 0; 217 return 0;
217} 218}
218 219
219static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 220static long hidraw_ioctl(struct file *file, unsigned int cmd,
221 unsigned long arg)
220{ 222{
223 struct inode *inode = file->f_path.dentry->d_inode;
221 unsigned int minor = iminor(inode); 224 unsigned int minor = iminor(inode);
225 long ret = 0;
226 /* FIXME: What stops hidraw_table going NULL */
222 struct hidraw *dev = hidraw_table[minor]; 227 struct hidraw *dev = hidraw_table[minor];
223 void __user *user_arg = (void __user*) arg; 228 void __user *user_arg = (void __user*) arg;
224 229
230 lock_kernel();
225 switch (cmd) { 231 switch (cmd) {
226 case HIDIOCGRDESCSIZE: 232 case HIDIOCGRDESCSIZE:
227 if (put_user(dev->hid->rsize, (int __user *)arg)) 233 if (put_user(dev->hid->rsize, (int __user *)arg))
228 return -EFAULT; 234 ret = -EFAULT;
229 return 0; 235 break;
230 236
231 case HIDIOCGRDESC: 237 case HIDIOCGRDESC:
232 { 238 {
233 __u32 len; 239 __u32 len;
234 240
235 if (get_user(len, (int __user *)arg)) 241 if (get_user(len, (int __user *)arg))
236 return -EFAULT; 242 ret = -EFAULT;
237 243 else if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
238 if (len > HID_MAX_DESCRIPTOR_SIZE - 1) 244 ret = -EINVAL;
239 return -EINVAL; 245 else if (copy_to_user(user_arg + offsetof(
240 246 struct hidraw_report_descriptor,
241 if (copy_to_user(user_arg + offsetof( 247 value[0]),
242 struct hidraw_report_descriptor, 248 dev->hid->rdesc,
243 value[0]), 249 min(dev->hid->rsize, len)))
244 dev->hid->rdesc, 250 ret = -EFAULT;
245 min(dev->hid->rsize, len))) 251 break;
246 return -EFAULT;
247 return 0;
248 } 252 }
249 case HIDIOCGRAWINFO: 253 case HIDIOCGRAWINFO:
250 { 254 {
@@ -254,15 +258,13 @@ static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd
254 dinfo.vendor = dev->hid->vendor; 258 dinfo.vendor = dev->hid->vendor;
255 dinfo.product = dev->hid->product; 259 dinfo.product = dev->hid->product;
256 if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) 260 if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
257 return -EFAULT; 261 ret = -EFAULT;
258 262 break;
259 return 0;
260 } 263 }
261 default: 264 default:
262 printk(KERN_EMERG "hidraw: unsupported ioctl() %x\n", 265 ret = -ENOTTY;
263 cmd);
264 } 266 }
265 return -EINVAL; 267 return ret;
266} 268}
267 269
268static const struct file_operations hidraw_ops = { 270static const struct file_operations hidraw_ops = {
@@ -272,7 +274,7 @@ static const struct file_operations hidraw_ops = {
272 .poll = hidraw_poll, 274 .poll = hidraw_poll,
273 .open = hidraw_open, 275 .open = hidraw_open,
274 .release = hidraw_release, 276 .release = hidraw_release,
275 .ioctl = hidraw_ioctl, 277 .unlocked_ioctl = hidraw_ioctl,
276}; 278};
277 279
278void hidraw_report_event(struct hid_device *hid, u8 *data, int len) 280void hidraw_report_event(struct hid_device *hid, u8 *data, int len)