Commit cbae4873 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (42 commits)
  usb: gadget: composite: avoid access beyond array max length
  USB: serial: handle Data Carrier Detect changes
  USB: gadget: Fix endpoint representation in ci13xxx_udc
  USB: gadget: Fix error path in ci13xxx_udc gadget probe function
  usb: pch_udc: Fix the worning log issue at gadget driver remove
  USB: serial: Updated support for ICOM devices
  USB: ehci-mxc: add work-around for efika mx/sb bug
  USB: unbreak ehci-mxc on otg port of i.MX27
  drivers: update to pl2303 usb-serial to support Motorola cables
  USB: adding USB support for Cinterion's HC2x, EU3 and PH8 products
  USB serial: add missing .usb_driver field in serial drivers
  USB: ehci-fsl: Fix 'have_sysif_regs' detection
  USB: g_printer: fix bug in module parameter definitions
  USB: g_printer: fix bug in unregistration
  USB: uss720: remove duplicate USB device
  MAINTAINERS: add ueagle-atm entry
  USB: EHCI: fix DMA deallocation bug
  USB: pch_udc: support new device ML7213 IOH
  usb: pch_udc: Fixed issue which does not work with g_serial
  usb: set ep_dev async suspend should be later than device_initialize
  ...
parents fb1c6348 fd96d0d8
...@@ -3139,6 +3139,12 @@ S: Maintained ...@@ -3139,6 +3139,12 @@ S: Maintained
F: net/ieee802154/ F: net/ieee802154/
F: drivers/ieee802154/ F: drivers/ieee802154/
IKANOS/ADI EAGLE ADSL USB DRIVER
M: Matthieu Castet <castet.matthieu@free.fr>
M: Stanislaw Gruszka <stf_xl@wp.pl>
S: Maintained
F: drivers/usb/atm/ueagle-atm.c
INTEGRITY MEASUREMENT ARCHITECTURE (IMA) INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
M: Mimi Zohar <zohar@us.ibm.com> M: Mimi Zohar <zohar@us.ibm.com>
S: Supported S: Supported
......
...@@ -342,7 +342,7 @@ static ssize_t wdm_write ...@@ -342,7 +342,7 @@ static ssize_t wdm_write
goto outnp; goto outnp;
} }
if (!file->f_flags && O_NONBLOCK) if (!(file->f_flags & O_NONBLOCK))
r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
&desc->flags)); &desc->flags));
else else
......
...@@ -192,12 +192,12 @@ int usb_create_ep_devs(struct device *parent, ...@@ -192,12 +192,12 @@ int usb_create_ep_devs(struct device *parent,
ep_dev->dev.parent = parent; ep_dev->dev.parent = parent;
ep_dev->dev.release = ep_device_release; ep_dev->dev.release = ep_device_release;
dev_set_name(&ep_dev->dev, "ep_%02x", endpoint->desc.bEndpointAddress); dev_set_name(&ep_dev->dev, "ep_%02x", endpoint->desc.bEndpointAddress);
device_enable_async_suspend(&ep_dev->dev);
retval = device_register(&ep_dev->dev); retval = device_register(&ep_dev->dev);
if (retval) if (retval)
goto error_register; goto error_register;
device_enable_async_suspend(&ep_dev->dev);
endpoint->ep_dev = ep_dev; endpoint->ep_dev = ep_dev;
return retval; return retval;
......
...@@ -405,6 +405,11 @@ static int suspend_common(struct device *dev, bool do_wakeup) ...@@ -405,6 +405,11 @@ static int suspend_common(struct device *dev, bool do_wakeup)
return retval; return retval;
} }
/* If MSI-X is enabled, the driver will have synchronized all vectors
* in pci_suspend(). If MSI or legacy PCI is enabled, that will be
* synchronized here.
*/
if (!hcd->msix_enabled)
synchronize_irq(pci_dev->irq); synchronize_irq(pci_dev->irq);
/* Downstream ports from this root hub should already be quiesced, so /* Downstream ports from this root hub should already be quiesced, so
......
...@@ -676,6 +676,8 @@ static void hub_init_func3(struct work_struct *ws); ...@@ -676,6 +676,8 @@ static void hub_init_func3(struct work_struct *ws);
static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
{ {
struct usb_device *hdev = hub->hdev; struct usb_device *hdev = hub->hdev;
struct usb_hcd *hcd;
int ret;
int port1; int port1;
int status; int status;
bool need_debounce_delay = false; bool need_debounce_delay = false;
...@@ -714,6 +716,25 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) ...@@ -714,6 +716,25 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
usb_autopm_get_interface_no_resume( usb_autopm_get_interface_no_resume(
to_usb_interface(hub->intfdev)); to_usb_interface(hub->intfdev));
return; /* Continues at init2: below */ return; /* Continues at init2: below */
} else if (type == HUB_RESET_RESUME) {
/* The internal host controller state for the hub device
* may be gone after a host power loss on system resume.
* Update the device's info so the HW knows it's a hub.
*/
hcd = bus_to_hcd(hdev->bus);
if (hcd->driver->update_hub_device) {
ret = hcd->driver->update_hub_device(hcd, hdev,
&hub->tt, GFP_NOIO);
if (ret < 0) {
dev_err(hub->intfdev, "Host not "
"accepting hub info "
"update.\n");
dev_err(hub->intfdev, "LS/FS devices "
"and hubs may not work "
"under this hub\n.");
}
}
hub_power_on(hub, true);
} else { } else {
hub_power_on(hub, true); hub_power_on(hub, true);
} }
......
...@@ -509,7 +509,7 @@ config USB_LANGWELL ...@@ -509,7 +509,7 @@ config USB_LANGWELL
select USB_GADGET_SELECTED select USB_GADGET_SELECTED
config USB_GADGET_EG20T config USB_GADGET_EG20T
boolean "Intel EG20T(Topcliff) USB Device controller" boolean "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC"
depends on PCI depends on PCI
select USB_GADGET_DUALSPEED select USB_GADGET_DUALSPEED
help help
...@@ -525,6 +525,11 @@ config USB_GADGET_EG20T ...@@ -525,6 +525,11 @@ config USB_GADGET_EG20T
This driver dose not support interrupt transfer or isochronous This driver dose not support interrupt transfer or isochronous
transfer modes. transfer modes.
This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
for IVI(In-Vehicle Infotainment) use.
ML7213 is companion chip for Intel Atom E6xx series.
ML7213 is completely compatible for Intel EG20T PCH.
config USB_EG20T config USB_EG20T
tristate tristate
depends on USB_GADGET_EG20T depends on USB_GADGET_EG20T
......
This diff is collapsed.
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* DEFINE * DEFINE
*****************************************************************************/ *****************************************************************************/
#define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */ #define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */
#define ENDPT_MAX (16) #define ENDPT_MAX (32)
#define CTRL_PAYLOAD_MAX (64) #define CTRL_PAYLOAD_MAX (64)
#define RX (0) /* similar to USB_DIR_OUT but can be used as an index */ #define RX (0) /* similar to USB_DIR_OUT but can be used as an index */
#define TX (1) /* similar to USB_DIR_IN but can be used as an index */ #define TX (1) /* similar to USB_DIR_IN but can be used as an index */
...@@ -88,8 +88,7 @@ struct ci13xxx_ep { ...@@ -88,8 +88,7 @@ struct ci13xxx_ep {
struct list_head queue; struct list_head queue;
struct ci13xxx_qh *ptr; struct ci13xxx_qh *ptr;
dma_addr_t dma; dma_addr_t dma;
} qh[2]; } qh;
struct usb_request *status;
int wedge; int wedge;
/* global resources */ /* global resources */
...@@ -119,9 +118,13 @@ struct ci13xxx { ...@@ -119,9 +118,13 @@ struct ci13xxx {
struct dma_pool *qh_pool; /* DMA pool for queue heads */ struct dma_pool *qh_pool; /* DMA pool for queue heads */
struct dma_pool *td_pool; /* DMA pool for transfer descs */ struct dma_pool *td_pool; /* DMA pool for transfer descs */
struct usb_request *status; /* ep0 status request */
struct usb_gadget gadget; /* USB slave device */ struct usb_gadget gadget; /* USB slave device */
struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
u32 ep0_dir; /* ep0 direction */
#define ep0out ci13xxx_ep[0]
#define ep0in ci13xxx_ep[16]
struct usb_gadget_driver *driver; /* 3rd party gadget driver */ struct usb_gadget_driver *driver; /* 3rd party gadget driver */
struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ struct ci13xxx_udc_driver *udc_driver; /* device controller driver */
......
...@@ -928,7 +928,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -928,7 +928,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
*/ */
switch (ctrl->bRequestType & USB_RECIP_MASK) { switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_INTERFACE: case USB_RECIP_INTERFACE:
if (cdev->config) if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
break;
f = cdev->config->interface[intf]; f = cdev->config->interface[intf];
break; break;
......
This diff is collapsed.
...@@ -131,31 +131,31 @@ static struct printer_dev usb_printer_gadget; ...@@ -131,31 +131,31 @@ static struct printer_dev usb_printer_gadget;
* parameters are in UTF-8 (superset of ASCII's 7 bit characters). * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
*/ */
static ushort __initdata idVendor; static ushort idVendor;
module_param(idVendor, ushort, S_IRUGO); module_param(idVendor, ushort, S_IRUGO);
MODULE_PARM_DESC(idVendor, "USB Vendor ID"); MODULE_PARM_DESC(idVendor, "USB Vendor ID");
static ushort __initdata idProduct; static ushort idProduct;
module_param(idProduct, ushort, S_IRUGO); module_param(idProduct, ushort, S_IRUGO);
MODULE_PARM_DESC(idProduct, "USB Product ID"); MODULE_PARM_DESC(idProduct, "USB Product ID");
static ushort __initdata bcdDevice; static ushort bcdDevice;
module_param(bcdDevice, ushort, S_IRUGO); module_param(bcdDevice, ushort, S_IRUGO);
MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
static char *__initdata iManufacturer; static char *iManufacturer;
module_param(iManufacturer, charp, S_IRUGO); module_param(iManufacturer, charp, S_IRUGO);
MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
static char *__initdata iProduct; static char *iProduct;
module_param(iProduct, charp, S_IRUGO); module_param(iProduct, charp, S_IRUGO);
MODULE_PARM_DESC(iProduct, "USB Product string"); MODULE_PARM_DESC(iProduct, "USB Product string");
static char *__initdata iSerialNum; static char *iSerialNum;
module_param(iSerialNum, charp, S_IRUGO); module_param(iSerialNum, charp, S_IRUGO);
MODULE_PARM_DESC(iSerialNum, "1"); MODULE_PARM_DESC(iSerialNum, "1");
static char *__initdata iPNPstring; static char *iPNPstring;
module_param(iPNPstring, charp, S_IRUGO); module_param(iPNPstring, charp, S_IRUGO);
MODULE_PARM_DESC(iPNPstring, "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"); MODULE_PARM_DESC(iPNPstring, "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;");
...@@ -1596,13 +1596,12 @@ cleanup(void) ...@@ -1596,13 +1596,12 @@ cleanup(void)
int status; int status;
mutex_lock(&usb_printer_gadget.lock_printer_io); mutex_lock(&usb_printer_gadget.lock_printer_io);
class_destroy(usb_gadget_class);
unregister_chrdev_region(g_printer_devno, 2);
status = usb_gadget_unregister_driver(&printer_driver); status = usb_gadget_unregister_driver(&printer_driver);
if (status) if (status)
ERROR(dev, "usb_gadget_unregister_driver %x\n", status); ERROR(dev, "usb_gadget_unregister_driver %x\n", status);
unregister_chrdev_region(g_printer_devno, 2);
class_destroy(usb_gadget_class);
mutex_unlock(&usb_printer_gadget.lock_printer_io); mutex_unlock(&usb_printer_gadget.lock_printer_io);
} }
module_exit(cleanup); module_exit(cleanup);
...@@ -52,7 +52,6 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, ...@@ -52,7 +52,6 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
struct resource *res; struct resource *res;
int irq; int irq;
int retval; int retval;
unsigned int temp;
pr_debug("initializing FSL-SOC USB Controller\n"); pr_debug("initializing FSL-SOC USB Controller\n");
...@@ -126,18 +125,6 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, ...@@ -126,18 +125,6 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
goto err3; goto err3;
} }
/*
* Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs
* flag for 83xx or 8536 system interface registers.
*/
if (pdata->big_endian_mmio)
temp = in_be32(hcd->regs + FSL_SOC_USB_ID);
else
temp = in_le32(hcd->regs + FSL_SOC_USB_ID);
if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK))
pdata->have_sysif_regs = 1;
/* Enable USB controller, 83xx or 8536 */ /* Enable USB controller, 83xx or 8536 */
if (pdata->have_sysif_regs) if (pdata->have_sysif_regs)
setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4); setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);
......
...@@ -19,9 +19,6 @@ ...@@ -19,9 +19,6 @@
#define _EHCI_FSL_H #define _EHCI_FSL_H
/* offsets for the non-ehci registers in the FSL SOC USB controller */ /* offsets for the non-ehci registers in the FSL SOC USB controller */
#define FSL_SOC_USB_ID 0x0
#define ID_MSK 0x3f
#define NID_MSK 0x3f00
#define FSL_SOC_USB_ULPIVP 0x170 #define FSL_SOC_USB_ULPIVP 0x170
#define FSL_SOC_USB_PORTSC1 0x184 #define FSL_SOC_USB_PORTSC1 0x184
#define PORT_PTS_MSK (3<<30) #define PORT_PTS_MSK (3<<30)
......
...@@ -572,6 +572,8 @@ static int ehci_init(struct usb_hcd *hcd) ...@@ -572,6 +572,8 @@ static int ehci_init(struct usb_hcd *hcd)
ehci->iaa_watchdog.function = ehci_iaa_watchdog; ehci->iaa_watchdog.function = ehci_iaa_watchdog;
ehci->iaa_watchdog.data = (unsigned long) ehci; ehci->iaa_watchdog.data = (unsigned long) ehci;
hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
/* /*
* hw default: 1K periodic list heads, one per frame. * hw default: 1K periodic list heads, one per frame.
* periodic_size can shrink by USBCMD update if hcc_params allows. * periodic_size can shrink by USBCMD update if hcc_params allows.
...@@ -579,11 +581,20 @@ static int ehci_init(struct usb_hcd *hcd) ...@@ -579,11 +581,20 @@ static int ehci_init(struct usb_hcd *hcd)
ehci->periodic_size = DEFAULT_I_TDPS; ehci->periodic_size = DEFAULT_I_TDPS;
INIT_LIST_HEAD(&ehci->cached_itd_list); INIT_LIST_HEAD(&ehci->cached_itd_list);
INIT_LIST_HEAD(&ehci->cached_sitd_list); INIT_LIST_HEAD(&ehci->cached_sitd_list);
if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
/* periodic schedule size can be smaller than default */
switch (EHCI_TUNE_FLS) {
case 0: ehci->periodic_size = 1024; break;
case 1: ehci->periodic_size = 512; break;
case 2: ehci->periodic_size = 256; break;
default: BUG();
}
}
if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
return retval; return retval;
/* controllers may cache some of the periodic schedule ... */ /* controllers may cache some of the periodic schedule ... */
hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
if (HCC_ISOC_CACHE(hcc_params)) // full frame cache if (HCC_ISOC_CACHE(hcc_params)) // full frame cache
ehci->i_thresh = 2 + 8; ehci->i_thresh = 2 + 8;
else // N microframes cached else // N microframes cached
...@@ -637,12 +648,6 @@ static int ehci_init(struct usb_hcd *hcd) ...@@ -637,12 +648,6 @@ static int ehci_init(struct usb_hcd *hcd)
/* periodic schedule size can be smaller than default */ /* periodic schedule size can be smaller than default */
temp &= ~(3 << 2); temp &= ~(3 << 2);
temp |= (EHCI_TUNE_FLS << 2); temp |= (EHCI_TUNE_FLS << 2);
switch (EHCI_TUNE_FLS) {
case 0: ehci->periodic_size = 1024; break;
case 1: ehci->periodic_size = 512; break;
case 2: ehci->periodic_size = 256; break;
default: BUG();
}
} }
if (HCC_LPM(hcc_params)) { if (HCC_LPM(hcc_params)) {
/* support link power management EHCI 1.1 addendum */ /* support link power management EHCI 1.1 addendum */
......
...@@ -21,10 +21,13 @@ ...@@ -21,10 +21,13 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <mach/mxc_ehci.h> #include <mach/mxc_ehci.h>
#include <asm/mach-types.h>
#define ULPI_VIEWPORT_OFFSET 0x170 #define ULPI_VIEWPORT_OFFSET 0x170
struct ehci_mxc_priv { struct ehci_mxc_priv {
...@@ -114,6 +117,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -114,6 +117,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
struct usb_hcd *hcd; struct usb_hcd *hcd;
struct resource *res; struct resource *res;
int irq, ret; int irq, ret;
unsigned int flags;
struct ehci_mxc_priv *priv; struct ehci_mxc_priv *priv;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ehci_hcd *ehci; struct ehci_hcd *ehci;
...@@ -177,8 +181,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -177,8 +181,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
clk_enable(priv->ahbclk); clk_enable(priv->ahbclk);
} }
/* "dr" device has its own clock */ /* "dr" device has its own clock on i.MX51 */
if (pdev->id == 0) { if (cpu_is_mx51() && (pdev->id == 0)) {
priv->phy1clk = clk_get(dev, "usb_phy1"); priv->phy1clk = clk_get(dev, "usb_phy1");
if (IS_ERR(priv->phy1clk)) { if (IS_ERR(priv->phy1clk)) {
ret = PTR_ERR(priv->phy1clk); ret = PTR_ERR(priv->phy1clk);
...@@ -240,6 +244,23 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -240,6 +244,23 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_add; goto err_add;
if (pdata->otg) {
/*
* efikamx and efikasb have some hardware bug which is
* preventing usb to work unless CHRGVBUS is set.
* It's in violation of USB specs
*/
if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) {
flags = otg_io_read(pdata->otg, ULPI_OTG_CTRL);
flags |= ULPI_OTG_CTRL_CHRGVBUS;
ret = otg_io_write(pdata->otg, flags, ULPI_OTG_CTRL);
if (ret) {
dev_err(dev, "unable to set CHRVBUS\n");
goto err_add;
}
}
}
return 0; return 0;
err_add: err_add:
......
...@@ -44,28 +44,35 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) ...@@ -44,28 +44,35 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
return 0; return 0;
} }
static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci) static int ehci_quirk_amd_hudson(struct ehci_hcd *ehci)
{ {
struct pci_dev *amd_smbus_dev; struct pci_dev *amd_smbus_dev;
u8 rev = 0; u8 rev = 0;
amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL);
if (amd_smbus_dev) {
pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
if (rev < 0x40) {
pci_dev_put(amd_smbus_dev);
amd_smbus_dev = NULL;
return 0;
}
} else {
amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x780b, NULL);
if (!amd_smbus_dev) if (!amd_smbus_dev)
return 0; return 0;
pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
if (rev < 0x40) { if (rev < 0x11 || rev > 0x18) {
pci_dev_put(amd_smbus_dev); pci_dev_put(amd_smbus_dev);
amd_smbus_dev = NULL; amd_smbus_dev = NULL;
return 0; return 0;
} }
}
if (!amd_nb_dev) if (!amd_nb_dev)
amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL);
if (!amd_nb_dev)
ehci_err(ehci, "QUIRK: unable to get AMD NB device\n");
ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n"); ehci_info(ehci, "QUIRK: Enable exception for AMD Hudson ASPM\n");
pci_dev_put(amd_smbus_dev); pci_dev_put(amd_smbus_dev);
amd_smbus_dev = NULL; amd_smbus_dev = NULL;
...@@ -131,7 +138,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ...@@ -131,7 +138,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
/* cache this readonly data; minimize chip reads */ /* cache this readonly data; minimize chip reads */
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
if (ehci_quirk_amd_SB800(ehci)) if (ehci_quirk_amd_hudson(ehci))
ehci->amd_l1_fix = 1; ehci->amd_l1_fix = 1;
retval = ehci_halt(ehci); retval = ehci_halt(ehci);
......
...@@ -262,19 +262,24 @@ static void fsl_usb2_mpc5121_exit(struct platform_device *pdev) ...@@ -262,19 +262,24 @@ static void fsl_usb2_mpc5121_exit(struct platform_device *pdev)
} }
} }
struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = { static struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = {
.big_endian_desc = 1, .big_endian_desc = 1,
.big_endian_mmio = 1, .big_endian_mmio = 1,
.es = 1, .es = 1,
.have_sysif_regs = 0,
.le_setup_buf = 1, .le_setup_buf = 1,
.init = fsl_usb2_mpc5121_init, .init = fsl_usb2_mpc5121_init,
.exit = fsl_usb2_mpc5121_exit, .exit = fsl_usb2_mpc5121_exit,
}; };
#endif /* CONFIG_PPC_MPC512x */ #endif /* CONFIG_PPC_MPC512x */
static struct fsl_usb2_platform_data fsl_usb2_mpc8xxx_pd = {
.have_sysif_regs = 1,
};
static const struct of_device_id fsl_usb2_mph_dr_of_match[] = { static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
{ .compatible = "fsl-usb2-mph", }, { .compatible = "fsl-usb2-mph", .data = &fsl_usb2_mpc8xxx_pd, },
{ .compatible = "fsl-usb2-dr", }, { .compatible = "fsl-usb2-dr", .data = &fsl_usb2_mpc8xxx_pd, },
#ifdef CONFIG_PPC_MPC512x #ifdef CONFIG_PPC_MPC512x
{ .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, }, { .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, },
#endif #endif
......
...@@ -308,11 +308,8 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, ...@@ -308,11 +308,8 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring,
/* Ring the host controller doorbell after placing a command on the ring */ /* Ring the host controller doorbell after placing a command on the ring */
void xhci_ring_cmd_db(struct xhci_hcd *xhci) void xhci_ring_cmd_db(struct xhci_hcd *xhci)
{ {
u32 temp;
xhci_dbg(xhci, "// Ding dong!\n"); xhci_dbg(xhci, "// Ding dong!\n");
temp = xhci_readl(xhci, &xhci->dba->doorbell[0]) & DB_MASK; xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]);
xhci_writel(xhci, temp | DB_TARGET_HOST, &xhci->dba->doorbell[0]);
/* Flush PCI posted writes */ /* Flush PCI posted writes */
xhci_readl(xhci, &xhci->dba->doorbell[0]); xhci_readl(xhci, &xhci->dba->doorbell[0]);
} }
...@@ -322,26 +319,24 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, ...@@ -322,26 +319,24 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
unsigned int ep_index, unsigned int ep_index,
unsigned int stream_id) unsigned int stream_id)
{ {
struct xhci_virt_ep *ep;
unsigned int ep_state;
u32 field;
__u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id]; __u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id];
struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
unsigned int ep_state = ep->ep_state;
ep = &xhci->devs[slot_id]->eps[ep_index];
ep_state = ep->ep_state;
/* Don't ring the doorbell for this endpoint if there are pending /* Don't ring the doorbell for this endpoint if there are pending
* cancellations because the we don't want to interrupt processing. * cancellations because we don't want to interrupt processing.
* We don't want to restart any stream rings if there's a set dequeue * We don't want to restart any stream rings if there's a set dequeue
* pointer command pending because the device can choose to start any * pointer command pending because the device can choose to start any
* stream once the endpoint is on the HW schedule. * stream once the endpoint is on the HW schedule.
* FIXME - check all the stream rings for pending cancellations. * FIXME - check all the stream rings for pending cancellations.
*/ */
if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING) if ((ep_state & EP_HALT_PENDING) || (ep_state & SET_DEQ_PENDING) ||
&& !(ep_state & EP_HALTED)) { (ep_state & EP_HALTED))
field = xhci_readl(xhci, db_addr) & DB_MASK; return;
field |= EPI_TO_DB(ep_index) | STREAM_ID_TO_DB(stream_id); xhci_writel(xhci, DB_VALUE(ep_index, stream_id), db_addr);
xhci_writel(xhci, field, db_addr); /* The CPU has better things to do at this point than wait for a
} * write-posting flush. It'll get there soon enough.
*/
} }
/* Ring the doorbell for any rings with pending URBs */ /* Ring the doorbell for any rings with pending URBs */
...@@ -1188,7 +1183,7 @@ static void handle_port_status(struct xhci_hcd *xhci, ...@@ -1188,7 +1183,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1); addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1);
temp = xhci_readl(xhci, addr); temp = xhci_readl(xhci, addr);
if ((temp & PORT_CONNECT) && (hcd->state == HC_STATE_SUSPENDED)) { if (hcd->state == HC_STATE_SUSPENDED) {
xhci_dbg(xhci, "resume root hub\n"); xhci_dbg(xhci, "resume root hub\n");
usb_hcd_resume_root_hub(hcd); usb_hcd_resume_root_hub(hcd);
} }
...@@ -1710,8 +1705,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1710,8 +1705,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* Others already handled above */ /* Others already handled above */
break; break;
} }
dev_dbg(&td->urb->dev->dev, xhci_dbg(xhci, "ep %#x - asked for %d bytes, "
"ep %#x - asked for %d bytes, "
"%d bytes untransferred\n", "%d bytes untransferred\n",
td->urb->ep->desc.bEndpointAddress, td->urb->ep->desc.bEndpointAddress,
td->urb->transfer_buffer_length, td->urb->transfer_buffer_length,
...@@ -2389,7 +2383,8 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) ...@@ -2389,7 +2383,8 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb)
} }
xhci_dbg(xhci, "\n"); xhci_dbg(xhci, "\n");
if (!in_interrupt()) if (!in_interrupt())
dev_dbg(&urb->dev->dev, "ep %#x - urb len = %d, sglist used, num_trbs = %d\n", xhci_dbg(xhci, "ep %#x - urb len = %d, sglist used, "
"num_trbs = %d\n",
urb->ep->desc.bEndpointAddress, urb->ep->desc.bEndpointAddress,
urb->transfer_buffer_length, urb->transfer_buffer_length,
num_trbs); num_trbs);
...@@ -2414,14 +2409,17 @@ static void check_trb_math(struct urb *urb, int num_trbs, int running_total) ...@@ -2414,14 +2409,17 @@ static void check_trb_math(struct urb *urb, int num_trbs, int running_total)
static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id, static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id,
unsigned int ep_index, unsigned int stream_id, int start_cycle, unsigned int ep_index, unsigned int stream_id, int start_cycle,
struct xhci_generic_trb *start_trb, struct xhci_td *td) struct xhci_generic_trb *start_trb)
{ {
/* /*
* Pass all the TRBs to the hardware at once and make sure this write * Pass all the TRBs to the hardware at once and make sure this write
* isn't reordered. * isn't reordered.
*/ */
wmb(); wmb();
if (start_cycle)
start_trb->field[3] |= start_cycle; start_trb->field[3] |= start_cycle;
else
start_trb->field[3] &= ~0x1;
xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id);
} }
...@@ -2449,7 +2447,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2449,7 +2447,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
* to set the polling interval (once the API is added). * to set the polling interval (once the API is added).
*/ */
if (xhci_interval != ep_interval) { if (xhci_interval != ep_interval) {
if (!printk_ratelimit()) if (printk_ratelimit())
dev_dbg(&urb->dev->dev, "Driver uses different interval" dev_dbg(&urb->dev->dev, "Driver uses different interval"
" (%d microframe%s) than xHCI " " (%d microframe%s) than xHCI "
"(%d microframe%s)\n", "(%d microframe%s)\n",
...@@ -2551,9 +2549,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2551,9 +2549,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
u32 remainder = 0; u32 remainder = 0;
/* Don't change the cycle bit of the first TRB until later */ /* Don't change the cycle bit of the first TRB until later */
if (first_trb) if (first_trb) {
first_trb = false; first_trb = false;
else if (start_cycle == 0)
field |= 0x1;
} else
field |= ep_ring->cycle_state; field |= ep_ring->cycle_state;
/* Chain all the TRBs together; clear the chain bit in the last /* Chain all the TRBs together; clear the chain bit in the last
...@@ -2625,7 +2625,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2625,7 +2625,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
check_trb_math(urb, num_trbs, running_total); check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
start_cycle, start_trb, td); start_cycle, start_trb);
return 0; return 0;
} }
...@@ -2671,7 +2671,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2671,7 +2671,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */ /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
if (!in_interrupt()) if (!in_interrupt())
dev_dbg(&urb->dev->dev, "ep %#x - urb len = %#x (%d), addr = %#llx, num_trbs = %d\n", xhci_dbg(xhci, "ep %#x - urb len = %#x (%d), "
"addr = %#llx, num_trbs = %d\n",
urb->ep->desc.bEndpointAddress, urb->ep->desc.bEndpointAddress,
urb->transfer_buffer_length, urb->transfer_buffer_length,
urb->transfer_buffer_length, urb->transfer_buffer_length,
...@@ -2711,9 +2712,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2711,9 +2712,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
field = 0; field = 0;
/* Don't change the cycle bit of the first TRB until later */ /* Don't change the cycle bit of the first TRB until later */
if (first_trb) if (first_trb) {
first_trb = false; first_trb = false;
else if (start_cycle == 0)
field |= 0x1;
} else
field |= ep_ring->cycle_state; field |= ep_ring->cycle_state;
/* Chain all the TRBs together; clear the chain bit in the last /* Chain all the TRBs together; clear the chain bit in the last
...@@ -2757,7 +2760,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2757,7 +2760,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
check_trb_math(urb, num_trbs, running_total); check_trb_math(urb, num_trbs, running_total);
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
start_cycle, start_trb, td); start_cycle, start_trb);
return 0; return 0;
} }
...@@ -2818,13 +2821,17 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2818,13 +2821,17 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Queue setup TRB - see section 6.4.1.2.1 */ /* Queue setup TRB - see section 6.4.1.2.1 */
/* FIXME better way to translate setup_packet into two u32 fields? */ /* FIXME better way to translate setup_packet into two u32 fields? */
setup = (struct usb_ctrlrequest *) urb->setup_packet; setup = (struct usb_ctrlrequest *) urb->setup_packet;
field = 0;
field |= TRB_IDT | TRB_TYPE(TRB_SETUP);
if (start_cycle == 0)
field |= 0x1;
queue_trb(xhci, ep_ring, false, true, queue_trb(xhci, ep_ring, false, true,
/* FIXME endianness is probably going to bite my ass here. */ /* FIXME endianness is probably going to bite my ass here. */
setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16, setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16,
setup->wIndex | setup->wLength << 16, setup->wIndex | setup->wLength << 16,
TRB_LEN(8) | TRB_INTR_TARGET(0), TRB_LEN(8) | TRB_INTR_TARGET(0),
/* Immediate data in pointer */ /* Immediate data in pointer */
TRB_IDT | TRB_TYPE(TRB_SETUP)); field);
/* If there's data, queue data TRBs */ /* If there's data, queue data TRBs */
field = 0; field = 0;
...@@ -2859,7 +2866,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2859,7 +2866,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state); field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state);
giveback_first_trb(xhci, slot_id, ep_index, 0, giveback_first_trb(xhci, slot_id, ep_index, 0,
start_cycle, start_trb, td); start_cycle, start_trb);
return 0; return 0;
} }
...@@ -2900,6 +2907,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2900,6 +2907,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
int running_total, trb_buff_len, td_len, td_remain_len, ret; int running_total, trb_buff_len, td_len, td_remain_len, ret;
u64 start_addr, addr; u64 start_addr, addr;
int i, j; int i, j;
bool more_trbs_coming;
ep_ring = xhci->devs[slot_id]->eps[ep_index].ring; ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
...@@ -2910,7 +2918,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2910,7 +2918,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
} }
if (!in_interrupt()) if (!in_interrupt())
dev_dbg(&urb->dev->dev, "ep %#x - urb len = %#x (%d)," xhci_dbg(xhci, "ep %#x - urb len = %#x (%d),"
" addr = %#llx, num_tds = %d\n", " addr = %#llx, num_tds = %d\n",
urb->ep->desc.bEndpointAddress, urb->ep->desc.bEndpointAddress,
urb->transfer_buffer_length, urb->transfer_buffer_length,
...@@ -2950,7 +2958,10 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2950,7 +2958,10 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
field |= TRB_TYPE(TRB_ISOC); field |= TRB_TYPE(TRB_ISOC);
/* Assume URB_ISO_ASAP is set */ /* Assume URB_ISO_ASAP is set */
field |= TRB_SIA; field |= TRB_SIA;
if (i > 0) if (i == 0) {
if (start_cycle == 0)
field |= 0x1;
} else
field |= ep_ring->cycle_state; field |= ep_ring->cycle_state;
first_trb = false; first_trb = false;
} else { } else {
...@@ -2965,9 +2976,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2965,9 +2976,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
*/ */
if (j < trbs_per_td - 1) { if (j < trbs_per_td - 1) {
field |= TRB_CHAIN; field |= TRB_CHAIN;
more_trbs_coming = true;
} else { } else {
td->last_trb = ep_ring->enqueue; td->last_trb = ep_ring->enqueue;
field |= TRB_IOC; field |= TRB_IOC;
more_trbs_coming = false;
} }
/* Calculate TRB length */ /* Calculate TRB length */
...@@ -2980,7 +2993,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -2980,7 +2993,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
length_field = TRB_LEN(trb_buff_len) | length_field = TRB_LEN(trb_buff_len) |
remainder | remainder |
TRB_INTR_TARGET(0); TRB_INTR_TARGET(0);
queue_trb(xhci, ep_ring, false, false, queue_trb(xhci, ep_ring, false, more_trbs_coming,
lower_32_bits(addr), lower_32_bits(addr),
upper_32_bits(addr), upper_32_bits(addr),
length_field, length_field,
...@@ -3003,10 +3016,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3003,10 +3016,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
} }
} }
wmb(); giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
start_trb->field[3] |= start_cycle; start_cycle, start_trb);
xhci_ring_ep_doorbell(xhci, slot_id, ep_index, urb->stream_id);
return 0; return 0;
} }
...@@ -3064,7 +3075,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3064,7 +3075,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
* to set the polling interval (once the API is added). * to set the polling interval (once the API is added).
*/ */
if (xhci_interval != ep_interval) { if (xhci_interval != ep_interval) {
if (!printk_ratelimit()) if (printk_ratelimit())
dev_dbg(&urb->dev->dev, "Driver uses different interval" dev_dbg(&urb->dev->dev, "Driver uses different interval"
" (%d microframe%s) than xHCI " " (%d microframe%s) than xHCI "
"(%d microframe%s)\n", "(%d microframe%s)\n",
......
...@@ -226,7 +226,8 @@ static int xhci_setup_msi(struct xhci_hcd *xhci) ...@@ -226,7 +226,8 @@ static int xhci_setup_msi(struct xhci_hcd *xhci)
static int xhci_setup_msix(struct xhci_hcd *xhci) static int xhci_setup_msix(struct xhci_hcd *xhci)
{ {
int i, ret = 0; int i, ret = 0;
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); struct usb_hcd *hcd = xhci_to_hcd(xhci);
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
/* /*
* calculate number of msi-x vectors supported. * calculate number of msi-x vectors supported.
...@@ -265,6 +266,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) ...@@ -265,6 +266,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
goto disable_msix; goto disable_msix;
} }
hcd->msix_enabled = 1;
return ret; return ret;
disable_msix: disable_msix:
...@@ -280,7 +282,8 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) ...@@ -280,7 +282,8 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
/* Free any IRQs and disable MSI-X */ /* Free any IRQs and disable MSI-X */
static void xhci_cleanup_msix(struct xhci_hcd *xhci) static void xhci_cleanup_msix(struct xhci_hcd *xhci)
{ {
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); struct usb_hcd *hcd = xhci_to_hcd(xhci);
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
xhci_free_irq(xhci); xhci_free_irq(xhci);
...@@ -292,6 +295,7 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci) ...@@ -292,6 +295,7 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)
pci_disable_msi(pdev); pci_disable_msi(pdev);
} }
hcd->msix_enabled = 0;
return; return;
} }
...@@ -508,9 +512,10 @@ void xhci_stop(struct usb_hcd *hcd) ...@@ -508,9 +512,10 @@ void xhci_stop(struct usb_hcd *hcd)
spin_lock_irq(&xhci->lock); spin_lock_irq(&xhci->lock);
xhci_halt(xhci); xhci_halt(xhci);
xhci_reset(xhci); xhci_reset(xhci);
xhci_cleanup_msix(xhci);
spin_unlock_irq(&xhci->lock); spin_unlock_irq(&xhci->lock);
xhci_cleanup_msix(xhci);
#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
/* Tell the event ring poll function not to reschedule */ /* Tell the event ring poll function not to reschedule */
xhci->zombie = 1; xhci->zombie = 1;
...@@ -544,9 +549,10 @@ void xhci_shutdown(struct usb_hcd *hcd) ...@@ -544,9 +549,10 @@ void xhci_shutdown(struct usb_hcd *hcd)
spin_lock_irq(&xhci->lock); spin_lock_irq(&xhci->lock);
xhci_halt(xhci); xhci_halt(xhci);
xhci_cleanup_msix(xhci);
spin_unlock_irq(&xhci->lock); spin_unlock_irq(&xhci->lock);
xhci_cleanup_msix(xhci);
xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
xhci_readl(xhci, &xhci->op_regs->status)); xhci_readl(xhci, &xhci->op_regs->status));
} }
...@@ -647,6 +653,7 @@ int xhci_suspend(struct xhci_hcd *xhci) ...@@ -647,6 +653,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
int rc = 0; int rc = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *hcd = xhci_to_hcd(xhci);
u32 command; u32 command;
int i;
spin_lock_irq(&xhci->lock); spin_lock_irq(&xhci->lock);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
...@@ -677,10 +684,15 @@ int xhci_suspend(struct xhci_hcd *xhci) ...@@ -677,10 +684,15 @@ int xhci_suspend(struct xhci_hcd *xhci)
spin_unlock_irq(&xhci->lock); spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
/* step 5: remove core well power */
xhci_cleanup_msix(xhci);
spin_unlock_irq(&xhci->lock); spin_unlock_irq(&xhci->lock);
/* step 5: remove core well power */
/* synchronize irq when using MSI-X */
if (xhci->msix_entries) {
for (i = 0; i < xhci->msix_count; i++)
synchronize_irq(xhci->msix_entries[i].vector);
}
return rc; return rc;
} }
...@@ -694,7 +706,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) ...@@ -694,7 +706,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
{ {
u32 command, temp = 0; u32 command, temp = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *hcd = xhci_to_hcd(xhci);
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
int old_state, retval; int old_state, retval;
old_state = hcd->state; old_state = hcd->state;
...@@ -729,9 +740,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) ...@@ -729,9 +740,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
xhci_dbg(xhci, "Stop HCD\n"); xhci_dbg(xhci, "Stop HCD\n");
xhci_halt(xhci); xhci_halt(xhci);
xhci_reset(xhci); xhci_reset(xhci);
if (hibernated)
xhci_cleanup_msix(xhci);
spin_unlock_irq(&xhci->lock); spin_unlock_irq(&xhci->lock);
xhci_cleanup_msix(xhci);
#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
/* Tell the event ring poll function not to reschedule */ /* Tell the event ring poll function not to reschedule */
...@@ -765,30 +775,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) ...@@ -765,30 +775,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
return retval; return retval;
} }
spin_unlock_irq(&xhci->lock);
/* Re-setup MSI-X */
if (hcd->irq)
free_irq(hcd->irq, hcd);
hcd->irq = -1;
retval = xhci_setup_msix(xhci);
if (retval)
/* fall back to msi*/
retval = xhci_setup_msi(xhci);
if (retval) {
/* fall back to legacy interrupt*/
retval = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
hcd->irq_descr, hcd);
if (retval) {
xhci_err(xhci, "request interrupt %d failed\n",
pdev->irq);
return retval;
}
hcd->irq = pdev->irq;
}
spin_lock_irq(&xhci->lock);
/* step 4: set Run/Stop bit */ /* step 4: set Run/Stop bit */
command = xhci_readl(xhci, &xhci->op_regs->command); command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_RUN; command |= CMD_RUN;
...@@ -2445,8 +2431,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) ...@@ -2445,8 +2431,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
xhci_err(xhci, "Error while assigning device slot ID\n"); xhci_err(xhci, "Error while assigning device slot ID\n");
return 0; return 0;
} }
/* xhci_alloc_virt_device() does not touch rings; no need to lock */ /* xhci_alloc_virt_device() does not touch rings; no need to lock.
if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { * Use GFP_NOIO, since this function can be called from
* xhci_discover_or_reset_device(), which may be called as part of
* mass storage driver error handling.
*/
if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) {
/* Disable slot, if we can do it without mem alloc */ /* Disable slot, if we can do it without mem alloc */
xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
......
...@@ -436,22 +436,18 @@ struct xhci_run_regs { ...@@ -436,22 +436,18 @@ struct xhci_run_regs {
/** /**
* struct doorbell_array * struct doorbell_array
* *
* Bits 0 - 7: Endpoint target
* Bits 8 - 15: RsvdZ
* Bits 16 - 31: Stream ID
*
* Section 5.6 * Section 5.6
*/ */
struct xhci_doorbell_array { struct xhci_doorbell_array {
u32 doorbell[256]; u32 doorbell[256];
}; };
#define DB_TARGET_MASK 0xFFFFFF00 #define DB_VALUE(ep, stream) ((((ep) + 1) & 0xff) | ((stream) << 16))
#define DB_STREAM_ID_MASK 0x0000FFFF #define DB_VALUE_HOST 0x00000000
#define DB_TARGET_HOST 0x0
#define DB_STREAM_ID_HOST 0x0
#define DB_MASK (0xff << 8)
/* Endpoint Target - bits 0:7 */
#define EPI_TO_DB(p) (((p) + 1) & 0xff)
#define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16)
/** /**
* struct xhci_protocol_caps * struct xhci_protocol_caps
......
...@@ -45,7 +45,7 @@ struct usb_led { ...@@ -45,7 +45,7 @@ struct usb_led {
static void change_color(struct usb_led *led) static void change_color(struct usb_led *led)
{ {
int retval; int retval = 0;
unsigned char *buffer; unsigned char *buffer;
buffer = kmalloc(8, GFP_KERNEL); buffer = kmalloc(8, GFP_KERNEL);
......
...@@ -776,7 +776,6 @@ static const struct usb_device_id uss720_table[] = { ...@@ -776,7 +776,6 @@ static const struct usb_device_id uss720_table[] = {
{ USB_DEVICE(0x0557, 0x2001) }, { USB_DEVICE(0x0557, 0x2001) },
{ USB_DEVICE(0x0729, 0x1284) }, { USB_DEVICE(0x0729, 0x1284) },
{ USB_DEVICE(0x1293, 0x0002) }, { USB_DEVICE(0x1293, 0x0002) },
{ USB_DEVICE(0x1293, 0x0002) },
{ USB_DEVICE(0x050d, 0x0002) }, { USB_DEVICE(0x050d, 0x0002) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -132,6 +132,8 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) ...@@ -132,6 +132,8 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, nop); platform_set_drvdata(pdev, nop);
BLOCKING_INIT_NOTIFIER_HEAD(&nop->otg.notifier);
return 0; return 0;
exit: exit:
kfree(nop); kfree(nop);
......
...@@ -45,7 +45,7 @@ struct ulpi_info { ...@@ -45,7 +45,7 @@ struct ulpi_info {
/* ULPI hardcoded IDs, used for probing */ /* ULPI hardcoded IDs, used for probing */
static struct ulpi_info ulpi_ids[] = { static struct ulpi_info ulpi_ids[] = {
ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"),
ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB3319"), ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"),
}; };
static int ulpi_set_otg_flags(struct otg_transceiver *otg) static int ulpi_set_otg_flags(struct otg_transceiver *otg)
......
...@@ -486,12 +486,22 @@ static void ch341_read_int_callback(struct urb *urb) ...@@ -486,12 +486,22 @@ static void ch341_read_int_callback(struct urb *urb)
if (actual_length >= 4) { if (actual_length >= 4) {
struct ch341_private *priv = usb_get_serial_port_data(port); struct ch341_private *priv = usb_get_serial_port_data(port);
unsigned long flags; unsigned long flags;
u8 prev_line_status = priv->line_status;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT; priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT;
if ((data[1] & CH341_MULT_STAT)) if ((data[1] & CH341_MULT_STAT))
priv->multi_status_change = 1; priv->multi_status_change = 1;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
if ((priv->line_status ^ prev_line_status) & CH341_BIT_DCD) {
struct tty_struct *tty = tty_port_tty_get(&port->port);
if (tty)
usb_serial_handle_dcd_change(port, tty,
priv->line_status & CH341_BIT_DCD);
tty_kref_put(tty);
}
wake_up_interruptible(&priv->delta_msr_wait); wake_up_interruptible(&priv->delta_msr_wait);
} }
......
...@@ -49,7 +49,6 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *, ...@@ -49,7 +49,6 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *,
static void cp210x_break_ctl(struct tty_struct *, int); static void cp210x_break_ctl(struct tty_struct *, int);
static int cp210x_startup(struct usb_serial *); static int cp210x_startup(struct usb_serial *);
static void cp210x_dtr_rts(struct usb_serial_port *p, int on); static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
static int cp210x_carrier_raised(struct usb_serial_port *p);
static int debug; static int debug;
...@@ -87,7 +86,6 @@ static const struct usb_device_id id_table[] = { ...@@ -87,7 +86,6 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
{ USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
{ USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
{ USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
{ USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
...@@ -110,7 +108,9 @@ static const struct usb_device_id id_table[] = { ...@@ -110,7 +108,9 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
{ USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
{ USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
{ USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */
{ USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
{ USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
{ USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
...@@ -165,8 +165,7 @@ static struct usb_serial_driver cp210x_device = { ...@@ -165,8 +165,7 @@ static struct usb_serial_driver cp210x_device = {
.tiocmget = cp210x_tiocmget, .tiocmget = cp210x_tiocmget,
.tiocmset = cp210x_tiocmset, .tiocmset = cp210x_tiocmset,
.attach = cp210x_startup, .attach = cp210x_startup,
.dtr_rts = cp210x_dtr_rts, .dtr_rts = cp210x_dtr_rts
.carrier_raised = cp210x_carrier_raised
}; };
/* Config request types */ /* Config request types */
...@@ -765,15 +764,6 @@ static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) ...@@ -765,15 +764,6 @@ static int cp210x_tiocmget (struct tty_struct *tty, struct file *file)
return result; return result;
} }
static int cp210x_carrier_raised(struct usb_serial_port *p)
{
unsigned int control;
cp210x_get_config(p, CP210X_GET_MDMSTS, &control, 1);
if (control & CONTROL_DCD)
return 1;
return 0;
}
static void cp210x_break_ctl (struct tty_struct *tty, int break_state) static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
{ {
struct usb_serial_port *port = tty->driver_data; struct usb_serial_port *port = tty->driver_data;
......
...@@ -455,7 +455,6 @@ static int digi_write_room(struct tty_struct *tty); ...@@ -455,7 +455,6 @@ static int digi_write_room(struct tty_struct *tty);
static int digi_chars_in_buffer(struct tty_struct *tty); static int digi_chars_in_buffer(struct tty_struct *tty);
static int digi_open(struct tty_struct *tty, struct usb_serial_port *port); static int digi_open(struct tty_struct *tty, struct usb_serial_port *port);
static void digi_close(struct usb_serial_port *port); static void digi_close(struct usb_serial_port *port);
static int digi_carrier_raised(struct usb_serial_port *port);
static void digi_dtr_rts(struct usb_serial_port *port, int on); static void digi_dtr_rts(struct usb_serial_port *port, int on);
static int digi_startup_device(struct usb_serial *serial); static int digi_startup_device(struct usb_serial *serial);
static int digi_startup(struct usb_serial *serial); static int digi_startup(struct usb_serial *serial);
...@@ -511,7 +510,6 @@ static struct usb_serial_driver digi_acceleport_2_device = { ...@@ -511,7 +510,6 @@ static struct usb_serial_driver digi_acceleport_2_device = {
.open = digi_open, .open = digi_open,
.close = digi_close, .close = digi_close,
.dtr_rts = digi_dtr_rts, .dtr_rts = digi_dtr_rts,
.carrier_raised = digi_carrier_raised,
.write = digi_write, .write = digi_write,
.write_room = digi_write_room, .write_room = digi_write_room,
.write_bulk_callback = digi_write_bulk_callback, .write_bulk_callback = digi_write_bulk_callback,
...@@ -1339,14 +1337,6 @@ static void digi_dtr_rts(struct usb_serial_port *port, int on) ...@@ -1339,14 +1337,6 @@ static void digi_dtr_rts(struct usb_serial_port *port, int on)
digi_set_modem_signals(port, on * (TIOCM_DTR|TIOCM_RTS), 1); digi_set_modem_signals(port, on * (TIOCM_DTR|TIOCM_RTS), 1);
} }
static int digi_carrier_raised(struct usb_serial_port *port)
{
struct digi_port *priv = usb_get_serial_port_data(port);
if (priv->dp_modem_signals & TIOCM_CD)
return 1;
return 0;
}
static int digi_open(struct tty_struct *tty, struct usb_serial_port *port) static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
int ret; int ret;
......
...@@ -676,7 +676,17 @@ static struct usb_device_id id_table_combined [] = { ...@@ -676,7 +676,17 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) },
{ USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2C2_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2D_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2VT_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2VR_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVT_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVR_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVT_PID) },
{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVR_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) }, { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
......
...@@ -569,11 +569,23 @@ ...@@ -569,11 +569,23 @@
#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ #define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */
/* /*
* Icom ID-1 digital transceiver * Definitions for Icom Inc. devices
*/ */
#define ICOM_VID 0x0C26 /* Icom vendor ID */
#define ICOM_ID1_VID 0x0C26 /* Note: ID-1 is a communications tranceiver for HAM-radio operators */
#define ICOM_ID1_PID 0x0004 #define ICOM_ID_1_PID 0x0004 /* ID-1 USB to RS-232 */
/* Note: OPC is an Optional cable to connect an Icom Tranceiver */
#define ICOM_OPC_U_UC_PID 0x0018 /* OPC-478UC, OPC-1122U cloning cable */
/* Note: ID-RP* devices are Icom Repeater Devices for HAM-radio */
#define ICOM_ID_RP2C1_PID 0x0009 /* ID-RP2C Asset 1 to RS-232 */
#define ICOM_ID_RP2C2_PID 0x000A /* ID-RP2C Asset 2 to RS-232 */
#define ICOM_ID_RP2D_PID 0x000B /* ID-RP2D configuration port*/
#define ICOM_ID_RP2VT_PID 0x000C /* ID-RP2V Transmit config port */
#define ICOM_ID_RP2VR_PID 0x000D /* ID-RP2V Receive config port */
#define ICOM_ID_RP4KVT_PID 0x0010 /* ID-RP4000V Transmit config port */
#define ICOM_ID_RP4KVR_PID 0x0011 /* ID-RP4000V Receive config port */
#define ICOM_ID_RP2KVT_PID 0x0012 /* ID-RP2000V Transmit config port */
#define ICOM_ID_RP2KVR_PID 0x0013 /* ID-RP2000V Receive config port */
/* /*
* GN Otometrics (http://www.otometrics.com) * GN Otometrics (http://www.otometrics.com)
......
...@@ -479,6 +479,26 @@ int usb_serial_handle_break(struct usb_serial_port *port) ...@@ -479,6 +479,26 @@ int usb_serial_handle_break(struct usb_serial_port *port)
} }
EXPORT_SYMBOL_GPL(usb_serial_handle_break); EXPORT_SYMBOL_GPL(usb_serial_handle_break);
/**
* usb_serial_handle_dcd_change - handle a change of carrier detect state
* @port: usb_serial_port structure for the open port
* @tty: tty_struct structure for the port
* @status: new carrier detect status, nonzero if active
*/
void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
struct tty_struct *tty, unsigned int status)
{
struct tty_port *port = &usb_port->port;
dbg("%s - port %d, status %d", __func__, usb_port->number, status);
if (status)
wake_up_interruptible(&port->open_wait);
else if (tty && !C_CLOCAL(tty))
tty_hangup(tty);
}
EXPORT_SYMBOL_GPL(usb_serial_handle_dcd_change);
int usb_serial_generic_resume(struct usb_serial *serial) int usb_serial_generic_resume(struct usb_serial *serial)
{ {
struct usb_serial_port *port; struct usb_serial_port *port;
......
...@@ -199,6 +199,7 @@ static struct usb_serial_driver epic_device = { ...@@ -199,6 +199,7 @@ static struct usb_serial_driver epic_device = {
.name = "epic", .name = "epic",
}, },
.description = "EPiC device", .description = "EPiC device",
.usb_driver = &io_driver,
.id_table = Epic_port_id_table, .id_table = Epic_port_id_table,
.num_ports = 1, .num_ports = 1,
.open = edge_open, .open = edge_open,
......
...@@ -1275,6 +1275,7 @@ static struct usb_serial_driver iuu_device = { ...@@ -1275,6 +1275,7 @@ static struct usb_serial_driver iuu_device = {
.name = "iuu_phoenix", .name = "iuu_phoenix",
}, },
.id_table = id_table, .id_table = id_table,
.usb_driver = &iuu_driver,
.num_ports = 1, .num_ports = 1,
.bulk_in_size = 512, .bulk_in_size = 512,
.bulk_out_size = 512, .bulk_out_size = 512,
......
...@@ -546,6 +546,7 @@ static struct usb_serial_driver keyspan_pre_device = { ...@@ -546,6 +546,7 @@ static struct usb_serial_driver keyspan_pre_device = {
.name = "keyspan_no_firm", .name = "keyspan_no_firm",
}, },
.description = "Keyspan - (without firmware)", .description = "Keyspan - (without firmware)",
.usb_driver = &keyspan_driver,
.id_table = keyspan_pre_ids, .id_table = keyspan_pre_ids,
.num_ports = 1, .num_ports = 1,
.attach = keyspan_fake_startup, .attach = keyspan_fake_startup,
...@@ -557,6 +558,7 @@ static struct usb_serial_driver keyspan_1port_device = { ...@@ -557,6 +558,7 @@ static struct usb_serial_driver keyspan_1port_device = {
.name = "keyspan_1", .name = "keyspan_1",
}, },
.description = "Keyspan 1 port adapter", .description = "Keyspan 1 port adapter",
.usb_driver = &keyspan_driver,
.id_table = keyspan_1port_ids, .id_table = keyspan_1port_ids,
.num_ports = 1, .num_ports = 1,
.open = keyspan_open, .open = keyspan_open,
...@@ -579,6 +581,7 @@ static struct usb_serial_driver keyspan_2port_device = { ...@@ -579,6 +581,7 @@ static struct usb_serial_driver keyspan_2port_device = {
.name = "keyspan_2", .name = "keyspan_2",
}, },
.description = "Keyspan 2 port adapter", .description = "Keyspan 2 port adapter",
.usb_driver = &keyspan_driver,
.id_table = keyspan_2port_ids, .id_table = keyspan_2port_ids,
.num_ports = 2, .num_ports = 2,
.open = keyspan_open, .open = keyspan_open,
...@@ -601,6 +604,7 @@ static struct usb_serial_driver keyspan_4port_device = { ...@@ -601,6 +604,7 @@ static struct usb_serial_driver keyspan_4port_device = {
.name = "keyspan_4", .name = "keyspan_4",
}, },
.description = "Keyspan 4 port adapter", .description = "Keyspan 4 port adapter",
.usb_driver = &keyspan_driver,
.id_table = keyspan_4port_ids, .id_table = keyspan_4port_ids,
.num_ports = 4, .num_ports = 4,
.open = keyspan_open, .open = keyspan_open,
......
...@@ -679,22 +679,6 @@ static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on) ...@@ -679,22 +679,6 @@ static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on)
} }
} }
static int keyspan_pda_carrier_raised(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
unsigned char modembits;
/* If we can read the modem status and the DCD is low then
carrier is not raised yet */
if (keyspan_pda_get_modem_info(serial, &modembits) >= 0) {
if (!(modembits & (1>>6)))
return 0;
}
/* Carrier raised, or we failed (eg disconnected) so
progress accordingly */
return 1;
}
static int keyspan_pda_open(struct tty_struct *tty, static int keyspan_pda_open(struct tty_struct *tty,
struct usb_serial_port *port) struct usb_serial_port *port)
...@@ -881,7 +865,6 @@ static struct usb_serial_driver keyspan_pda_device = { ...@@ -881,7 +865,6 @@ static struct usb_serial_driver keyspan_pda_device = {
.id_table = id_table_std, .id_table = id_table_std,
.num_ports = 1, .num_ports = 1,
.dtr_rts = keyspan_pda_dtr_rts, .dtr_rts = keyspan_pda_dtr_rts,
.carrier_raised = keyspan_pda_carrier_raised,
.open = keyspan_pda_open, .open = keyspan_pda_open,
.close = keyspan_pda_close, .close = keyspan_pda_close,
.write = keyspan_pda_write, .write = keyspan_pda_write,
......
...@@ -44,6 +44,7 @@ static struct usb_serial_driver moto_device = { ...@@ -44,6 +44,7 @@ static struct usb_serial_driver moto_device = {
.name = "moto-modem", .name = "moto-modem",
}, },
.id_table = id_table, .id_table = id_table,
.usb_driver = &moto_driver,
.num_ports = 1, .num_ports = 1,
}; };
......
...@@ -382,7 +382,16 @@ static void option_instat_callback(struct urb *urb); ...@@ -382,7 +382,16 @@ static void option_instat_callback(struct urb *urb);
#define HAIER_VENDOR_ID 0x201e #define HAIER_VENDOR_ID 0x201e
#define HAIER_PRODUCT_CE100 0x2009 #define HAIER_PRODUCT_CE100 0x2009
#define CINTERION_VENDOR_ID 0x0681 /* Cinterion (formerly Siemens) products */
#define SIEMENS_VENDOR_ID 0x0681
#define CINTERION_VENDOR_ID 0x1e2d
#define CINTERION_PRODUCT_HC25_MDM 0x0047
#define CINTERION_PRODUCT_HC25_MDMNET 0x0040
#define CINTERION_PRODUCT_HC28_MDM 0x004C
#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */
#define CINTERION_PRODUCT_EU3_E 0x0051
#define CINTERION_PRODUCT_EU3_P 0x0052
#define CINTERION_PRODUCT_PH8 0x0053
/* Olivetti products */ /* Olivetti products */
#define OLIVETTI_VENDOR_ID 0x0b3c #define OLIVETTI_VENDOR_ID 0x0b3c
...@@ -944,7 +953,17 @@ static const struct usb_device_id option_ids[] = { ...@@ -944,7 +953,17 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
{ USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, /* Cinterion */
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
{ USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
......
...@@ -157,6 +157,7 @@ static struct usb_serial_driver oti6858_device = { ...@@ -157,6 +157,7 @@ static struct usb_serial_driver oti6858_device = {
.name = "oti6858", .name = "oti6858",
}, },
.id_table = id_table, .id_table = id_table,
.usb_driver = &oti6858_driver,
.num_ports = 1, .num_ports = 1,
.open = oti6858_open, .open = oti6858_open,
.close = oti6858_close, .close = oti6858_close,
......
...@@ -50,6 +50,7 @@ static const struct usb_device_id id_table[] = { ...@@ -50,6 +50,7 @@ static const struct usb_device_id id_table[] = {
{ 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(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },
{ 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) },
...@@ -677,9 +678,11 @@ static void pl2303_update_line_status(struct usb_serial_port *port, ...@@ -677,9 +678,11 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
{ {
struct pl2303_private *priv = usb_get_serial_port_data(port); struct pl2303_private *priv = usb_get_serial_port_data(port);
struct tty_struct *tty;
unsigned long flags; unsigned long flags;
u8 status_idx = UART_STATE; u8 status_idx = UART_STATE;
u8 length = UART_STATE + 1; u8 length = UART_STATE + 1;
u8 prev_line_status;
u16 idv, idp; u16 idv, idp;
idv = le16_to_cpu(port->serial->dev->descriptor.idVendor); idv = le16_to_cpu(port->serial->dev->descriptor.idVendor);
...@@ -701,11 +704,20 @@ static void pl2303_update_line_status(struct usb_serial_port *port, ...@@ -701,11 +704,20 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
/* Save off the uart status for others to look at */ /* Save off the uart status for others to look at */
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
prev_line_status = priv->line_status;
priv->line_status = data[status_idx]; priv->line_status = data[status_idx];
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
if (priv->line_status & UART_BREAK_ERROR) if (priv->line_status & UART_BREAK_ERROR)
usb_serial_handle_break(port); usb_serial_handle_break(port);
wake_up_interruptible(&priv->delta_msr_wait); wake_up_interruptible(&priv->delta_msr_wait);
tty = tty_port_tty_get(&port->port);
if (!tty)
return;
if ((priv->line_status ^ prev_line_status) & UART_DCD)
usb_serial_handle_dcd_change(port, tty,
priv->line_status & UART_DCD);
tty_kref_put(tty);
} }
static void pl2303_read_int_callback(struct urb *urb) static void pl2303_read_int_callback(struct urb *urb)
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define PL2303_PRODUCT_ID_MMX 0x0612 #define PL2303_PRODUCT_ID_MMX 0x0612
#define PL2303_PRODUCT_ID_GPRS 0x0609 #define PL2303_PRODUCT_ID_GPRS 0x0609
#define PL2303_PRODUCT_ID_HCR331 0x331a #define PL2303_PRODUCT_ID_HCR331 0x331a
#define PL2303_PRODUCT_ID_MOTOROLA 0x0307
#define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID 0x0557
#define ATEN_VENDOR_ID2 0x0547 #define ATEN_VENDOR_ID2 0x0547
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define UTSTARCOM_PRODUCT_UM175_V1 0x3712 #define UTSTARCOM_PRODUCT_UM175_V1 0x3712
#define UTSTARCOM_PRODUCT_UM175_V2 0x3714 #define UTSTARCOM_PRODUCT_UM175_V2 0x3714
#define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 #define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715
#define PANTECH_PRODUCT_UML290_VZW 0x3718
/* CMOTECH devices */ /* CMOTECH devices */
#define CMOTECH_VENDOR_ID 0x16d8 #define CMOTECH_VENDOR_ID 0x16d8
...@@ -66,6 +67,7 @@ static struct usb_device_id id_table[] = { ...@@ -66,6 +67,7 @@ static struct usb_device_id id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) },
{ }, { },
}; };
MODULE_DEVICE_TABLE(usb, id_table); MODULE_DEVICE_TABLE(usb, id_table);
...@@ -84,6 +86,7 @@ static struct usb_serial_driver qcaux_device = { ...@@ -84,6 +86,7 @@ static struct usb_serial_driver qcaux_device = {
.name = "qcaux", .name = "qcaux",
}, },
.id_table = id_table, .id_table = id_table,
.usb_driver = &qcaux_driver,
.num_ports = 1, .num_ports = 1,
}; };
......
...@@ -42,6 +42,7 @@ static struct usb_serial_driver siemens_usb_mpi_device = { ...@@ -42,6 +42,7 @@ static struct usb_serial_driver siemens_usb_mpi_device = {
.name = "siemens_mpi", .name = "siemens_mpi",
}, },
.id_table = id_table, .id_table = id_table,
.usb_driver = &siemens_usb_mpi_driver,
.num_ports = 1, .num_ports = 1,
}; };
......
...@@ -133,7 +133,7 @@ struct spcp8x5_usb_ctrl_arg { ...@@ -133,7 +133,7 @@ struct spcp8x5_usb_ctrl_arg {
/* how come ??? */ /* how come ??? */
#define UART_STATE 0x08 #define UART_STATE 0x08
#define UART_STATE_TRANSIENT_MASK 0x74 #define UART_STATE_TRANSIENT_MASK 0x75
#define UART_DCD 0x01 #define UART_DCD 0x01
#define UART_DSR 0x02 #define UART_DSR 0x02
#define UART_BREAK_ERROR 0x04 #define UART_BREAK_ERROR 0x04
...@@ -525,6 +525,10 @@ static void spcp8x5_process_read_urb(struct urb *urb) ...@@ -525,6 +525,10 @@ static void spcp8x5_process_read_urb(struct urb *urb)
/* overrun is special, not associated with a char */ /* overrun is special, not associated with a char */
if (status & UART_OVERRUN_ERROR) if (status & UART_OVERRUN_ERROR)
tty_insert_flip_char(tty, 0, TTY_OVERRUN); tty_insert_flip_char(tty, 0, TTY_OVERRUN);
if (status & UART_DCD)
usb_serial_handle_dcd_change(port, tty,
priv->line_status & MSR_STATUS_LINE_DCD);
} }
tty_insert_flip_string_fixed_flag(tty, data, tty_flag, tty_insert_flip_string_fixed_flag(tty, data, tty_flag,
...@@ -645,6 +649,7 @@ static struct usb_serial_driver spcp8x5_device = { ...@@ -645,6 +649,7 @@ static struct usb_serial_driver spcp8x5_device = {
.name = "SPCP8x5", .name = "SPCP8x5",
}, },
.id_table = id_table, .id_table = id_table,
.usb_driver = &spcp8x5_driver,
.num_ports = 1, .num_ports = 1,
.open = spcp8x5_open, .open = spcp8x5_open,
.dtr_rts = spcp8x5_dtr_rts, .dtr_rts = spcp8x5_dtr_rts,
......
...@@ -1344,11 +1344,15 @@ int usb_serial_register(struct usb_serial_driver *driver) ...@@ -1344,11 +1344,15 @@ int usb_serial_register(struct usb_serial_driver *driver)
return -ENODEV; return -ENODEV;
fixup_generic(driver); fixup_generic(driver);
if (driver->usb_driver)
driver->usb_driver->supports_autosuspend = 1;
if (!driver->description) if (!driver->description)
driver->description = driver->driver.name; driver->description = driver->driver.name;
if (!driver->usb_driver) {
WARN(1, "Serial driver %s has no usb_driver\n",
driver->description);
return -EINVAL;
}
driver->usb_driver->supports_autosuspend = 1;
/* Add this device to our list of devices */ /* Add this device to our list of devices */
mutex_lock(&table_lock); mutex_lock(&table_lock);
......
...@@ -75,6 +75,7 @@ static struct usb_serial_driver debug_device = { ...@@ -75,6 +75,7 @@ static struct usb_serial_driver debug_device = {
.name = "debug", .name = "debug",
}, },
.id_table = id_table, .id_table = id_table,
.usb_driver = &debug_driver,
.num_ports = 1, .num_ports = 1,
.bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE,
.break_ctl = usb_debug_break_ctl, .break_ctl = usb_debug_break_ctl,
......
...@@ -31,4 +31,9 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, ...@@ -31,4 +31,9 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999,
"Cypress ISD-300LP", "Cypress ISD-300LP",
USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x9999,
"Super Top",
"USB 2.0 SATA BRIDGE",
USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
#endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */ #endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */
...@@ -1044,6 +1044,15 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, ...@@ -1044,6 +1044,15 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BULK32), US_FL_BULK32),
/* Reported by <ttkspam@free.fr>
* The device reports a vendor-specific device class, requiring an
* explicit vendor/product match.
*/
UNUSUAL_DEV( 0x0851, 0x1542, 0x0002, 0x0002,
"MagicPixel",
"FW_Omega2",
USB_SC_DEVICE, USB_PR_DEVICE, NULL, 0),
/* Andrew Lunn <andrew@lunn.ch> /* Andrew Lunn <andrew@lunn.ch>
* PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL
* on LUN 4. * on LUN 4.
...@@ -1872,6 +1881,15 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200, ...@@ -1872,6 +1881,15 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_READ_DISC_INFO ), US_FL_NO_READ_DISC_INFO ),
/* Patch by Richard Schtz <r.schtz@t-online.de>
* This external hard drive enclosure uses a JMicron chip which
* needs the US_FL_IGNORE_RESIDUE flag to work properly. */
UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000,
"TrekStor GmbH & Co. KG",
"DataStation maxi g.u",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ),
UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
"ST", "ST",
"2A", "2A",
......
...@@ -112,6 +112,7 @@ struct usb_hcd { ...@@ -112,6 +112,7 @@ struct usb_hcd {
/* Flags that get set only during HCD registration or removal. */ /* Flags that get set only during HCD registration or removal. */
unsigned rh_registered:1;/* is root hub registered? */ unsigned rh_registered:1;/* is root hub registered? */
unsigned rh_pollable:1; /* may we poll the root hub? */ unsigned rh_pollable:1; /* may we poll the root hub? */
unsigned msix_enabled:1; /* driver has MSI-X enabled? */
/* The next flag is a stopgap, to be removed when all the HCDs /* The next flag is a stopgap, to be removed when all the HCDs
* support the new root-hub polling mechanism. */ * support the new root-hub polling mechanism. */
......
...@@ -347,6 +347,9 @@ extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, ...@@ -347,6 +347,9 @@ extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port,
unsigned int ch); unsigned int ch);
extern int usb_serial_handle_break(struct usb_serial_port *port); extern int usb_serial_handle_break(struct usb_serial_port *port);
extern void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
struct tty_struct *tty,
unsigned int status);
extern int usb_serial_bus_register(struct usb_serial_driver *device); extern int usb_serial_bus_register(struct usb_serial_driver *device);
......
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