diff options
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r-- | drivers/usb/core/devio.c | 48 |
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 | ||
1428 | static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb, | 1426 | static 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 | |||
1801 | static int proc_submiturb(struct usb_dev_state *ps, void __user *arg) | 1800 | static 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 | ||
1813 | static int proc_unlinkurb(struct usb_dev_state *ps, void __user *arg) | 1816 | static 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, | |||
2005 | static int proc_submiturb_compat(struct usb_dev_state *ps, void __user *arg) | 2008 | static 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 | ||
2017 | static int processcompl_compat(struct async *as, void __user * __user *arg) | 2024 | static 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 = { | |||
2614 | static void usbdev_remove(struct usb_device *udev) | 2621 | static 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 | ||