aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index fa783531ee88..a02448105527 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -63,7 +63,7 @@ struct usb_dev_state {
63 unsigned int discsignr; 63 unsigned int discsignr;
64 struct pid *disc_pid; 64 struct pid *disc_pid;
65 const struct cred *cred; 65 const struct cred *cred;
66 void __user *disccontext; 66 sigval_t disccontext;
67 unsigned long ifclaimed; 67 unsigned long ifclaimed;
68 u32 disabled_bulk_eps; 68 u32 disabled_bulk_eps;
69 bool privileges_dropped; 69 bool privileges_dropped;
@@ -90,6 +90,7 @@ struct async {
90 unsigned int ifnum; 90 unsigned int ifnum;
91 void __user *userbuffer; 91 void __user *userbuffer;
92 void __user *userurb; 92 void __user *userurb;
93 sigval_t userurb_sigval;
93 struct urb *urb; 94 struct urb *urb;
94 struct usb_memory *usbm; 95 struct usb_memory *usbm;
95 unsigned int mem_usage; 96 unsigned int mem_usage;
@@ -582,22 +583,19 @@ static void async_completed(struct urb *urb)
582{ 583{
583 struct async *as = urb->context; 584 struct async *as = urb->context;
584 struct usb_dev_state *ps = as->ps; 585 struct usb_dev_state *ps = as->ps;
585 struct kernel_siginfo sinfo;
586 struct pid *pid = NULL; 586 struct pid *pid = NULL;
587 const struct cred *cred = NULL; 587 const struct cred *cred = NULL;
588 unsigned long flags; 588 unsigned long flags;
589 int signr; 589 sigval_t addr;
590 int signr, errno;
590 591
591 spin_lock_irqsave(&ps->lock, flags); 592 spin_lock_irqsave(&ps->lock, flags);
592 list_move_tail(&as->asynclist, &ps->async_completed); 593 list_move_tail(&as->asynclist, &ps->async_completed);
593 as->status = urb->status; 594 as->status = urb->status;
594 signr = as->signr; 595 signr = as->signr;
595 if (signr) { 596 if (signr) {
596 clear_siginfo(&sinfo); 597 errno = as->status;
597 sinfo.si_signo = as->signr; 598 addr = as->userurb_sigval;
598 sinfo.si_errno = as->status;
599 sinfo.si_code = SI_ASYNCIO;
600 sinfo.si_addr = as->userurb;
601 pid = get_pid(as->pid); 599 pid = get_pid(as->pid);
602 cred = get_cred(as->cred); 600 cred = get_cred(as->cred);
603 } 601 }
@@ -615,7 +613,7 @@ static void async_completed(struct urb *urb)
615 spin_unlock_irqrestore(&ps->lock, flags); 613 spin_unlock_irqrestore(&ps->lock, flags);
616 614
617 if (signr) { 615 if (signr) {
618 kill_pid_info_as_cred(sinfo.si_signo, &sinfo, pid, cred); 616 kill_pid_usb_asyncio(signr, errno, addr, pid, cred);
619 put_pid(pid); 617 put_pid(pid);
620 put_cred(cred); 618 put_cred(cred);
621 } 619 }
@@ -1427,7 +1425,7 @@ find_memory_area(struct usb_dev_state *ps, const struct usbdevfs_urb *uurb)
1427 1425
1428static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb, 1426static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb,
1429 struct usbdevfs_iso_packet_desc __user *iso_frame_desc, 1427 struct usbdevfs_iso_packet_desc __user *iso_frame_desc,
1430 void __user *arg) 1428 void __user *arg, sigval_t userurb_sigval)
1431{ 1429{
1432 struct usbdevfs_iso_packet_desc *isopkt = NULL; 1430 struct usbdevfs_iso_packet_desc *isopkt = NULL;
1433 struct usb_host_endpoint *ep; 1431 struct usb_host_endpoint *ep;
@@ -1727,6 +1725,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
1727 isopkt = NULL; 1725 isopkt = NULL;
1728 as->ps = ps; 1726 as->ps = ps;
1729 as->userurb = arg; 1727 as->userurb = arg;
1728 as->userurb_sigval = userurb_sigval;
1730 if (as->usbm) { 1729 if (as->usbm) {
1731 unsigned long uurb_start = (unsigned long)uurb->buffer; 1730 unsigned long uurb_start = (unsigned long)uurb->buffer;
1732 1731
@@ -1801,13 +1800,17 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
1801static int proc_submiturb(struct usb_dev_state *ps, void __user *arg) 1800static int proc_submiturb(struct usb_dev_state *ps, void __user *arg)
1802{ 1801{
1803 struct usbdevfs_urb uurb; 1802 struct usbdevfs_urb uurb;
1803 sigval_t userurb_sigval;
1804 1804
1805 if (copy_from_user(&uurb, arg, sizeof(uurb))) 1805 if (copy_from_user(&uurb, arg, sizeof(uurb)))
1806 return -EFAULT; 1806 return -EFAULT;
1807 1807
1808 memset(&userurb_sigval, 0, sizeof(userurb_sigval));
1809 userurb_sigval.sival_ptr = arg;
1810
1808 return proc_do_submiturb(ps, &uurb, 1811 return proc_do_submiturb(ps, &uurb,
1809 (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), 1812 (((struct usbdevfs_urb __user *)arg)->iso_frame_desc),
1810 arg); 1813 arg, userurb_sigval);
1811} 1814}
1812 1815
1813static int proc_unlinkurb(struct usb_dev_state *ps, void __user *arg) 1816static int proc_unlinkurb(struct usb_dev_state *ps, void __user *arg)
@@ -1977,7 +1980,7 @@ static int proc_disconnectsignal_compat(struct usb_dev_state *ps, void __user *a
1977 if (copy_from_user(&ds, arg, sizeof(ds))) 1980 if (copy_from_user(&ds, arg, sizeof(ds)))
1978 return -EFAULT; 1981 return -EFAULT;
1979 ps->discsignr = ds.signr; 1982 ps->discsignr = ds.signr;
1980 ps->disccontext = compat_ptr(ds.context); 1983 ps->disccontext.sival_int = ds.context;
1981 return 0; 1984 return 0;
1982} 1985}
1983 1986
@@ -2005,13 +2008,17 @@ static int get_urb32(struct usbdevfs_urb *kurb,
2005static int proc_submiturb_compat(struct usb_dev_state *ps, void __user *arg) 2008static int proc_submiturb_compat(struct usb_dev_state *ps, void __user *arg)
2006{ 2009{
2007 struct usbdevfs_urb uurb; 2010 struct usbdevfs_urb uurb;
2011 sigval_t userurb_sigval;
2008 2012
2009 if (get_urb32(&uurb, (struct usbdevfs_urb32 __user *)arg)) 2013 if (get_urb32(&uurb, (struct usbdevfs_urb32 __user *)arg))
2010 return -EFAULT; 2014 return -EFAULT;
2011 2015
2016 memset(&userurb_sigval, 0, sizeof(userurb_sigval));
2017 userurb_sigval.sival_int = ptr_to_compat(arg);
2018
2012 return proc_do_submiturb(ps, &uurb, 2019 return proc_do_submiturb(ps, &uurb,
2013 ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, 2020 ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc,
2014 arg); 2021 arg, userurb_sigval);
2015} 2022}
2016 2023
2017static int processcompl_compat(struct async *as, void __user * __user *arg) 2024static int processcompl_compat(struct async *as, void __user * __user *arg)
@@ -2092,7 +2099,7 @@ static int proc_disconnectsignal(struct usb_dev_state *ps, void __user *arg)
2092 if (copy_from_user(&ds, arg, sizeof(ds))) 2099 if (copy_from_user(&ds, arg, sizeof(ds)))
2093 return -EFAULT; 2100 return -EFAULT;
2094 ps->discsignr = ds.signr; 2101 ps->discsignr = ds.signr;
2095 ps->disccontext = ds.context; 2102 ps->disccontext.sival_ptr = ds.context;
2096 return 0; 2103 return 0;
2097} 2104}
2098 2105
@@ -2614,22 +2621,15 @@ const struct file_operations usbdev_file_operations = {
2614static void usbdev_remove(struct usb_device *udev) 2621static void usbdev_remove(struct usb_device *udev)
2615{ 2622{
2616 struct usb_dev_state *ps; 2623 struct usb_dev_state *ps;
2617 struct kernel_siginfo sinfo;
2618 2624
2619 while (!list_empty(&udev->filelist)) { 2625 while (!list_empty(&udev->filelist)) {
2620 ps = list_entry(udev->filelist.next, struct usb_dev_state, list); 2626 ps = list_entry(udev->filelist.next, struct usb_dev_state, list);
2621 destroy_all_async(ps); 2627 destroy_all_async(ps);
2622 wake_up_all(&ps->wait); 2628 wake_up_all(&ps->wait);
2623 list_del_init(&ps->list); 2629 list_del_init(&ps->list);
2624 if (ps->discsignr) { 2630 if (ps->discsignr)
2625 clear_siginfo(&sinfo); 2631 kill_pid_usb_asyncio(ps->discsignr, EPIPE, ps->disccontext,
2626 sinfo.si_signo = ps->discsignr; 2632 ps->disc_pid, ps->cred);
2627 sinfo.si_errno = EPIPE;
2628 sinfo.si_code = SI_ASYNCIO;
2629 sinfo.si_addr = ps->disccontext;
2630 kill_pid_info_as_cred(ps->discsignr, &sinfo,
2631 ps->disc_pid, ps->cred);
2632 }
2633 } 2633 }
2634} 2634}
2635 2635