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: adding comment for ipaq forcing number of ports
  USB: fix Oops on loading ipaq module since 2.6.26
  USB: add a pl2303 device id
  USB: another option device id
  USB: don't lose disconnections during suspend
  USB: fix interrupt disabling for HCDs with shared interrupt handlers
  USB: New device ID for ftdi_sio driver
  sisusbvga: Fix oops on disconnect.
  USB: mass storage: new id for US_SC_CYP_ATACB
  USB: ohci - record data toggle after unlink
  USB: ehci - fix timer regression
  USB: fix cdc-acm resume()
  OHCI: Fix problem if SM501 and another platform driver is selected
This commit is contained in:
Linus Torvalds 2008-07-03 21:29:08 -07:00
commit bf9127c363
14 changed files with 89 additions and 37 deletions

View file

@ -1125,9 +1125,6 @@ static void stop_data_traffic(struct acm *acm)
for (i = 0; i < acm->rx_buflimit; i++) for (i = 0; i < acm->rx_buflimit; i++)
usb_kill_urb(acm->ru[i].urb); usb_kill_urb(acm->ru[i].urb);
INIT_LIST_HEAD(&acm->filled_read_bufs);
INIT_LIST_HEAD(&acm->spare_read_bufs);
tasklet_enable(&acm->urb_task); tasklet_enable(&acm->urb_task);
cancel_work_sync(&acm->work); cancel_work_sync(&acm->work);

View file

@ -1684,19 +1684,30 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
irqreturn_t usb_hcd_irq (int irq, void *__hcd) irqreturn_t usb_hcd_irq (int irq, void *__hcd)
{ {
struct usb_hcd *hcd = __hcd; struct usb_hcd *hcd = __hcd;
int start = hcd->state; unsigned long flags;
irqreturn_t rc;
if (unlikely(start == HC_STATE_HALT || /* IRQF_DISABLED doesn't work correctly with shared IRQs
!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) * when the first handler doesn't use it. So let's just
return IRQ_NONE; * assume it's never used.
if (hcd->driver->irq (hcd) == IRQ_NONE) */
return IRQ_NONE; local_irq_save(flags);
set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); if (unlikely(hcd->state == HC_STATE_HALT ||
!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
rc = IRQ_NONE;
} else if (hcd->driver->irq(hcd) == IRQ_NONE) {
rc = IRQ_NONE;
} else {
set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
if (unlikely(hcd->state == HC_STATE_HALT)) if (unlikely(hcd->state == HC_STATE_HALT))
usb_hc_died (hcd); usb_hc_died(hcd);
return IRQ_HANDLED; rc = IRQ_HANDLED;
}
local_irq_restore(flags);
return rc;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -1860,6 +1871,13 @@ int usb_add_hcd(struct usb_hcd *hcd,
/* enable irqs just before we start the controller */ /* enable irqs just before we start the controller */
if (hcd->driver->irq) { if (hcd->driver->irq) {
/* IRQF_DISABLED doesn't work as advertised when used together
* with IRQF_SHARED. As usb_hcd_irq() will always disable
* interrupts we can remove it here.
*/
irqflags &= ~IRQF_DISABLED;
snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
hcd->driver->description, hcd->self.busnum); hcd->driver->description, hcd->self.busnum);
if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,

View file

@ -713,18 +713,11 @@ static void hub_restart(struct usb_hub *hub, int type)
} }
/* Was the power session lost while we were suspended? */ /* Was the power session lost while we were suspended? */
switch (type) { status = hub_port_status(hub, port1, &portstatus, &portchange);
case HUB_RESET_RESUME:
portstatus = 0;
portchange = USB_PORT_STAT_C_CONNECTION;
break;
case HUB_RESET: /* If the device is gone, khubd will handle it later */
case HUB_RESUME: if (status == 0 && !(portstatus & USB_PORT_STAT_CONNECTION))
status = hub_port_status(hub, port1, continue;
&portstatus, &portchange);
break;
}
/* For "USB_PERSIST"-enabled children we must /* For "USB_PERSIST"-enabled children we must
* mark the child device for reset-resume and * mark the child device for reset-resume and

View file

@ -177,6 +177,15 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
static inline void static inline void
timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
{ {
/* Don't override timeouts which shrink or (later) disable
* the async ring; just the I/O watchdog. Note that if a
* SHRINK were pending, OFF would never be requested.
*/
if (timer_pending(&ehci->watchdog)
&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
& ehci->actions))
return;
if (!test_and_set_bit (action, &ehci->actions)) { if (!test_and_set_bit (action, &ehci->actions)) {
unsigned long t; unsigned long t;
@ -192,15 +201,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
t = EHCI_SHRINK_JIFFIES; t = EHCI_SHRINK_JIFFIES;
break; break;
} }
t += jiffies; mod_timer(&ehci->watchdog, t + jiffies);
// all timings except IAA watchdog can be overridden.
// async queue SHRINK often precedes IAA. while it's ready
// to go OFF neither can matter, and afterwards the IO
// watchdog stops unless there's still periodic traffic.
if (time_before_eq(t, ehci->watchdog.expires)
&& timer_pending (&ehci->watchdog))
return;
mod_timer (&ehci->watchdog, t);
} }
} }

View file

@ -1054,7 +1054,7 @@ MODULE_LICENSE ("GPL");
#ifdef CONFIG_MFD_SM501 #ifdef CONFIG_MFD_SM501
#include "ohci-sm501.c" #include "ohci-sm501.c"
#define PLATFORM_DRIVER ohci_hcd_sm501_driver #define SM501_OHCI_DRIVER ohci_hcd_sm501_driver
#endif #endif
#if !defined(PCI_DRIVER) && \ #if !defined(PCI_DRIVER) && \
@ -1062,6 +1062,7 @@ MODULE_LICENSE ("GPL");
!defined(OF_PLATFORM_DRIVER) && \ !defined(OF_PLATFORM_DRIVER) && \
!defined(SA1111_DRIVER) && \ !defined(SA1111_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && \
!defined(SM501_OHCI_DRIVER) && \
!defined(SSB_OHCI_DRIVER) !defined(SSB_OHCI_DRIVER)
#error "missing bus glue for ohci-hcd" #error "missing bus glue for ohci-hcd"
#endif #endif
@ -1121,9 +1122,18 @@ static int __init ohci_hcd_mod_init(void)
goto error_ssb; goto error_ssb;
#endif #endif
#ifdef SM501_OHCI_DRIVER
retval = platform_driver_register(&SM501_OHCI_DRIVER);
if (retval < 0)
goto error_sm501;
#endif
return retval; return retval;
/* Error path */ /* Error path */
#ifdef SM501_OHCI_DRIVER
error_sm501:
#endif
#ifdef SSB_OHCI_DRIVER #ifdef SSB_OHCI_DRIVER
error_ssb: error_ssb:
#endif #endif
@ -1159,6 +1169,9 @@ module_init(ohci_hcd_mod_init);
static void __exit ohci_hcd_mod_exit(void) static void __exit ohci_hcd_mod_exit(void)
{ {
#ifdef SM501_OHCI_DRIVER
platform_driver_unregister(&SM501_OHCI_DRIVER);
#endif
#ifdef SSB_OHCI_DRIVER #ifdef SSB_OHCI_DRIVER
ssb_driver_unregister(&SSB_OHCI_DRIVER); ssb_driver_unregister(&SSB_OHCI_DRIVER);
#endif #endif

View file

@ -952,6 +952,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick)
struct urb *urb; struct urb *urb;
urb_priv_t *urb_priv; urb_priv_t *urb_priv;
__hc32 savebits; __hc32 savebits;
u32 tdINFO;
td = list_entry (entry, struct td, td_list); td = list_entry (entry, struct td, td_list);
urb = td->urb; urb = td->urb;
@ -966,6 +967,17 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick)
savebits = *prev & ~cpu_to_hc32 (ohci, TD_MASK); savebits = *prev & ~cpu_to_hc32 (ohci, TD_MASK);
*prev = td->hwNextTD | savebits; *prev = td->hwNextTD | savebits;
/* If this was unlinked, the TD may not have been
* retired ... so manually save the data toggle.
* The controller ignores the value we save for
* control and ISO endpoints.
*/
tdINFO = hc32_to_cpup(ohci, &td->hwINFO);
if ((tdINFO & TD_T) == TD_T_DATA0)
ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_C);
else if ((tdINFO & TD_T) == TD_T_DATA1)
ed->hwHeadP |= cpu_to_hc32(ohci, ED_C);
/* HC may have partly processed this TD */ /* HC may have partly processed this TD */
td_done (ohci, urb, td); td_done (ohci, urb, td);
urb_priv->td_cnt++; urb_priv->td_cnt++;

View file

@ -3264,8 +3264,6 @@ static void sisusb_disconnect(struct usb_interface *intf)
/* decrement our usage count */ /* decrement our usage count */
kref_put(&sisusb->kref, sisusb_delete); kref_put(&sisusb->kref, sisusb_delete);
dev_info(&sisusb->sisusb_dev->dev, "Disconnected\n");
} }
static struct usb_device_id sisusb_table [] = { static struct usb_device_id sisusb_table [] = {

View file

@ -637,6 +637,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
{ }, /* Optional parameter entry */ { }, /* Optional parameter entry */
{ } /* Terminating entry */ { } /* Terminating entry */
}; };

View file

@ -828,6 +828,9 @@
/* Propox devices */ /* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
/* Rig Expert Ukraine devices */
#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */
/* Commands */ /* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */

View file

@ -570,7 +570,12 @@ static struct usb_serial_driver ipaq_device = {
.description = "PocketPC PDA", .description = "PocketPC PDA",
.usb_driver = &ipaq_driver, .usb_driver = &ipaq_driver,
.id_table = ipaq_id_table, .id_table = ipaq_id_table,
.num_ports = 2, /*
* some devices have an extra endpoint, which
* must be ignored as it would make the core
* create a second port which oopses when used
*/
.num_ports = 1,
.open = ipaq_open, .open = ipaq_open,
.close = ipaq_close, .close = ipaq_close,
.attach = ipaq_startup, .attach = ipaq_startup,

View file

@ -306,6 +306,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },

View file

@ -57,6 +57,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },

View file

@ -15,6 +15,7 @@
#define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 #define PL2303_PRODUCT_ID_RSAQ3 0xaaa2
#define PL2303_PRODUCT_ID_ALDIGA 0x0611 #define PL2303_PRODUCT_ID_ALDIGA 0x0611
#define PL2303_PRODUCT_ID_MMX 0x0612 #define PL2303_PRODUCT_ID_MMX 0x0612
#define PL2303_PRODUCT_ID_GPRS 0x0609
#define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID 0x0557
#define ATEN_VENDOR_ID2 0x0547 #define ATEN_VENDOR_ID2 0x0547

View file

@ -402,11 +402,19 @@ UNUSUAL_DEV( 0x04a5, 0x3010, 0x0100, 0x0100,
US_FL_IGNORE_RESIDUE ), US_FL_IGNORE_RESIDUE ),
#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
/* CY7C68300 : support atacb */
UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999,
"Cypress", "Cypress",
"Cypress AT2LP", "Cypress AT2LP",
US_SC_CYP_ATACB, US_PR_DEVICE, NULL, US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
0), 0),
/* CY7C68310 : support atacb and atacb2 */
UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999,
"Cypress",
"Cypress ISD-300LP",
US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
0),
#endif #endif
/* Reported by Simon Levitt <simon@whattf.com> /* Reported by Simon Levitt <simon@whattf.com>