mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: USB: isp1362: fix build failure on ARM systems via irq_flags cleanup USB: isp1362: better 64bit printf warning fixes USB: fix usbstorage for 2770:915d delivers no FAT USB: Fix level of isp1760 Reloading ptd error message USB: FHCI: avoid NULL pointer dereference USB: Fix duplicate sysfs problem after device reset. USB: add speed values for USB 3.0 and wireless controllers USB: add missing delay during remote wakeup USB: EHCI & UHCI: fix race between root-hub suspend and port resume USB: EHCI: fix handling of unusual interrupt intervals USB: Don't use GFP_KERNEL while we cannot reset a storage device USB: fix bitmask merge error usb: serial: fix memory leak in generic driver USB: serial: fix USB serial fix kfifo_len locking
This commit is contained in:
commit
c9140487b4
17 changed files with 112 additions and 48 deletions
|
@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
|
|||
return 0;
|
||||
/* allocate 2^1 pages = 8K (on i386);
|
||||
* should be more than enough for one device */
|
||||
pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
|
||||
pages_start = (char *)__get_free_pages(GFP_NOIO, 1);
|
||||
if (!pages_start)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -1684,6 +1684,24 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,
|
|||
}
|
||||
}
|
||||
if (cur_alt && new_alt) {
|
||||
struct usb_interface *iface = usb_ifnum_to_if(udev,
|
||||
cur_alt->desc.bInterfaceNumber);
|
||||
|
||||
if (iface->resetting_device) {
|
||||
/*
|
||||
* The USB core just reset the device, so the xHCI host
|
||||
* and the device will think alt setting 0 is installed.
|
||||
* However, the USB core will pass in the alternate
|
||||
* setting installed before the reset as cur_alt. Dig
|
||||
* out the alternate setting 0 structure, or the first
|
||||
* alternate setting if a broken device doesn't have alt
|
||||
* setting 0.
|
||||
*/
|
||||
cur_alt = usb_altnum_to_altsetting(iface, 0);
|
||||
if (!cur_alt)
|
||||
cur_alt = &iface->altsetting[0];
|
||||
}
|
||||
|
||||
/* Drop all the endpoints in the current alt setting */
|
||||
for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) {
|
||||
ret = hcd->driver->drop_endpoint(hcd, udev,
|
||||
|
|
|
@ -3347,6 +3347,9 @@ static void hub_events(void)
|
|||
USB_PORT_FEAT_C_SUSPEND);
|
||||
udev = hdev->children[i-1];
|
||||
if (udev) {
|
||||
/* TRSMRCY = 10 msec */
|
||||
msleep(10);
|
||||
|
||||
usb_lock_device(udev);
|
||||
ret = remote_wakeup(hdev->
|
||||
children[i-1]);
|
||||
|
@ -3692,19 +3695,14 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
|
|||
usb_enable_interface(udev, intf, true);
|
||||
ret = 0;
|
||||
} else {
|
||||
/* We've just reset the device, so it will think alt
|
||||
* setting 0 is installed. For usb_set_interface() to
|
||||
* work properly, we need to set the current alternate
|
||||
* interface setting to 0 (or the first alt setting, if
|
||||
* the device doesn't have alt setting 0).
|
||||
/* Let the bandwidth allocation function know that this
|
||||
* device has been reset, and it will have to use
|
||||
* alternate setting 0 as the current alternate setting.
|
||||
*/
|
||||
intf->cur_altsetting =
|
||||
usb_find_alt_setting(config, i, 0);
|
||||
if (!intf->cur_altsetting)
|
||||
intf->cur_altsetting =
|
||||
&config->intf_cache[i]->altsetting[0];
|
||||
intf->resetting_device = 1;
|
||||
ret = usb_set_interface(udev, desc->bInterfaceNumber,
|
||||
desc->bAlternateSetting);
|
||||
intf->resetting_device = 0;
|
||||
}
|
||||
if (ret < 0) {
|
||||
dev_err(&udev->dev, "failed to restore interface %d "
|
||||
|
|
|
@ -906,11 +906,11 @@ char *usb_cache_string(struct usb_device *udev, int index)
|
|||
if (index <= 0)
|
||||
return NULL;
|
||||
|
||||
buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
|
||||
buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
|
||||
if (buf) {
|
||||
len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
|
||||
if (len > 0) {
|
||||
smallbuf = kmalloc(++len, GFP_KERNEL);
|
||||
smallbuf = kmalloc(++len, GFP_NOIO);
|
||||
if (!smallbuf)
|
||||
return buf;
|
||||
memcpy(smallbuf, buf, len);
|
||||
|
@ -1731,7 +1731,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
|||
if (cp) {
|
||||
nintf = cp->desc.bNumInterfaces;
|
||||
new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
|
||||
GFP_KERNEL);
|
||||
GFP_NOIO);
|
||||
if (!new_interfaces) {
|
||||
dev_err(&dev->dev, "Out of memory\n");
|
||||
return -ENOMEM;
|
||||
|
@ -1740,7 +1740,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
|||
for (; n < nintf; ++n) {
|
||||
new_interfaces[n] = kzalloc(
|
||||
sizeof(struct usb_interface),
|
||||
GFP_KERNEL);
|
||||
GFP_NOIO);
|
||||
if (!new_interfaces[n]) {
|
||||
dev_err(&dev->dev, "Out of memory\n");
|
||||
ret = -ENOMEM;
|
||||
|
|
|
@ -115,6 +115,12 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
|
|||
case USB_SPEED_HIGH:
|
||||
speed = "480";
|
||||
break;
|
||||
case USB_SPEED_VARIABLE:
|
||||
speed = "480";
|
||||
break;
|
||||
case USB_SPEED_SUPER:
|
||||
speed = "5000";
|
||||
break;
|
||||
default:
|
||||
speed = "unknown";
|
||||
}
|
||||
|
|
|
@ -787,9 +787,10 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||
|
||||
/* start 20 msec resume signaling from this port,
|
||||
* and make khubd collect PORT_STAT_C_SUSPEND to
|
||||
* stop that signaling.
|
||||
* stop that signaling. Use 5 ms extra for safety,
|
||||
* like usb_port_resume() does.
|
||||
*/
|
||||
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
|
||||
ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
|
||||
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
|
||||
mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
|
||||
}
|
||||
|
|
|
@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||
del_timer_sync(&ehci->watchdog);
|
||||
del_timer_sync(&ehci->iaa_watchdog);
|
||||
|
||||
port = HCS_N_PORTS (ehci->hcs_params);
|
||||
spin_lock_irq (&ehci->lock);
|
||||
|
||||
/* Once the controller is stopped, port resumes that are already
|
||||
* in progress won't complete. Hence if remote wakeup is enabled
|
||||
* for the root hub and any ports are in the middle of a resume or
|
||||
* remote wakeup, we must fail the suspend.
|
||||
*/
|
||||
if (hcd->self.root_hub->do_remote_wakeup) {
|
||||
port = HCS_N_PORTS(ehci->hcs_params);
|
||||
while (port--) {
|
||||
if (ehci->reset_done[port] != 0) {
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
ehci_dbg(ehci, "suspend failed because "
|
||||
"port %d is resuming\n",
|
||||
port + 1);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* stop schedules, clean any completed work */
|
||||
if (HC_IS_RUNNING(hcd->state)) {
|
||||
ehci_quiesce (ehci);
|
||||
|
@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||
*/
|
||||
ehci->bus_suspended = 0;
|
||||
ehci->owned_ports = 0;
|
||||
port = HCS_N_PORTS(ehci->hcs_params);
|
||||
while (port--) {
|
||||
u32 __iomem *reg = &ehci->regs->port_status [port];
|
||||
u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
|
||||
|
|
|
@ -849,9 +849,10 @@ qh_make (
|
|||
* But interval 1 scheduling is simpler, and
|
||||
* includes high bandwidth.
|
||||
*/
|
||||
dbg ("intr period %d uframes, NYET!",
|
||||
urb->interval);
|
||||
goto done;
|
||||
urb->interval = 1;
|
||||
} else if (qh->period > ehci->periodic_size) {
|
||||
qh->period = ehci->periodic_size;
|
||||
urb->interval = qh->period << 3;
|
||||
}
|
||||
} else {
|
||||
int think_time;
|
||||
|
@ -874,6 +875,10 @@ qh_make (
|
|||
usb_calc_bus_time (urb->dev->speed,
|
||||
is_input, 0, max_packet (maxp)));
|
||||
qh->period = urb->interval;
|
||||
if (qh->period > ehci->periodic_size) {
|
||||
qh->period = ehci->periodic_size;
|
||||
urb->interval = qh->period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -242,9 +242,10 @@ static int fhci_mem_init(struct fhci_hcd *fhci)
|
|||
static void fhci_usb_free(void *lld)
|
||||
{
|
||||
struct fhci_usb *usb = lld;
|
||||
struct fhci_hcd *fhci = usb->fhci;
|
||||
struct fhci_hcd *fhci;
|
||||
|
||||
if (usb) {
|
||||
fhci = usb->fhci;
|
||||
fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
|
||||
fhci_ep0_free(usb);
|
||||
kfree(usb->actual_frame);
|
||||
|
|
|
@ -2270,10 +2270,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd)
|
|||
dev_info(hcd->self.controller, "ISP1362 Memory usage:\n");
|
||||
dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n",
|
||||
istl_size / 2, istl_size, 0, istl_size / 2);
|
||||
dev_info(hcd->self.controller, " INTL: %4d * (%3lu+8): %4d @ $%04x\n",
|
||||
dev_info(hcd->self.controller, " INTL: %4d * (%3zu+8): %4d @ $%04x\n",
|
||||
ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
|
||||
intl_size, istl_size);
|
||||
dev_info(hcd->self.controller, " ATL : %4d * (%3lu+8): %4d @ $%04x\n",
|
||||
dev_info(hcd->self.controller, " ATL : %4d * (%3zu+8): %4d @ $%04x\n",
|
||||
atl_buffers, atl_blksize - PTD_HEADER_SIZE,
|
||||
atl_size, istl_size + intl_size);
|
||||
dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total,
|
||||
|
@ -2697,6 +2697,8 @@ static int __init isp1362_probe(struct platform_device *pdev)
|
|||
void __iomem *data_reg;
|
||||
int irq;
|
||||
int retval = 0;
|
||||
struct resource *irq_res;
|
||||
unsigned int irq_flags = 0;
|
||||
|
||||
/* basic sanity checks first. board-specific init logic should
|
||||
* have initialized this the three resources and probably board
|
||||
|
@ -2710,11 +2712,12 @@ static int __init isp1362_probe(struct platform_device *pdev)
|
|||
|
||||
data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (!addr || !data || irq < 0) {
|
||||
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!addr || !data || !irq_res) {
|
||||
retval = -ENODEV;
|
||||
goto err1;
|
||||
}
|
||||
irq = irq_res->start;
|
||||
|
||||
#ifdef CONFIG_USB_HCD_DMA
|
||||
if (pdev->dev.dma_mask) {
|
||||
|
@ -2781,12 +2784,16 @@ static int __init isp1362_probe(struct platform_device *pdev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
if (isp1362_hcd->board)
|
||||
set_irq_type(irq, isp1362_hcd->board->int_act_high ? IRQT_RISING : IRQT_FALLING);
|
||||
#endif
|
||||
if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE)
|
||||
irq_flags |= IRQF_TRIGGER_RISING;
|
||||
if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE)
|
||||
irq_flags |= IRQF_TRIGGER_FALLING;
|
||||
if (irq_res->flags & IORESOURCE_IRQ_HIGHLEVEL)
|
||||
irq_flags |= IRQF_TRIGGER_HIGH;
|
||||
if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL)
|
||||
irq_flags |= IRQF_TRIGGER_LOW;
|
||||
|
||||
retval = usb_add_hcd(hcd, irq, IRQF_TRIGGER_LOW | IRQF_DISABLED | IRQF_SHARED);
|
||||
retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_DISABLED | IRQF_SHARED);
|
||||
if (retval != 0)
|
||||
goto err6;
|
||||
pr_info("%s, irq %d\n", hcd->product_desc, irq);
|
||||
|
|
|
@ -1039,12 +1039,12 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
|
|||
if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) {
|
||||
u32 buffstatus;
|
||||
|
||||
/* XXX
|
||||
/*
|
||||
* NAKs are handled in HW by the chip. Usually if the
|
||||
* device is not able to send data fast enough.
|
||||
* This did not trigger for a long time now.
|
||||
* This happens mostly on slower hardware.
|
||||
*/
|
||||
printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: "
|
||||
printk(KERN_NOTICE "Reloading ptd %p/%p... qh %p read: "
|
||||
"%d of %zu done: %08x cur: %08x\n", qtd,
|
||||
urb, qh, PTD_XFERRED_LENGTH(dw3),
|
||||
qtd->length, done_map,
|
||||
|
|
|
@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hcd *hcd)
|
|||
spin_lock_irq(&uhci->lock);
|
||||
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
|
||||
rc = -ESHUTDOWN;
|
||||
else if (!uhci->dead)
|
||||
else if (uhci->dead)
|
||||
; /* Dead controllers tell no tales */
|
||||
|
||||
/* Once the controller is stopped, port resumes that are already
|
||||
* in progress won't complete. Hence if remote wakeup is enabled
|
||||
* for the root hub and any ports are in the middle of a resume or
|
||||
* remote wakeup, we must fail the suspend.
|
||||
*/
|
||||
else if (hcd->self.root_hub->do_remote_wakeup &&
|
||||
uhci->resuming_ports) {
|
||||
dev_dbg(uhci_dev(uhci), "suspend failed because a port "
|
||||
"is resuming\n");
|
||||
rc = -EBUSY;
|
||||
} else
|
||||
suspend_rh(uhci, UHCI_RH_SUSPENDED);
|
||||
spin_unlock_irq(&uhci->lock);
|
||||
return rc;
|
||||
|
|
|
@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
|
|||
/* Port received a wakeup request */
|
||||
set_bit(port, &uhci->resuming_ports);
|
||||
uhci->ports_timeout = jiffies +
|
||||
msecs_to_jiffies(20);
|
||||
msecs_to_jiffies(25);
|
||||
|
||||
/* Make sure we see the port again
|
||||
* after the resuming period is over. */
|
||||
|
|
|
@ -386,12 +386,12 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
|
|||
|
||||
dbg("%s - port %d", __func__, port->number);
|
||||
|
||||
if (serial->type->max_in_flight_urbs) {
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
if (serial->type->max_in_flight_urbs)
|
||||
chars = port->tx_bytes_flight;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
} else if (serial->num_bulk_out)
|
||||
else if (serial->num_bulk_out)
|
||||
chars = kfifo_len(&port->write_fifo);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
||||
dbg("%s - returns %d", __func__, chars);
|
||||
return chars;
|
||||
|
@ -489,6 +489,8 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
|
|||
dbg("%s - port %d", __func__, port->number);
|
||||
|
||||
if (port->serial->type->max_in_flight_urbs) {
|
||||
kfree(urb->transfer_buffer);
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
--port->urbs_in_flight;
|
||||
port->tx_bytes_flight -= urb->transfer_buffer_length;
|
||||
|
|
|
@ -1807,13 +1807,6 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999,
|
|||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_GO_SLOW ),
|
||||
|
||||
/* Reported by Rohan Hart <rohan.hart17@gmail.com> */
|
||||
UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010,
|
||||
"INTOVA",
|
||||
"Pixtreme",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_FIX_CAPACITY ),
|
||||
|
||||
/* Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
|
||||
* Mio Moov 330
|
||||
*/
|
||||
|
|
|
@ -434,7 +434,8 @@ static void adjust_quirks(struct us_data *us)
|
|||
u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor);
|
||||
u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
|
||||
unsigned f = 0;
|
||||
unsigned int mask = (US_FL_SANE_SENSE | US_FL_FIX_CAPACITY |
|
||||
unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE |
|
||||
US_FL_FIX_CAPACITY |
|
||||
US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
|
||||
US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
|
||||
US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
|
||||
|
|
|
@ -192,6 +192,7 @@ struct usb_interface {
|
|||
unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */
|
||||
unsigned needs_binding:1; /* needs delayed unbind/rebind */
|
||||
unsigned reset_running:1;
|
||||
unsigned resetting_device:1; /* true: bandwidth alloc after reset */
|
||||
|
||||
struct device dev; /* interface specific device info */
|
||||
struct device *usb_dev;
|
||||
|
|
Loading…
Reference in a new issue