kernel: USB update from stlinux24_217
This commit is contained in:
@@ -403,7 +403,7 @@ static void async_completed(struct urb *urb)
|
||||
sinfo.si_errno = as->status;
|
||||
sinfo.si_code = SI_ASYNCIO;
|
||||
sinfo.si_addr = as->userurb;
|
||||
pid = as->pid;
|
||||
pid = get_pid(as->pid);
|
||||
uid = as->uid;
|
||||
euid = as->euid;
|
||||
secid = as->secid;
|
||||
@@ -416,9 +416,11 @@ static void async_completed(struct urb *urb)
|
||||
cancel_bulk_urbs(ps, as->bulk_addr);
|
||||
spin_unlock(&ps->lock);
|
||||
|
||||
if (signr)
|
||||
if (signr) {
|
||||
kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid,
|
||||
euid, secid);
|
||||
put_pid(pid);
|
||||
}
|
||||
|
||||
wake_up(&ps->wait);
|
||||
}
|
||||
@@ -1452,10 +1454,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
|
||||
void __user *addr = as->userurb;
|
||||
unsigned int i;
|
||||
|
||||
if (as->userbuffer && urb->actual_length)
|
||||
if (copy_to_user(as->userbuffer, urb->transfer_buffer,
|
||||
urb->actual_length))
|
||||
if (as->userbuffer && urb->actual_length) {
|
||||
if (urb->number_of_packets > 0) /* Isochronous */
|
||||
i = urb->transfer_buffer_length;
|
||||
else /* Non-Isoc */
|
||||
i = urb->actual_length;
|
||||
if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
|
||||
return -EFAULT;
|
||||
}
|
||||
if (put_user(as->status, &userurb->status))
|
||||
return -EFAULT;
|
||||
if (put_user(urb->actual_length, &userurb->actual_length))
|
||||
|
@@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
||||
for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
|
||||
intf = udev->actconfig->interface[i];
|
||||
status = usb_suspend_interface(udev, intf, msg);
|
||||
|
||||
/* Ignore errors during system sleep transitions */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status == 0)
|
||||
if (status == 0) {
|
||||
status = usb_suspend_device(udev, msg);
|
||||
|
||||
/* Again, ignore errors during system sleep transitions */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
}
|
||||
|
||||
/* If the suspend failed, resume interfaces that did get suspended */
|
||||
if (status != 0) {
|
||||
pm_message_t msg2;
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/usb/quirks.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/byteorder.h>
|
||||
@@ -458,10 +459,8 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
|
||||
* talking to TTs must queue control transfers (not just bulk and iso), so
|
||||
* both can talk to the same hub concurrently.
|
||||
*/
|
||||
static void hub_tt_work(struct work_struct *work)
|
||||
void _hub_tt_work(struct usb_hub *hub)
|
||||
{
|
||||
struct usb_hub *hub =
|
||||
container_of(work, struct usb_hub, tt.clear_work);
|
||||
unsigned long flags;
|
||||
int limit = 100;
|
||||
|
||||
@@ -496,6 +495,14 @@ static void hub_tt_work(struct work_struct *work)
|
||||
spin_unlock_irqrestore (&hub->tt.lock, flags);
|
||||
}
|
||||
|
||||
void hub_tt_work(struct work_struct *work)
|
||||
{
|
||||
struct usb_hub *hub =
|
||||
container_of(work, struct usb_hub, tt.clear_work);
|
||||
|
||||
_hub_tt_work(hub);
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
|
||||
* @urb: an URB associated with the failed or incomplete split transaction
|
||||
@@ -543,7 +550,20 @@ int usb_hub_clear_tt_buffer(struct urb *urb)
|
||||
/* tell keventd to clear state for this TT */
|
||||
spin_lock_irqsave (&tt->lock, flags);
|
||||
list_add_tail (&clear->clear_list, &tt->clear_list);
|
||||
schedule_work(&tt->clear_work);
|
||||
/* don't schedule on kevent if we're running on keventd (e.g.,
|
||||
* in hid_reset we can get here on kevent) unless on >=2.6.36
|
||||
*/
|
||||
if (!current_is_keventd())
|
||||
/* put it on keventd */
|
||||
schedule_work(&tt->clear_work);
|
||||
else {
|
||||
/* let khubd do it */
|
||||
struct usb_hub *hub =
|
||||
container_of(&tt->clear_work, struct usb_hub,
|
||||
tt.clear_work);
|
||||
kick_khubd(hub);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore (&tt->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
@@ -1812,6 +1832,16 @@ int usb_new_device(struct usb_device *udev)
|
||||
/* Tell the world! */
|
||||
announce_device(udev);
|
||||
|
||||
#if 0
|
||||
if (udev->serial)
|
||||
add_device_randomness(udev->serial, strlen(udev->serial));
|
||||
if (udev->product)
|
||||
add_device_randomness(udev->product, strlen(udev->product));
|
||||
if (udev->manufacturer)
|
||||
add_device_randomness(udev->manufacturer,
|
||||
strlen(udev->manufacturer));
|
||||
#endif
|
||||
|
||||
/* Register the device. The device driver is responsible
|
||||
* for configuring the device and invoking the add-device
|
||||
* notifier chain (used by usbfs and possibly others).
|
||||
@@ -2188,6 +2218,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
/* System sleep transitions should never fail */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
} else {
|
||||
/* device has up to 10 msec to fully suspend */
|
||||
dev_dbg(&udev->dev, "usb %ssuspend\n",
|
||||
@@ -2427,16 +2461,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
unsigned port1;
|
||||
|
||||
/* fail if children aren't already suspended */
|
||||
/* Warn if children aren't already suspended */
|
||||
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
||||
struct usb_device *udev;
|
||||
|
||||
udev = hdev->children [port1-1];
|
||||
if (udev && udev->can_submit) {
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
dev_dbg(&intf->dev, "port %d nyet suspended\n",
|
||||
port1);
|
||||
return -EBUSY;
|
||||
dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
|
||||
if (msg.event & PM_EVENT_AUTO)
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3271,6 +3304,10 @@ static void hub_events(void)
|
||||
if (hub->quiescing)
|
||||
goto loop_autopm;
|
||||
|
||||
/* _hub_tt_work usually run on keventd */
|
||||
if (!list_empty(&hub->tt.clear_list))
|
||||
_hub_tt_work(hub);
|
||||
|
||||
if (hub->error) {
|
||||
dev_dbg (hub_dev, "resetting for error %d\n",
|
||||
hub->error);
|
||||
|
@@ -38,6 +38,51 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* Creative SB Audigy 2 NX */
|
||||
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C200 */
|
||||
{ USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C250 */
|
||||
{ USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam B/C500 */
|
||||
{ USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C600 */
|
||||
{ USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam Pro 9000 */
|
||||
{ USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C905 */
|
||||
{ USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C210 */
|
||||
{ USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C260 */
|
||||
{ USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C310 */
|
||||
{ USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C910 */
|
||||
{ USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C160 */
|
||||
{ USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C270 */
|
||||
{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam Pro 9000 */
|
||||
{ USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam E3500 */
|
||||
{ USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam Vision Pro */
|
||||
{ USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Harmony 700-series */
|
||||
{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
@@ -69,6 +114,12 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x06a3, 0x0006), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */
|
||||
{ USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Guillemot Webcam Hercules Dualpix Exchange*/
|
||||
{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* M-Systems Flash Disk Pioneers */
|
||||
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
|
Reference in New Issue
Block a user