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