diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/devio.c | 333 |
1 files changed, 188 insertions, 145 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e661994ad18d..ae94176c64e4 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -75,14 +75,14 @@ struct async { | |||
75 | u32 secid; | 75 | u32 secid; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static int usbfs_snoop = 0; | 78 | static int usbfs_snoop; |
79 | module_param (usbfs_snoop, bool, S_IRUGO | S_IWUSR); | 79 | module_param(usbfs_snoop, bool, S_IRUGO | S_IWUSR); |
80 | MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic"); | 80 | MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); |
81 | 81 | ||
82 | #define snoop(dev, format, arg...) \ | 82 | #define snoop(dev, format, arg...) \ |
83 | do { \ | 83 | do { \ |
84 | if (usbfs_snoop) \ | 84 | if (usbfs_snoop) \ |
85 | dev_info( dev , format , ## arg); \ | 85 | dev_info(dev , format , ## arg); \ |
86 | } while (0) | 86 | } while (0) |
87 | 87 | ||
88 | #define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0) | 88 | #define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0) |
@@ -90,7 +90,7 @@ MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic"); | |||
90 | 90 | ||
91 | #define MAX_USBFS_BUFFER_SIZE 16384 | 91 | #define MAX_USBFS_BUFFER_SIZE 16384 |
92 | 92 | ||
93 | static inline int connected (struct dev_state *ps) | 93 | static inline int connected(struct dev_state *ps) |
94 | { | 94 | { |
95 | return (!list_empty(&ps->list) && | 95 | return (!list_empty(&ps->list) && |
96 | ps->dev->state != USB_STATE_NOTATTACHED); | 96 | ps->dev->state != USB_STATE_NOTATTACHED); |
@@ -120,7 +120,8 @@ static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) | |||
120 | return ret; | 120 | return ret; |
121 | } | 121 | } |
122 | 122 | ||
123 | static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 123 | static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, |
124 | loff_t *ppos) | ||
124 | { | 125 | { |
125 | struct dev_state *ps = file->private_data; | 126 | struct dev_state *ps = file->private_data; |
126 | struct usb_device *dev = ps->dev; | 127 | struct usb_device *dev = ps->dev; |
@@ -140,7 +141,8 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l | |||
140 | } | 141 | } |
141 | 142 | ||
142 | if (pos < sizeof(struct usb_device_descriptor)) { | 143 | if (pos < sizeof(struct usb_device_descriptor)) { |
143 | struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */ | 144 | /* 18 bytes - fits on the stack */ |
145 | struct usb_device_descriptor temp_desc; | ||
144 | 146 | ||
145 | memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor)); | 147 | memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor)); |
146 | le16_to_cpus(&temp_desc.bcdUSB); | 148 | le16_to_cpus(&temp_desc.bcdUSB); |
@@ -213,14 +215,14 @@ static struct async *alloc_async(unsigned int numisoframes) | |||
213 | struct async *as; | 215 | struct async *as; |
214 | 216 | ||
215 | as = kzalloc(sizeof(struct async), GFP_KERNEL); | 217 | as = kzalloc(sizeof(struct async), GFP_KERNEL); |
216 | if (!as) | 218 | if (!as) |
217 | return NULL; | 219 | return NULL; |
218 | as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); | 220 | as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); |
219 | if (!as->urb) { | 221 | if (!as->urb) { |
220 | kfree(as); | 222 | kfree(as); |
221 | return NULL; | 223 | return NULL; |
222 | } | 224 | } |
223 | return as; | 225 | return as; |
224 | } | 226 | } |
225 | 227 | ||
226 | static void free_async(struct async *as) | 228 | static void free_async(struct async *as) |
@@ -234,52 +236,54 @@ static void free_async(struct async *as) | |||
234 | 236 | ||
235 | static inline void async_newpending(struct async *as) | 237 | static inline void async_newpending(struct async *as) |
236 | { | 238 | { |
237 | struct dev_state *ps = as->ps; | 239 | struct dev_state *ps = as->ps; |
238 | unsigned long flags; | 240 | unsigned long flags; |
239 | 241 | ||
240 | spin_lock_irqsave(&ps->lock, flags); | 242 | spin_lock_irqsave(&ps->lock, flags); |
241 | list_add_tail(&as->asynclist, &ps->async_pending); | 243 | list_add_tail(&as->asynclist, &ps->async_pending); |
242 | spin_unlock_irqrestore(&ps->lock, flags); | 244 | spin_unlock_irqrestore(&ps->lock, flags); |
243 | } | 245 | } |
244 | 246 | ||
245 | static inline void async_removepending(struct async *as) | 247 | static inline void async_removepending(struct async *as) |
246 | { | 248 | { |
247 | struct dev_state *ps = as->ps; | 249 | struct dev_state *ps = as->ps; |
248 | unsigned long flags; | 250 | unsigned long flags; |
249 | 251 | ||
250 | spin_lock_irqsave(&ps->lock, flags); | 252 | spin_lock_irqsave(&ps->lock, flags); |
251 | list_del_init(&as->asynclist); | 253 | list_del_init(&as->asynclist); |
252 | spin_unlock_irqrestore(&ps->lock, flags); | 254 | spin_unlock_irqrestore(&ps->lock, flags); |
253 | } | 255 | } |
254 | 256 | ||
255 | static inline struct async *async_getcompleted(struct dev_state *ps) | 257 | static inline struct async *async_getcompleted(struct dev_state *ps) |
256 | { | 258 | { |
257 | unsigned long flags; | 259 | unsigned long flags; |
258 | struct async *as = NULL; | 260 | struct async *as = NULL; |
259 | 261 | ||
260 | spin_lock_irqsave(&ps->lock, flags); | 262 | spin_lock_irqsave(&ps->lock, flags); |
261 | if (!list_empty(&ps->async_completed)) { | 263 | if (!list_empty(&ps->async_completed)) { |
262 | as = list_entry(ps->async_completed.next, struct async, asynclist); | 264 | as = list_entry(ps->async_completed.next, struct async, |
263 | list_del_init(&as->asynclist); | 265 | asynclist); |
264 | } | 266 | list_del_init(&as->asynclist); |
265 | spin_unlock_irqrestore(&ps->lock, flags); | 267 | } |
266 | return as; | 268 | spin_unlock_irqrestore(&ps->lock, flags); |
269 | return as; | ||
267 | } | 270 | } |
268 | 271 | ||
269 | static inline struct async *async_getpending(struct dev_state *ps, void __user *userurb) | 272 | static inline struct async *async_getpending(struct dev_state *ps, |
273 | void __user *userurb) | ||
270 | { | 274 | { |
271 | unsigned long flags; | 275 | unsigned long flags; |
272 | struct async *as; | 276 | struct async *as; |
273 | 277 | ||
274 | spin_lock_irqsave(&ps->lock, flags); | 278 | spin_lock_irqsave(&ps->lock, flags); |
275 | list_for_each_entry(as, &ps->async_pending, asynclist) | 279 | list_for_each_entry(as, &ps->async_pending, asynclist) |
276 | if (as->userurb == userurb) { | 280 | if (as->userurb == userurb) { |
277 | list_del_init(&as->asynclist); | 281 | list_del_init(&as->asynclist); |
278 | spin_unlock_irqrestore(&ps->lock, flags); | 282 | spin_unlock_irqrestore(&ps->lock, flags); |
279 | return as; | 283 | return as; |
280 | } | 284 | } |
281 | spin_unlock_irqrestore(&ps->lock, flags); | 285 | spin_unlock_irqrestore(&ps->lock, flags); |
282 | return NULL; | 286 | return NULL; |
283 | } | 287 | } |
284 | 288 | ||
285 | static void snoop_urb(struct urb *urb, void __user *userurb) | 289 | static void snoop_urb(struct urb *urb, void __user *userurb) |
@@ -298,19 +302,19 @@ static void snoop_urb(struct urb *urb, void __user *userurb) | |||
298 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); | 302 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); |
299 | dev_info(&urb->dev->dev, "data: "); | 303 | dev_info(&urb->dev->dev, "data: "); |
300 | for (j = 0; j < urb->transfer_buffer_length; ++j) | 304 | for (j = 0; j < urb->transfer_buffer_length; ++j) |
301 | printk ("%02x ", data[j]); | 305 | printk("%02x ", data[j]); |
302 | printk("\n"); | 306 | printk("\n"); |
303 | } | 307 | } |
304 | 308 | ||
305 | static void async_completed(struct urb *urb) | 309 | static void async_completed(struct urb *urb) |
306 | { | 310 | { |
307 | struct async *as = urb->context; | 311 | struct async *as = urb->context; |
308 | struct dev_state *ps = as->ps; | 312 | struct dev_state *ps = as->ps; |
309 | struct siginfo sinfo; | 313 | struct siginfo sinfo; |
310 | 314 | ||
311 | spin_lock(&ps->lock); | 315 | spin_lock(&ps->lock); |
312 | list_move_tail(&as->asynclist, &ps->async_completed); | 316 | list_move_tail(&as->asynclist, &ps->async_completed); |
313 | spin_unlock(&ps->lock); | 317 | spin_unlock(&ps->lock); |
314 | as->status = urb->status; | 318 | as->status = urb->status; |
315 | if (as->signr) { | 319 | if (as->signr) { |
316 | sinfo.si_signo = as->signr; | 320 | sinfo.si_signo = as->signr; |
@@ -325,7 +329,7 @@ static void async_completed(struct urb *urb) | |||
325 | wake_up(&ps->wait); | 329 | wake_up(&ps->wait); |
326 | } | 330 | } |
327 | 331 | ||
328 | static void destroy_async (struct dev_state *ps, struct list_head *list) | 332 | static void destroy_async(struct dev_state *ps, struct list_head *list) |
329 | { | 333 | { |
330 | struct async *as; | 334 | struct async *as; |
331 | unsigned long flags; | 335 | unsigned long flags; |
@@ -348,7 +352,8 @@ static void destroy_async (struct dev_state *ps, struct list_head *list) | |||
348 | } | 352 | } |
349 | } | 353 | } |
350 | 354 | ||
351 | static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum) | 355 | static void destroy_async_on_interface(struct dev_state *ps, |
356 | unsigned int ifnum) | ||
352 | { | 357 | { |
353 | struct list_head *p, *q, hitlist; | 358 | struct list_head *p, *q, hitlist; |
354 | unsigned long flags; | 359 | unsigned long flags; |
@@ -364,7 +369,7 @@ static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum | |||
364 | 369 | ||
365 | static inline void destroy_all_async(struct dev_state *ps) | 370 | static inline void destroy_all_async(struct dev_state *ps) |
366 | { | 371 | { |
367 | destroy_async(ps, &ps->async_pending); | 372 | destroy_async(ps, &ps->async_pending); |
368 | } | 373 | } |
369 | 374 | ||
370 | /* | 375 | /* |
@@ -373,15 +378,15 @@ static inline void destroy_all_async(struct dev_state *ps) | |||
373 | * they're also undone when devices disconnect. | 378 | * they're also undone when devices disconnect. |
374 | */ | 379 | */ |
375 | 380 | ||
376 | static int driver_probe (struct usb_interface *intf, | 381 | static int driver_probe(struct usb_interface *intf, |
377 | const struct usb_device_id *id) | 382 | const struct usb_device_id *id) |
378 | { | 383 | { |
379 | return -ENODEV; | 384 | return -ENODEV; |
380 | } | 385 | } |
381 | 386 | ||
382 | static void driver_disconnect(struct usb_interface *intf) | 387 | static void driver_disconnect(struct usb_interface *intf) |
383 | { | 388 | { |
384 | struct dev_state *ps = usb_get_intfdata (intf); | 389 | struct dev_state *ps = usb_get_intfdata(intf); |
385 | unsigned int ifnum = intf->altsetting->desc.bInterfaceNumber; | 390 | unsigned int ifnum = intf->altsetting->desc.bInterfaceNumber; |
386 | 391 | ||
387 | if (!ps) | 392 | if (!ps) |
@@ -396,7 +401,7 @@ static void driver_disconnect(struct usb_interface *intf) | |||
396 | else | 401 | else |
397 | warn("interface number %u out of range", ifnum); | 402 | warn("interface number %u out of range", ifnum); |
398 | 403 | ||
399 | usb_set_intfdata (intf, NULL); | 404 | usb_set_intfdata(intf, NULL); |
400 | 405 | ||
401 | /* force async requests to complete */ | 406 | /* force async requests to complete */ |
402 | destroy_async_on_interface(ps, ifnum); | 407 | destroy_async_on_interface(ps, ifnum); |
@@ -474,15 +479,16 @@ static int checkintf(struct dev_state *ps, unsigned int ifnum) | |||
474 | if (test_bit(ifnum, &ps->ifclaimed)) | 479 | if (test_bit(ifnum, &ps->ifclaimed)) |
475 | return 0; | 480 | return 0; |
476 | /* if not yet claimed, claim it for the driver */ | 481 | /* if not yet claimed, claim it for the driver */ |
477 | dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim interface %u before use\n", | 482 | dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim " |
478 | task_pid_nr(current), current->comm, ifnum); | 483 | "interface %u before use\n", task_pid_nr(current), |
484 | current->comm, ifnum); | ||
479 | return claimintf(ps, ifnum); | 485 | return claimintf(ps, ifnum); |
480 | } | 486 | } |
481 | 487 | ||
482 | static int findintfep(struct usb_device *dev, unsigned int ep) | 488 | static int findintfep(struct usb_device *dev, unsigned int ep) |
483 | { | 489 | { |
484 | unsigned int i, j, e; | 490 | unsigned int i, j, e; |
485 | struct usb_interface *intf; | 491 | struct usb_interface *intf; |
486 | struct usb_host_interface *alts; | 492 | struct usb_host_interface *alts; |
487 | struct usb_endpoint_descriptor *endpt; | 493 | struct usb_endpoint_descriptor *endpt; |
488 | 494 | ||
@@ -493,7 +499,7 @@ static int findintfep(struct usb_device *dev, unsigned int ep) | |||
493 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { | 499 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { |
494 | intf = dev->actconfig->interface[i]; | 500 | intf = dev->actconfig->interface[i]; |
495 | for (j = 0; j < intf->num_altsetting; j++) { | 501 | for (j = 0; j < intf->num_altsetting; j++) { |
496 | alts = &intf->altsetting[j]; | 502 | alts = &intf->altsetting[j]; |
497 | for (e = 0; e < alts->desc.bNumEndpoints; e++) { | 503 | for (e = 0; e < alts->desc.bNumEndpoints; e++) { |
498 | endpt = &alts->endpoint[e].desc; | 504 | endpt = &alts->endpoint[e].desc; |
499 | if (endpt->bEndpointAddress == ep) | 505 | if (endpt->bEndpointAddress == ep) |
@@ -501,10 +507,11 @@ static int findintfep(struct usb_device *dev, unsigned int ep) | |||
501 | } | 507 | } |
502 | } | 508 | } |
503 | } | 509 | } |
504 | return -ENOENT; | 510 | return -ENOENT; |
505 | } | 511 | } |
506 | 512 | ||
507 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned int index) | 513 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, |
514 | unsigned int index) | ||
508 | { | 515 | { |
509 | int ret = 0; | 516 | int ret = 0; |
510 | 517 | ||
@@ -517,7 +524,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
517 | index &= 0xff; | 524 | index &= 0xff; |
518 | switch (requesttype & USB_RECIP_MASK) { | 525 | switch (requesttype & USB_RECIP_MASK) { |
519 | case USB_RECIP_ENDPOINT: | 526 | case USB_RECIP_ENDPOINT: |
520 | if ((ret = findintfep(ps->dev, index)) >= 0) | 527 | ret = findintfep(ps->dev, index); |
528 | if (ret >= 0) | ||
521 | ret = checkintf(ps, ret); | 529 | ret = checkintf(ps, ret); |
522 | break; | 530 | break; |
523 | 531 | ||
@@ -561,7 +569,8 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
561 | mutex_lock(&usbfs_mutex); | 569 | mutex_lock(&usbfs_mutex); |
562 | 570 | ||
563 | ret = -ENOMEM; | 571 | ret = -ENOMEM; |
564 | if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL))) | 572 | ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL); |
573 | if (!ps) | ||
565 | goto out; | 574 | goto out; |
566 | 575 | ||
567 | ret = -ENOENT; | 576 | ret = -ENOENT; |
@@ -642,15 +651,18 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
642 | 651 | ||
643 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 652 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
644 | return -EFAULT; | 653 | return -EFAULT; |
645 | if ((ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex))) | 654 | ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); |
655 | if (ret) | ||
646 | return ret; | 656 | return ret; |
647 | if (ctrl.wLength > PAGE_SIZE) | 657 | if (ctrl.wLength > PAGE_SIZE) |
648 | return -EINVAL; | 658 | return -EINVAL; |
649 | if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL))) | 659 | tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); |
660 | if (!tbuf) | ||
650 | return -ENOMEM; | 661 | return -ENOMEM; |
651 | tmo = ctrl.timeout; | 662 | tmo = ctrl.timeout; |
652 | if (ctrl.bRequestType & 0x80) { | 663 | if (ctrl.bRequestType & 0x80) { |
653 | if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, ctrl.wLength)) { | 664 | if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, |
665 | ctrl.wLength)) { | ||
654 | free_page((unsigned long)tbuf); | 666 | free_page((unsigned long)tbuf); |
655 | return -EINVAL; | 667 | return -EINVAL; |
656 | } | 668 | } |
@@ -661,14 +673,15 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
661 | ctrl.wIndex, ctrl.wLength); | 673 | ctrl.wIndex, ctrl.wLength); |
662 | 674 | ||
663 | usb_unlock_device(dev); | 675 | usb_unlock_device(dev); |
664 | i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, | 676 | i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, |
665 | ctrl.wValue, ctrl.wIndex, tbuf, ctrl.wLength, tmo); | 677 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
678 | tbuf, ctrl.wLength, tmo); | ||
666 | usb_lock_device(dev); | 679 | usb_lock_device(dev); |
667 | if ((i > 0) && ctrl.wLength) { | 680 | if ((i > 0) && ctrl.wLength) { |
668 | if (usbfs_snoop) { | 681 | if (usbfs_snoop) { |
669 | dev_info(&dev->dev, "control read: data "); | 682 | dev_info(&dev->dev, "control read: data "); |
670 | for (j = 0; j < i; ++j) | 683 | for (j = 0; j < i; ++j) |
671 | printk("%02x ", (unsigned char)(tbuf)[j]); | 684 | printk("%02x ", (u8)(tbuf)[j]); |
672 | printk("\n"); | 685 | printk("\n"); |
673 | } | 686 | } |
674 | if (copy_to_user(ctrl.data, tbuf, i)) { | 687 | if (copy_to_user(ctrl.data, tbuf, i)) { |
@@ -695,12 +708,13 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
695 | printk("\n"); | 708 | printk("\n"); |
696 | } | 709 | } |
697 | usb_unlock_device(dev); | 710 | usb_unlock_device(dev); |
698 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, | 711 | i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, |
699 | ctrl.wValue, ctrl.wIndex, tbuf, ctrl.wLength, tmo); | 712 | ctrl.bRequestType, ctrl.wValue, ctrl.wIndex, |
713 | tbuf, ctrl.wLength, tmo); | ||
700 | usb_lock_device(dev); | 714 | usb_lock_device(dev); |
701 | } | 715 | } |
702 | free_page((unsigned long)tbuf); | 716 | free_page((unsigned long)tbuf); |
703 | if (i<0 && i != -EPIPE) { | 717 | if (i < 0 && i != -EPIPE) { |
704 | dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " | 718 | dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " |
705 | "failed cmd %s rqt %u rq %u len %u ret %d\n", | 719 | "failed cmd %s rqt %u rq %u len %u ret %d\n", |
706 | current->comm, ctrl.bRequestType, ctrl.bRequest, | 720 | current->comm, ctrl.bRequestType, ctrl.bRequest, |
@@ -720,9 +734,11 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
720 | 734 | ||
721 | if (copy_from_user(&bulk, arg, sizeof(bulk))) | 735 | if (copy_from_user(&bulk, arg, sizeof(bulk))) |
722 | return -EFAULT; | 736 | return -EFAULT; |
723 | if ((ret = findintfep(ps->dev, bulk.ep)) < 0) | 737 | ret = findintfep(ps->dev, bulk.ep); |
738 | if (ret < 0) | ||
724 | return ret; | 739 | return ret; |
725 | if ((ret = checkintf(ps, ret))) | 740 | ret = checkintf(ps, ret); |
741 | if (ret) | ||
726 | return ret; | 742 | return ret; |
727 | if (bulk.ep & USB_DIR_IN) | 743 | if (bulk.ep & USB_DIR_IN) |
728 | pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f); | 744 | pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f); |
@@ -750,7 +766,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
750 | if (usbfs_snoop) { | 766 | if (usbfs_snoop) { |
751 | dev_info(&dev->dev, "bulk read: data "); | 767 | dev_info(&dev->dev, "bulk read: data "); |
752 | for (j = 0; j < len2; ++j) | 768 | for (j = 0; j < len2; ++j) |
753 | printk("%02x ", (unsigned char)(tbuf)[j]); | 769 | printk("%02x ", (u8)(tbuf)[j]); |
754 | printk("\n"); | 770 | printk("\n"); |
755 | } | 771 | } |
756 | if (copy_to_user(bulk.data, tbuf, len2)) { | 772 | if (copy_to_user(bulk.data, tbuf, len2)) { |
@@ -790,9 +806,11 @@ static int proc_resetep(struct dev_state *ps, void __user *arg) | |||
790 | 806 | ||
791 | if (get_user(ep, (unsigned int __user *)arg)) | 807 | if (get_user(ep, (unsigned int __user *)arg)) |
792 | return -EFAULT; | 808 | return -EFAULT; |
793 | if ((ret = findintfep(ps->dev, ep)) < 0) | 809 | ret = findintfep(ps->dev, ep); |
810 | if (ret < 0) | ||
794 | return ret; | 811 | return ret; |
795 | if ((ret = checkintf(ps, ret))) | 812 | ret = checkintf(ps, ret); |
813 | if (ret) | ||
796 | return ret; | 814 | return ret; |
797 | usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0); | 815 | usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0); |
798 | return 0; | 816 | return 0; |
@@ -806,18 +824,19 @@ static int proc_clearhalt(struct dev_state *ps, void __user *arg) | |||
806 | 824 | ||
807 | if (get_user(ep, (unsigned int __user *)arg)) | 825 | if (get_user(ep, (unsigned int __user *)arg)) |
808 | return -EFAULT; | 826 | return -EFAULT; |
809 | if ((ret = findintfep(ps->dev, ep)) < 0) | 827 | ret = findintfep(ps->dev, ep); |
828 | if (ret < 0) | ||
810 | return ret; | 829 | return ret; |
811 | if ((ret = checkintf(ps, ret))) | 830 | ret = checkintf(ps, ret); |
831 | if (ret) | ||
812 | return ret; | 832 | return ret; |
813 | if (ep & USB_DIR_IN) | 833 | if (ep & USB_DIR_IN) |
814 | pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f); | 834 | pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f); |
815 | else | 835 | else |
816 | pipe = usb_sndbulkpipe(ps->dev, ep & 0x7f); | 836 | pipe = usb_sndbulkpipe(ps->dev, ep & 0x7f); |
817 | 837 | ||
818 | return usb_clear_halt(ps->dev, pipe); | 838 | return usb_clear_halt(ps->dev, pipe); |
819 | } | 839 | } |
820 | |||
821 | 840 | ||
822 | static int proc_getdriver(struct dev_state *ps, void __user *arg) | 841 | static int proc_getdriver(struct dev_state *ps, void __user *arg) |
823 | { | 842 | { |
@@ -871,23 +890,23 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) | |||
871 | { | 890 | { |
872 | int u; | 891 | int u; |
873 | int status = 0; | 892 | int status = 0; |
874 | struct usb_host_config *actconfig; | 893 | struct usb_host_config *actconfig; |
875 | 894 | ||
876 | if (get_user(u, (int __user *)arg)) | 895 | if (get_user(u, (int __user *)arg)) |
877 | return -EFAULT; | 896 | return -EFAULT; |
878 | 897 | ||
879 | actconfig = ps->dev->actconfig; | 898 | actconfig = ps->dev->actconfig; |
880 | 899 | ||
881 | /* Don't touch the device if any interfaces are claimed. | 900 | /* Don't touch the device if any interfaces are claimed. |
882 | * It could interfere with other drivers' operations, and if | 901 | * It could interfere with other drivers' operations, and if |
883 | * an interface is claimed by usbfs it could easily deadlock. | 902 | * an interface is claimed by usbfs it could easily deadlock. |
884 | */ | 903 | */ |
885 | if (actconfig) { | 904 | if (actconfig) { |
886 | int i; | 905 | int i; |
887 | 906 | ||
888 | for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) { | 907 | for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) { |
889 | if (usb_interface_claimed(actconfig->interface[i])) { | 908 | if (usb_interface_claimed(actconfig->interface[i])) { |
890 | dev_warn (&ps->dev->dev, | 909 | dev_warn(&ps->dev->dev, |
891 | "usbfs: interface %d claimed by %s " | 910 | "usbfs: interface %d claimed by %s " |
892 | "while '%s' sets config #%d\n", | 911 | "while '%s' sets config #%d\n", |
893 | actconfig->interface[i] | 912 | actconfig->interface[i] |
@@ -896,11 +915,11 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) | |||
896 | actconfig->interface[i] | 915 | actconfig->interface[i] |
897 | ->dev.driver->name, | 916 | ->dev.driver->name, |
898 | current->comm, u); | 917 | current->comm, u); |
899 | status = -EBUSY; | 918 | status = -EBUSY; |
900 | break; | 919 | break; |
901 | } | 920 | } |
902 | } | 921 | } |
903 | } | 922 | } |
904 | 923 | ||
905 | /* SET_CONFIGURATION is often abused as a "cheap" driver reset, | 924 | /* SET_CONFIGURATION is often abused as a "cheap" driver reset, |
906 | * so avoid usb_set_configuration()'s kick to sysfs | 925 | * so avoid usb_set_configuration()'s kick to sysfs |
@@ -916,8 +935,8 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) | |||
916 | } | 935 | } |
917 | 936 | ||
918 | static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | 937 | static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, |
919 | struct usbdevfs_iso_packet_desc __user *iso_frame_desc, | 938 | struct usbdevfs_iso_packet_desc __user *iso_frame_desc, |
920 | void __user *arg) | 939 | void __user *arg) |
921 | { | 940 | { |
922 | struct usbdevfs_iso_packet_desc *isopkt = NULL; | 941 | struct usbdevfs_iso_packet_desc *isopkt = NULL; |
923 | struct usb_host_endpoint *ep; | 942 | struct usb_host_endpoint *ep; |
@@ -932,12 +951,16 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
932 | return -EINVAL; | 951 | return -EINVAL; |
933 | if (!uurb->buffer) | 952 | if (!uurb->buffer) |
934 | return -EINVAL; | 953 | return -EINVAL; |
935 | if (uurb->signr != 0 && (uurb->signr < SIGRTMIN || uurb->signr > SIGRTMAX)) | 954 | if (uurb->signr != 0 && (uurb->signr < SIGRTMIN || |
955 | uurb->signr > SIGRTMAX)) | ||
936 | return -EINVAL; | 956 | return -EINVAL; |
937 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { | 957 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && |
938 | if ((ifnum = findintfep(ps->dev, uurb->endpoint)) < 0) | 958 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { |
959 | ifnum = findintfep(ps->dev, uurb->endpoint); | ||
960 | if (ifnum < 0) | ||
939 | return ifnum; | 961 | return ifnum; |
940 | if ((ret = checkintf(ps, ifnum))) | 962 | ret = checkintf(ps, ifnum); |
963 | if (ret) | ||
941 | return ret; | 964 | return ret; |
942 | } | 965 | } |
943 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { | 966 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { |
@@ -953,10 +976,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
953 | case USBDEVFS_URB_TYPE_CONTROL: | 976 | case USBDEVFS_URB_TYPE_CONTROL: |
954 | if (!usb_endpoint_xfer_control(&ep->desc)) | 977 | if (!usb_endpoint_xfer_control(&ep->desc)) |
955 | return -EINVAL; | 978 | return -EINVAL; |
956 | /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ | 979 | /* min 8 byte setup packet, |
957 | if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) | 980 | * max 8 byte setup plus an arbitrary data stage */ |
981 | if (uurb->buffer_length < 8 || | ||
982 | uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) | ||
958 | return -EINVAL; | 983 | return -EINVAL; |
959 | if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) | 984 | dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); |
985 | if (!dr) | ||
960 | return -ENOMEM; | 986 | return -ENOMEM; |
961 | if (copy_from_user(dr, uurb->buffer, 8)) { | 987 | if (copy_from_user(dr, uurb->buffer, 8)) { |
962 | kfree(dr); | 988 | kfree(dr); |
@@ -966,7 +992,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
966 | kfree(dr); | 992 | kfree(dr); |
967 | return -EINVAL; | 993 | return -EINVAL; |
968 | } | 994 | } |
969 | if ((ret = check_ctrlrecip(ps, dr->bRequestType, le16_to_cpup(&dr->wIndex)))) { | 995 | ret = check_ctrlrecip(ps, dr->bRequestType, |
996 | le16_to_cpup(&dr->wIndex)); | ||
997 | if (ret) { | ||
970 | kfree(dr); | 998 | kfree(dr); |
971 | return ret; | 999 | return ret; |
972 | } | 1000 | } |
@@ -1012,11 +1040,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1012 | 1040 | ||
1013 | case USBDEVFS_URB_TYPE_ISO: | 1041 | case USBDEVFS_URB_TYPE_ISO: |
1014 | /* arbitrary limit */ | 1042 | /* arbitrary limit */ |
1015 | if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128) | 1043 | if (uurb->number_of_packets < 1 || |
1044 | uurb->number_of_packets > 128) | ||
1016 | return -EINVAL; | 1045 | return -EINVAL; |
1017 | if (!usb_endpoint_xfer_isoc(&ep->desc)) | 1046 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
1018 | return -EINVAL; | 1047 | return -EINVAL; |
1019 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; | 1048 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * |
1049 | uurb->number_of_packets; | ||
1020 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) | 1050 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) |
1021 | return -ENOMEM; | 1051 | return -ENOMEM; |
1022 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { | 1052 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { |
@@ -1024,7 +1054,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1024 | return -EFAULT; | 1054 | return -EFAULT; |
1025 | } | 1055 | } |
1026 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1056 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { |
1027 | /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */ | 1057 | /* arbitrary limit, |
1058 | * sufficient for USB 2.0 high-bandwidth iso */ | ||
1028 | if (isopkt[u].length > 8192) { | 1059 | if (isopkt[u].length > 8192) { |
1029 | kfree(isopkt); | 1060 | kfree(isopkt); |
1030 | return -EINVAL; | 1061 | return -EINVAL; |
@@ -1054,25 +1085,27 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1054 | default: | 1085 | default: |
1055 | return -EINVAL; | 1086 | return -EINVAL; |
1056 | } | 1087 | } |
1057 | if (!(as = alloc_async(uurb->number_of_packets))) { | 1088 | as = alloc_async(uurb->number_of_packets); |
1089 | if (!as) { | ||
1058 | kfree(isopkt); | 1090 | kfree(isopkt); |
1059 | kfree(dr); | 1091 | kfree(dr); |
1060 | return -ENOMEM; | 1092 | return -ENOMEM; |
1061 | } | 1093 | } |
1062 | if (!(as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL))) { | 1094 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL); |
1095 | if (!as->urb->transfer_buffer) { | ||
1063 | kfree(isopkt); | 1096 | kfree(isopkt); |
1064 | kfree(dr); | 1097 | kfree(dr); |
1065 | free_async(as); | 1098 | free_async(as); |
1066 | return -ENOMEM; | 1099 | return -ENOMEM; |
1067 | } | 1100 | } |
1068 | as->urb->dev = ps->dev; | 1101 | as->urb->dev = ps->dev; |
1069 | as->urb->pipe = (uurb->type << 30) | | 1102 | as->urb->pipe = (uurb->type << 30) | |
1070 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | | 1103 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | |
1071 | (uurb->endpoint & USB_DIR_IN); | 1104 | (uurb->endpoint & USB_DIR_IN); |
1072 | as->urb->transfer_flags = uurb->flags | | 1105 | as->urb->transfer_flags = uurb->flags | |
1073 | (is_in ? URB_DIR_IN : URB_DIR_OUT); | 1106 | (is_in ? URB_DIR_IN : URB_DIR_OUT); |
1074 | as->urb->transfer_buffer_length = uurb->buffer_length; | 1107 | as->urb->transfer_buffer_length = uurb->buffer_length; |
1075 | as->urb->setup_packet = (unsigned char*)dr; | 1108 | as->urb->setup_packet = (unsigned char *)dr; |
1076 | as->urb->start_frame = uurb->start_frame; | 1109 | as->urb->start_frame = uurb->start_frame; |
1077 | as->urb->number_of_packets = uurb->number_of_packets; | 1110 | as->urb->number_of_packets = uurb->number_of_packets; |
1078 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || | 1111 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || |
@@ -1080,8 +1113,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1080 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); | 1113 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); |
1081 | else | 1114 | else |
1082 | as->urb->interval = ep->desc.bInterval; | 1115 | as->urb->interval = ep->desc.bInterval; |
1083 | as->urb->context = as; | 1116 | as->urb->context = as; |
1084 | as->urb->complete = async_completed; | 1117 | as->urb->complete = async_completed; |
1085 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1118 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { |
1086 | as->urb->iso_frame_desc[u].offset = totlen; | 1119 | as->urb->iso_frame_desc[u].offset = totlen; |
1087 | as->urb->iso_frame_desc[u].length = isopkt[u].length; | 1120 | as->urb->iso_frame_desc[u].length = isopkt[u].length; |
@@ -1089,7 +1122,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1089 | } | 1122 | } |
1090 | kfree(isopkt); | 1123 | kfree(isopkt); |
1091 | as->ps = ps; | 1124 | as->ps = ps; |
1092 | as->userurb = arg; | 1125 | as->userurb = arg; |
1093 | if (uurb->endpoint & USB_DIR_IN) | 1126 | if (uurb->endpoint & USB_DIR_IN) |
1094 | as->userbuffer = uurb->buffer; | 1127 | as->userbuffer = uurb->buffer; |
1095 | else | 1128 | else |
@@ -1108,14 +1141,15 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1108 | } | 1141 | } |
1109 | } | 1142 | } |
1110 | snoop_urb(as->urb, as->userurb); | 1143 | snoop_urb(as->urb, as->userurb); |
1111 | async_newpending(as); | 1144 | async_newpending(as); |
1112 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { | 1145 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { |
1113 | dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret); | 1146 | dev_printk(KERN_DEBUG, &ps->dev->dev, |
1114 | async_removepending(as); | 1147 | "usbfs: usb_submit_urb returned %d\n", ret); |
1115 | free_async(as); | 1148 | async_removepending(as); |
1116 | return ret; | 1149 | free_async(as); |
1117 | } | 1150 | return ret; |
1118 | return 0; | 1151 | } |
1152 | return 0; | ||
1119 | } | 1153 | } |
1120 | 1154 | ||
1121 | static int proc_submiturb(struct dev_state *ps, void __user *arg) | 1155 | static int proc_submiturb(struct dev_state *ps, void __user *arg) |
@@ -1125,7 +1159,9 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg) | |||
1125 | if (copy_from_user(&uurb, arg, sizeof(uurb))) | 1159 | if (copy_from_user(&uurb, arg, sizeof(uurb))) |
1126 | return -EFAULT; | 1160 | return -EFAULT; |
1127 | 1161 | ||
1128 | return proc_do_submiturb(ps, &uurb, (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), arg); | 1162 | return proc_do_submiturb(ps, &uurb, |
1163 | (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), | ||
1164 | arg); | ||
1129 | } | 1165 | } |
1130 | 1166 | ||
1131 | static int proc_unlinkurb(struct dev_state *ps, void __user *arg) | 1167 | static int proc_unlinkurb(struct dev_state *ps, void __user *arg) |
@@ -1147,7 +1183,8 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1147 | unsigned int i; | 1183 | unsigned int i; |
1148 | 1184 | ||
1149 | if (as->userbuffer) | 1185 | if (as->userbuffer) |
1150 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1186 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1187 | urb->transfer_buffer_length)) | ||
1151 | return -EFAULT; | 1188 | return -EFAULT; |
1152 | if (put_user(as->status, &userurb->status)) | 1189 | if (put_user(as->status, &userurb->status)) |
1153 | return -EFAULT; | 1190 | return -EFAULT; |
@@ -1174,16 +1211,17 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1174 | return 0; | 1211 | return 0; |
1175 | } | 1212 | } |
1176 | 1213 | ||
1177 | static struct async* reap_as(struct dev_state *ps) | 1214 | static struct async *reap_as(struct dev_state *ps) |
1178 | { | 1215 | { |
1179 | DECLARE_WAITQUEUE(wait, current); | 1216 | DECLARE_WAITQUEUE(wait, current); |
1180 | struct async *as = NULL; | 1217 | struct async *as = NULL; |
1181 | struct usb_device *dev = ps->dev; | 1218 | struct usb_device *dev = ps->dev; |
1182 | 1219 | ||
1183 | add_wait_queue(&ps->wait, &wait); | 1220 | add_wait_queue(&ps->wait, &wait); |
1184 | for (;;) { | 1221 | for (;;) { |
1185 | __set_current_state(TASK_INTERRUPTIBLE); | 1222 | __set_current_state(TASK_INTERRUPTIBLE); |
1186 | if ((as = async_getcompleted(ps))) | 1223 | as = async_getcompleted(ps); |
1224 | if (as) | ||
1187 | break; | 1225 | break; |
1188 | if (signal_pending(current)) | 1226 | if (signal_pending(current)) |
1189 | break; | 1227 | break; |
@@ -1247,10 +1285,12 @@ static int proc_submiturb_compat(struct dev_state *ps, void __user *arg) | |||
1247 | { | 1285 | { |
1248 | struct usbdevfs_urb uurb; | 1286 | struct usbdevfs_urb uurb; |
1249 | 1287 | ||
1250 | if (get_urb32(&uurb,(struct usbdevfs_urb32 __user *)arg)) | 1288 | if (get_urb32(&uurb, (struct usbdevfs_urb32 __user *)arg)) |
1251 | return -EFAULT; | 1289 | return -EFAULT; |
1252 | 1290 | ||
1253 | return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg); | 1291 | return proc_do_submiturb(ps, &uurb, |
1292 | ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, | ||
1293 | arg); | ||
1254 | } | 1294 | } |
1255 | 1295 | ||
1256 | static int processcompl_compat(struct async *as, void __user * __user *arg) | 1296 | static int processcompl_compat(struct async *as, void __user * __user *arg) |
@@ -1261,7 +1301,8 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
1261 | unsigned int i; | 1301 | unsigned int i; |
1262 | 1302 | ||
1263 | if (as->userbuffer) | 1303 | if (as->userbuffer) |
1264 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1304 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1305 | urb->transfer_buffer_length)) | ||
1265 | return -EFAULT; | 1306 | return -EFAULT; |
1266 | if (put_user(as->status, &userurb->status)) | 1307 | if (put_user(as->status, &userurb->status)) |
1267 | return -EFAULT; | 1308 | return -EFAULT; |
@@ -1352,16 +1393,16 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1352 | struct usb_driver *driver = NULL; | 1393 | struct usb_driver *driver = NULL; |
1353 | 1394 | ||
1354 | /* alloc buffer */ | 1395 | /* alloc buffer */ |
1355 | if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) { | 1396 | if ((size = _IOC_SIZE(ctl->ioctl_code)) > 0) { |
1356 | if ((buf = kmalloc (size, GFP_KERNEL)) == NULL) | 1397 | if ((buf = kmalloc(size, GFP_KERNEL)) == NULL) |
1357 | return -ENOMEM; | 1398 | return -ENOMEM; |
1358 | if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { | 1399 | if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { |
1359 | if (copy_from_user (buf, ctl->data, size)) { | 1400 | if (copy_from_user(buf, ctl->data, size)) { |
1360 | kfree(buf); | 1401 | kfree(buf); |
1361 | return -EFAULT; | 1402 | return -EFAULT; |
1362 | } | 1403 | } |
1363 | } else { | 1404 | } else { |
1364 | memset (buf, 0, size); | 1405 | memset(buf, 0, size); |
1365 | } | 1406 | } |
1366 | } | 1407 | } |
1367 | 1408 | ||
@@ -1372,15 +1413,15 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1372 | 1413 | ||
1373 | if (ps->dev->state != USB_STATE_CONFIGURED) | 1414 | if (ps->dev->state != USB_STATE_CONFIGURED) |
1374 | retval = -EHOSTUNREACH; | 1415 | retval = -EHOSTUNREACH; |
1375 | else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno))) | 1416 | else if (!(intf = usb_ifnum_to_if(ps->dev, ctl->ifno))) |
1376 | retval = -EINVAL; | 1417 | retval = -EINVAL; |
1377 | else switch (ctl->ioctl_code) { | 1418 | else switch (ctl->ioctl_code) { |
1378 | 1419 | ||
1379 | /* disconnect kernel driver from interface */ | 1420 | /* disconnect kernel driver from interface */ |
1380 | case USBDEVFS_DISCONNECT: | 1421 | case USBDEVFS_DISCONNECT: |
1381 | if (intf->dev.driver) { | 1422 | if (intf->dev.driver) { |
1382 | driver = to_usb_driver(intf->dev.driver); | 1423 | driver = to_usb_driver(intf->dev.driver); |
1383 | dev_dbg (&intf->dev, "disconnect by usbfs\n"); | 1424 | dev_dbg(&intf->dev, "disconnect by usbfs\n"); |
1384 | usb_driver_release_interface(driver, intf); | 1425 | usb_driver_release_interface(driver, intf); |
1385 | } else | 1426 | } else |
1386 | retval = -ENODATA; | 1427 | retval = -ENODATA; |
@@ -1401,7 +1442,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1401 | if (driver == NULL || driver->ioctl == NULL) { | 1442 | if (driver == NULL || driver->ioctl == NULL) { |
1402 | retval = -ENOTTY; | 1443 | retval = -ENOTTY; |
1403 | } else { | 1444 | } else { |
1404 | retval = driver->ioctl (intf, ctl->ioctl_code, buf); | 1445 | retval = driver->ioctl(intf, ctl->ioctl_code, buf); |
1405 | if (retval == -ENOIOCTLCMD) | 1446 | if (retval == -ENOIOCTLCMD) |
1406 | retval = -ENOTTY; | 1447 | retval = -ENOTTY; |
1407 | } | 1448 | } |
@@ -1409,9 +1450,9 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1409 | 1450 | ||
1410 | /* cleanup and return */ | 1451 | /* cleanup and return */ |
1411 | if (retval >= 0 | 1452 | if (retval >= 0 |
1412 | && (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0 | 1453 | && (_IOC_DIR(ctl->ioctl_code) & _IOC_READ) != 0 |
1413 | && size > 0 | 1454 | && size > 0 |
1414 | && copy_to_user (ctl->data, buf, size) != 0) | 1455 | && copy_to_user(ctl->data, buf, size) != 0) |
1415 | retval = -EFAULT; | 1456 | retval = -EFAULT; |
1416 | 1457 | ||
1417 | kfree(buf); | 1458 | kfree(buf); |
@@ -1422,7 +1463,7 @@ static int proc_ioctl_default(struct dev_state *ps, void __user *arg) | |||
1422 | { | 1463 | { |
1423 | struct usbdevfs_ioctl ctrl; | 1464 | struct usbdevfs_ioctl ctrl; |
1424 | 1465 | ||
1425 | if (copy_from_user(&ctrl, arg, sizeof (ctrl))) | 1466 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
1426 | return -EFAULT; | 1467 | return -EFAULT; |
1427 | return proc_ioctl(ps, &ctrl); | 1468 | return proc_ioctl(ps, &ctrl); |
1428 | } | 1469 | } |
@@ -1450,7 +1491,8 @@ static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg) | |||
1450 | * are assuming that somehow the configuration has been prevented from | 1491 | * are assuming that somehow the configuration has been prevented from |
1451 | * changing. But there's no mechanism to ensure that... | 1492 | * changing. But there's no mechanism to ensure that... |
1452 | */ | 1493 | */ |
1453 | static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 1494 | static int usbdev_ioctl(struct inode *inode, struct file *file, |
1495 | unsigned int cmd, unsigned long arg) | ||
1454 | { | 1496 | { |
1455 | struct dev_state *ps = file->private_data; | 1497 | struct dev_state *ps = file->private_data; |
1456 | struct usb_device *dev = ps->dev; | 1498 | struct usb_device *dev = ps->dev; |
@@ -1593,7 +1635,8 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
1593 | } | 1635 | } |
1594 | 1636 | ||
1595 | /* No kernel lock - fine */ | 1637 | /* No kernel lock - fine */ |
1596 | static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wait) | 1638 | static unsigned int usbdev_poll(struct file *file, |
1639 | struct poll_table_struct *wait) | ||
1597 | { | 1640 | { |
1598 | struct dev_state *ps = file->private_data; | 1641 | struct dev_state *ps = file->private_data; |
1599 | unsigned int mask = 0; | 1642 | unsigned int mask = 0; |
@@ -1664,7 +1707,7 @@ int __init usb_devio_init(void) | |||
1664 | int retval; | 1707 | int retval; |
1665 | 1708 | ||
1666 | retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX, | 1709 | retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX, |
1667 | "usb_device"); | 1710 | "usb_device"); |
1668 | if (retval) { | 1711 | if (retval) { |
1669 | err("unable to register minors for usb_device"); | 1712 | err("unable to register minors for usb_device"); |
1670 | goto out; | 1713 | goto out; |