Commit c9140487 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 456eac94 0a2fea2e
...@@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, ...@@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
return 0; return 0;
/* allocate 2^1 pages = 8K (on i386); /* allocate 2^1 pages = 8K (on i386);
* should be more than enough for one device */ * 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) if (!pages_start)
return -ENOMEM; return -ENOMEM;
......
...@@ -1684,6 +1684,24 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev, ...@@ -1684,6 +1684,24 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,
} }
} }
if (cur_alt && new_alt) { 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 */ /* Drop all the endpoints in the current alt setting */
for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) { for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) {
ret = hcd->driver->drop_endpoint(hcd, udev, ret = hcd->driver->drop_endpoint(hcd, udev,
......
...@@ -3347,6 +3347,9 @@ static void hub_events(void) ...@@ -3347,6 +3347,9 @@ static void hub_events(void)
USB_PORT_FEAT_C_SUSPEND); USB_PORT_FEAT_C_SUSPEND);
udev = hdev->children[i-1]; udev = hdev->children[i-1];
if (udev) { if (udev) {
/* TRSMRCY = 10 msec */
msleep(10);
usb_lock_device(udev); usb_lock_device(udev);
ret = remote_wakeup(hdev-> ret = remote_wakeup(hdev->
children[i-1]); children[i-1]);
...@@ -3692,19 +3695,14 @@ static int usb_reset_and_verify_device(struct usb_device *udev) ...@@ -3692,19 +3695,14 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
usb_enable_interface(udev, intf, true); usb_enable_interface(udev, intf, true);
ret = 0; ret = 0;
} else { } else {
/* We've just reset the device, so it will think alt /* Let the bandwidth allocation function know that this
* setting 0 is installed. For usb_set_interface() to * device has been reset, and it will have to use
* work properly, we need to set the current alternate * alternate setting 0 as the current alternate setting.
* interface setting to 0 (or the first alt setting, if
* the device doesn't have alt setting 0).
*/ */
intf->cur_altsetting = intf->resetting_device = 1;
usb_find_alt_setting(config, i, 0);
if (!intf->cur_altsetting)
intf->cur_altsetting =
&config->intf_cache[i]->altsetting[0];
ret = usb_set_interface(udev, desc->bInterfaceNumber, ret = usb_set_interface(udev, desc->bInterfaceNumber,
desc->bAlternateSetting); desc->bAlternateSetting);
intf->resetting_device = 0;
} }
if (ret < 0) { if (ret < 0) {
dev_err(&udev->dev, "failed to restore interface %d " dev_err(&udev->dev, "failed to restore interface %d "
......
...@@ -906,11 +906,11 @@ char *usb_cache_string(struct usb_device *udev, int index) ...@@ -906,11 +906,11 @@ char *usb_cache_string(struct usb_device *udev, int index)
if (index <= 0) if (index <= 0)
return NULL; return NULL;
buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL); buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
if (buf) { if (buf) {
len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE); len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
if (len > 0) { if (len > 0) {
smallbuf = kmalloc(++len, GFP_KERNEL); smallbuf = kmalloc(++len, GFP_NOIO);
if (!smallbuf) if (!smallbuf)
return buf; return buf;
memcpy(smallbuf, buf, len); memcpy(smallbuf, buf, len);
...@@ -1731,7 +1731,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1731,7 +1731,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
if (cp) { if (cp) {
nintf = cp->desc.bNumInterfaces; nintf = cp->desc.bNumInterfaces;
new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
GFP_KERNEL); GFP_NOIO);
if (!new_interfaces) { if (!new_interfaces) {
dev_err(&dev->dev, "Out of memory\n"); dev_err(&dev->dev, "Out of memory\n");
return -ENOMEM; return -ENOMEM;
...@@ -1740,7 +1740,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1740,7 +1740,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
for (; n < nintf; ++n) { for (; n < nintf; ++n) {
new_interfaces[n] = kzalloc( new_interfaces[n] = kzalloc(
sizeof(struct usb_interface), sizeof(struct usb_interface),
GFP_KERNEL); GFP_NOIO);
if (!new_interfaces[n]) { if (!new_interfaces[n]) {
dev_err(&dev->dev, "Out of memory\n"); dev_err(&dev->dev, "Out of memory\n");
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -115,6 +115,12 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -115,6 +115,12 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
case USB_SPEED_HIGH: case USB_SPEED_HIGH:
speed = "480"; speed = "480";
break; break;
case USB_SPEED_VARIABLE:
speed = "480";
break;
case USB_SPEED_SUPER:
speed = "5000";
break;
default: default:
speed = "unknown"; speed = "unknown";
} }
......
...@@ -787,9 +787,10 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) ...@@ -787,9 +787,10 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* start 20 msec resume signaling from this port, /* start 20 msec resume signaling from this port,
* and make khubd collect PORT_STAT_C_SUSPEND to * 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); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
mod_timer(&hcd->rh_timer, ehci->reset_done[i]); mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
} }
......
...@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ...@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
del_timer_sync(&ehci->watchdog); del_timer_sync(&ehci->watchdog);
del_timer_sync(&ehci->iaa_watchdog); del_timer_sync(&ehci->iaa_watchdog);
port = HCS_N_PORTS (ehci->hcs_params);
spin_lock_irq (&ehci->lock); 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 */ /* stop schedules, clean any completed work */
if (HC_IS_RUNNING(hcd->state)) { if (HC_IS_RUNNING(hcd->state)) {
ehci_quiesce (ehci); ehci_quiesce (ehci);
...@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ...@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
*/ */
ehci->bus_suspended = 0; ehci->bus_suspended = 0;
ehci->owned_ports = 0; ehci->owned_ports = 0;
port = HCS_N_PORTS(ehci->hcs_params);
while (port--) { while (port--) {
u32 __iomem *reg = &ehci->regs->port_status [port]; u32 __iomem *reg = &ehci->regs->port_status [port];
u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
......
...@@ -849,9 +849,10 @@ qh_make ( ...@@ -849,9 +849,10 @@ qh_make (
* But interval 1 scheduling is simpler, and * But interval 1 scheduling is simpler, and
* includes high bandwidth. * includes high bandwidth.
*/ */
dbg ("intr period %d uframes, NYET!", urb->interval = 1;
urb->interval); } else if (qh->period > ehci->periodic_size) {
goto done; qh->period = ehci->periodic_size;
urb->interval = qh->period << 3;
} }
} else { } else {
int think_time; int think_time;
...@@ -874,6 +875,10 @@ qh_make ( ...@@ -874,6 +875,10 @@ qh_make (
usb_calc_bus_time (urb->dev->speed, usb_calc_bus_time (urb->dev->speed,
is_input, 0, max_packet (maxp))); is_input, 0, max_packet (maxp)));
qh->period = urb->interval; 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) ...@@ -242,9 +242,10 @@ static int fhci_mem_init(struct fhci_hcd *fhci)
static void fhci_usb_free(void *lld) static void fhci_usb_free(void *lld)
{ {
struct fhci_usb *usb = lld; struct fhci_usb *usb = lld;
struct fhci_hcd *fhci = usb->fhci; struct fhci_hcd *fhci;
if (usb) { if (usb) {
fhci = usb->fhci;
fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF); fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
fhci_ep0_free(usb); fhci_ep0_free(usb);
kfree(usb->actual_frame); kfree(usb->actual_frame);
......
...@@ -2270,10 +2270,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd) ...@@ -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, "ISP1362 Memory usage:\n");
dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n",
istl_size / 2, istl_size, 0, istl_size / 2); 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, ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
intl_size, istl_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_buffers, atl_blksize - PTD_HEADER_SIZE,
atl_size, istl_size + intl_size); atl_size, istl_size + intl_size);
dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total,
...@@ -2697,6 +2697,8 @@ static int __init isp1362_probe(struct platform_device *pdev) ...@@ -2697,6 +2697,8 @@ static int __init isp1362_probe(struct platform_device *pdev)
void __iomem *data_reg; void __iomem *data_reg;
int irq; int irq;
int retval = 0; int retval = 0;
struct resource *irq_res;
unsigned int irq_flags = 0;
/* basic sanity checks first. board-specific init logic should /* basic sanity checks first. board-specific init logic should
* have initialized this the three resources and probably board * have initialized this the three resources and probably board
...@@ -2710,11 +2712,12 @@ static int __init isp1362_probe(struct platform_device *pdev) ...@@ -2710,11 +2712,12 @@ static int __init isp1362_probe(struct platform_device *pdev)
data = platform_get_resource(pdev, IORESOURCE_MEM, 0); data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
irq = platform_get_irq(pdev, 0); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!addr || !data || irq < 0) { if (!addr || !data || !irq_res) {
retval = -ENODEV; retval = -ENODEV;
goto err1; goto err1;
} }
irq = irq_res->start;
#ifdef CONFIG_USB_HCD_DMA #ifdef CONFIG_USB_HCD_DMA
if (pdev->dev.dma_mask) { if (pdev->dev.dma_mask) {
...@@ -2781,12 +2784,16 @@ static int __init isp1362_probe(struct platform_device *pdev) ...@@ -2781,12 +2784,16 @@ static int __init isp1362_probe(struct platform_device *pdev)
} }
#endif #endif
#ifdef CONFIG_ARM if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE)
if (isp1362_hcd->board) irq_flags |= IRQF_TRIGGER_RISING;
set_irq_type(irq, isp1362_hcd->board->int_act_high ? IRQT_RISING : IRQT_FALLING); if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE)
#endif 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) if (retval != 0)
goto err6; goto err6;
pr_info("%s, irq %d\n", hcd->product_desc, irq); pr_info("%s, irq %d\n", hcd->product_desc, irq);
......
...@@ -1039,12 +1039,12 @@ static void do_atl_int(struct usb_hcd *usb_hcd) ...@@ -1039,12 +1039,12 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) { if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) {
u32 buffstatus; u32 buffstatus;
/* XXX /*
* NAKs are handled in HW by the chip. Usually if the * NAKs are handled in HW by the chip. Usually if the
* device is not able to send data fast enough. * 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, "%d of %zu done: %08x cur: %08x\n", qtd,
urb, qh, PTD_XFERRED_LENGTH(dw3), urb, qh, PTD_XFERRED_LENGTH(dw3),
qtd->length, done_map, qtd->length, done_map,
......
...@@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hcd *hcd) ...@@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hcd *hcd)
spin_lock_irq(&uhci->lock); spin_lock_irq(&uhci->lock);
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
rc = -ESHUTDOWN; 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); suspend_rh(uhci, UHCI_RH_SUSPENDED);
spin_unlock_irq(&uhci->lock); spin_unlock_irq(&uhci->lock);
return rc; return rc;
......
...@@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci) ...@@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
/* Port received a wakeup request */ /* Port received a wakeup request */
set_bit(port, &uhci->resuming_ports); set_bit(port, &uhci->resuming_ports);
uhci->ports_timeout = jiffies + uhci->ports_timeout = jiffies +
msecs_to_jiffies(20); msecs_to_jiffies(25);
/* Make sure we see the port again /* Make sure we see the port again
* after the resuming period is over. */ * after the resuming period is over. */
......
...@@ -386,12 +386,12 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) ...@@ -386,12 +386,12 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
dbg("%s - port %d", __func__, port->number); 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; 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); chars = kfifo_len(&port->write_fifo);
spin_unlock_irqrestore(&port->lock, flags);
dbg("%s - returns %d", __func__, chars); dbg("%s - returns %d", __func__, chars);
return chars; return chars;
...@@ -489,6 +489,8 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) ...@@ -489,6 +489,8 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
dbg("%s - port %d", __func__, port->number); dbg("%s - port %d", __func__, port->number);
if (port->serial->type->max_in_flight_urbs) { if (port->serial->type->max_in_flight_urbs) {
kfree(urb->transfer_buffer);
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
--port->urbs_in_flight; --port->urbs_in_flight;
port->tx_bytes_flight -= urb->transfer_buffer_length; port->tx_bytes_flight -= urb->transfer_buffer_length;
......
...@@ -1807,13 +1807,6 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, ...@@ -1807,13 +1807,6 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_GO_SLOW ), 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> /* Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
* Mio Moov 330 * Mio Moov 330
*/ */
......
...@@ -434,7 +434,8 @@ static void adjust_quirks(struct us_data *us) ...@@ -434,7 +434,8 @@ static void adjust_quirks(struct us_data *us)
u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor); u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor);
u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct); u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
unsigned f = 0; 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_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 | US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
......
...@@ -192,6 +192,7 @@ struct usb_interface { ...@@ -192,6 +192,7 @@ struct usb_interface {
unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */
unsigned needs_binding:1; /* needs delayed unbind/rebind */ unsigned needs_binding:1; /* needs delayed unbind/rebind */
unsigned reset_running:1; unsigned reset_running:1;
unsigned resetting_device:1; /* true: bandwidth alloc after reset */
struct device dev; /* interface specific device info */ struct device dev; /* interface specific device info */
struct device *usb_dev; struct device *usb_dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment