projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
USB: fix urb dequeue bug to avoid kernel panic
[firefly-linux-kernel-4.4.55.git]
/
drivers
/
usb
/
core
/
hcd.c
diff --git
a/drivers/usb/core/hcd.c
b/drivers/usb/core/hcd.c
old mode 100644
(file)
new mode 100755
(executable)
index
ace9f84
..
1a1dfe5
--- a/
drivers/usb/core/hcd.c
+++ b/
drivers/usb/core/hcd.c
@@
-977,10
+977,7
@@
static int register_root_hub(struct usb_hcd *hcd)
if (retval) {
dev_err (parent_dev, "can't register root hub for %s, %d\n",
dev_name(&usb_dev->dev), retval);
if (retval) {
dev_err (parent_dev, "can't register root hub for %s, %d\n",
dev_name(&usb_dev->dev), retval);
- }
- mutex_unlock(&usb_bus_list_lock);
-
- if (retval == 0) {
+ } else {
spin_lock_irq (&hcd_root_hub_lock);
hcd->rh_registered = 1;
spin_unlock_irq (&hcd_root_hub_lock);
spin_lock_irq (&hcd_root_hub_lock);
hcd->rh_registered = 1;
spin_unlock_irq (&hcd_root_hub_lock);
@@
-989,6
+986,7
@@
static int register_root_hub(struct usb_hcd *hcd)
if (HCD_DEAD(hcd))
usb_hc_died (hcd); /* This time clean up */
}
if (HCD_DEAD(hcd))
usb_hc_died (hcd); /* This time clean up */
}
+ mutex_unlock(&usb_bus_list_lock);
return retval;
}
return retval;
}
@@
-1387,11
+1385,10
@@
int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
ret = -EAGAIN;
else
urb->transfer_flags |= URB_DMA_MAP_SG;
ret = -EAGAIN;
else
urb->transfer_flags |= URB_DMA_MAP_SG;
- if (n != urb->num_sgs) {
- urb->num_sgs = n;
+ urb->num_mapped_sgs = n;
+ if (n != urb->num_sgs)
urb->transfer_flags |=
URB_DMA_SG_COMBINED;
urb->transfer_flags |=
URB_DMA_SG_COMBINED;
- }
} else if (urb->sg) {
struct scatterlist *sg = urb->sg;
urb->transfer_dma = dma_map_page(
} else if (urb->sg) {
struct scatterlist *sg = urb->sg;
urb->transfer_dma = dma_map_page(
@@
-1583,8
+1580,12
@@
void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
/* pass ownership to the completion handler */
urb->status = status;
/* pass ownership to the completion handler */
urb->status = status;
- urb->complete (urb);
+ if(!atomic_read(&urb->use_count)){
+ printk("%s %d\n", __func__, atomic_read(&urb->use_count));
+ return;
+ }
atomic_dec (&urb->use_count);
atomic_dec (&urb->use_count);
+ urb->complete (urb);
if (unlikely(atomic_read(&urb->reject)))
wake_up (&usb_kill_urb_queue);
usb_put_urb (urb);
if (unlikely(atomic_read(&urb->reject)))
wake_up (&usb_kill_urb_queue);
usb_put_urb (urb);
@@
-1764,6
+1765,8
@@
int usb_hcd_alloc_bandwidth(struct usb_device *udev,
struct usb_interface *iface = usb_ifnum_to_if(udev,
cur_alt->desc.bInterfaceNumber);
struct usb_interface *iface = usb_ifnum_to_if(udev,
cur_alt->desc.bInterfaceNumber);
+ if (!iface)
+ return -EINVAL;
if (iface->resetting_device) {
/*
* The USB core just reset the device, so the xHCI host
if (iface->resetting_device) {
/*
* The USB core just reset the device, so the xHCI host
@@
-1956,6
+1959,7
@@
int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
}
if (!hcd->driver->bus_suspend) {
}
if (!hcd->driver->bus_suspend) {
+ printk("%s,error,everest\n",__func__);
status = -ENOENT;
} else {
clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
status = -ENOENT;
} else {
clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
@@
-2434,8
+2438,10
@@
int usb_add_hcd(struct usb_hcd *hcd,
&& device_can_wakeup(&hcd->self.root_hub->dev))
dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
&& device_can_wakeup(&hcd->self.root_hub->dev))
dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
- /* enable irqs just before we start the controller */
- if (usb_hcd_is_primary_hcd(hcd)) {
+ /* enable irqs just before we start the controller,
+ * if the BIOS provides legacy PCI irqs.
+ */
+ if (usb_hcd_is_primary_hcd(hcd) && irqnum) {
retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);
if (retval)
goto err_request_irq;
retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);
if (retval)
goto err_request_irq;