Merge 3.4-rc4 into usb-next.

This resolves the conflict in:
	drivers/usb/host/ehci-fsl.c
And picks up loads of xhci bugfixes to make it easier for others to test
with.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Greg Kroah-Hartman 2012-04-22 15:25:26 -07:00
commit 09091a4d5f
62 changed files with 1740 additions and 1255 deletions

View File

@ -0,0 +1,39 @@
ST SPEAr SoC USB controllers:
-----------------------------
EHCI:
-----
Required properties:
- compatible: "st,spear600-ehci"
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupts: Should contain the EHCI interrupt
Example:
ehci@e1800000 {
compatible = "st,spear600-ehci", "usb-ehci";
reg = <0xe1800000 0x1000>;
interrupt-parent = <&vic1>;
interrupts = <27>;
};
OHCI:
-----
Required properties:
- compatible: "st,spear600-ohci"
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupts: Should contain the OHCI interrupt
Example:
ohci@e1900000 {
compatible = "st,spear600-ohci", "usb-ohci";
reg = <0xe1800000 0x1000>;
interrupt-parent = <&vic1>;
interrupts = <26>;
};

View File

@ -297,6 +297,23 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
return -EILSEQ;
}
/* First Slave Address Descriptor should be port 0:
* the main register space for the core
*/
tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
if (tmp <= 0) {
/* Try again to see if it is a bridge */
tmp = bcma_erom_get_addr_desc(bus, eromptr,
SCAN_ADDR_TYPE_BRIDGE, 0);
if (tmp <= 0) {
return -EILSEQ;
} else {
pr_info("Bridge found\n");
return -ENXIO;
}
}
core->addr = tmp;
/* get & parse slave ports */
for (i = 0; i < ports[1]; i++) {
for (j = 0; ; j++) {
@ -309,7 +326,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
break;
} else {
if (i == 0 && j == 0)
core->addr = tmp;
core->addr1 = tmp;
}
}
}

View File

@ -782,20 +782,20 @@ static int __init asus_oled_init(void)
oled_class = class_create(THIS_MODULE, ASUS_OLED_UNDERSCORE_NAME);
if (IS_ERR(oled_class)) {
err("Error creating " ASUS_OLED_UNDERSCORE_NAME " class");
printk(KERN_ERR "Error creating " ASUS_OLED_UNDERSCORE_NAME " class\n");
return PTR_ERR(oled_class);
}
retval = class_create_file(oled_class, &class_attr_version.attr);
if (retval) {
err("Error creating class version file");
printk(KERN_ERR "Error creating class version file\n");
goto error;
}
retval = usb_register(&oled_driver);
if (retval) {
err("usb_register failed. Error number %d", retval);
printk(KERN_ERR "usb_register failed. Error number %d\n", retval);
goto error;
}

View File

@ -547,7 +547,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
break;
default:
err("Illegal gain %d\n", gain);
dev_err(&dev->interface->dev, "Illegal gain %d\n", gain);
}
}
@ -715,7 +715,7 @@ static int dt9812_probe(struct usb_interface *interface,
iface_desc = interface->cur_altsetting;
if (iface_desc->desc.bNumEndpoints != 5) {
err("Wrong number of endpints.");
dev_err(&interface->dev, "Wrong number of endpoints.\n");
retval = -ENODEV;
goto error;
}
@ -781,22 +781,22 @@ static int dt9812_probe(struct usb_interface *interface,
}
if (dt9812_read_info(dev, 1, &dev->vendor, sizeof(dev->vendor)) != 0) {
err("Failed to read vendor.");
dev_err(&interface->dev, "Failed to read vendor.\n");
retval = -ENODEV;
goto error;
}
if (dt9812_read_info(dev, 3, &dev->product, sizeof(dev->product)) != 0) {
err("Failed to read product.");
dev_err(&interface->dev, "Failed to read product.\n");
retval = -ENODEV;
goto error;
}
if (dt9812_read_info(dev, 5, &dev->device, sizeof(dev->device)) != 0) {
err("Failed to read device.");
dev_err(&interface->dev, "Failed to read device.\n");
retval = -ENODEV;
goto error;
}
if (dt9812_read_info(dev, 7, &dev->serial, sizeof(dev->serial)) != 0) {
err("Failed to read serial.");
dev_err(&interface->dev, "Failed to read serial.\n");
retval = -ENODEV;
goto error;
}
@ -1146,7 +1146,9 @@ static int __init usb_dt9812_init(void)
result = comedi_driver_register(&dt9812_comedi_driver);
if (result) {
usb_deregister(&dt9812_usb_driver);
err("comedi_driver_register failed. Error number %d", result);
printk(KERN_ERR KBUILD_MODNAME
": comedi_driver_register failed. Error number %d\n",
result);
}
return result;

View File

@ -295,7 +295,9 @@ static void vmk80xx_rx_callback(struct urb *urb)
if (!usb_submit_urb(urb, GFP_KERNEL))
goto exit;
err("comedi#: vmk80xx: %s - submit urb failed\n", __func__);
dev_err(&urb->dev->dev,
"comedi#: vmk80xx: %s - submit urb failed\n",
__func__);
usb_unanchor_urb(urb);
}

View File

@ -333,8 +333,8 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&usb_alphatrack_driver, subminor);
if (!interface) {
err("%s - error, can't find device for minor %d\n",
__func__, subminor);
printk(KERN_ERR "%s - error, can't find device for minor %d\n",
__func__, subminor);
retval = -ENODEV;
goto unlock_disconnect_exit;
}
@ -494,7 +494,8 @@ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
printk(KERN_ERR "%s: No device or device unplugged %d\n",
__func__, retval);
goto unlock_exit;
}
@ -564,7 +565,8 @@ static ssize_t usb_alphatrack_write(struct file *file,
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
printk(KERN_ERR "%s: No device or device unplugged %d\n",
__func__, retval);
goto unlock_exit;
}
@ -599,7 +601,7 @@ static ssize_t usb_alphatrack_write(struct file *file,
}
if (dev->interrupt_out_endpoint == NULL) {
err("Endpoint should not be be null!\n");
dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
goto unlock_exit;
}
@ -619,7 +621,8 @@ static ssize_t usb_alphatrack_write(struct file *file,
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
if (retval) {
dev->interrupt_out_busy = 0;
err("Couldn't submit interrupt_out_urb %d\n", retval);
dev_err(&dev->intf->dev,
"Couldn't submit interrupt_out_urb %d\n", retval);
atomic_dec(&dev->writes_pending);
goto unlock_exit;
}

View File

@ -353,7 +353,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&usb_tranzport_driver, subminor);
if (!interface) {
err("%s - error, can't find device for minor %d\n",
printk(KERN_ERR "%s - error, can't find device for minor %d\n",
__func__, subminor);
retval = -ENODEV;
goto unlock_disconnect_exit;
@ -517,9 +517,11 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer,
goto exit;
}
/* verify that the device wasn't unplugged */ if (dev->intf == NULL) {
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
printk(KERN_ERR "%s: No device or device unplugged %d\n",
__func__, retval);
goto unlock_exit;
}
@ -691,7 +693,8 @@ static ssize_t usb_tranzport_write(struct file *file,
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
printk(KERN_ERR "%s: No device or device unplugged %d\n",
__func__, retval);
goto unlock_exit;
}
@ -726,7 +729,7 @@ static ssize_t usb_tranzport_write(struct file *file,
}
if (dev->interrupt_out_endpoint == NULL) {
err("Endpoint should not be be null!\n");
dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
goto unlock_exit;
}
@ -746,7 +749,8 @@ static ssize_t usb_tranzport_write(struct file *file,
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
if (retval) {
dev->interrupt_out_busy = 0;
err("Couldn't submit interrupt_out_urb %d\n", retval);
dev_err(&dev->intf->dev,
"Couldn't submit interrupt_out_urb %d\n", retval);
goto unlock_exit;
}
retval = bytes_to_write;

View File

@ -1307,7 +1307,8 @@ static int __init line6_init(void)
retval = usb_register(&line6_driver);
if (retval) {
err("usb_register failed. Error number %d", retval);
printk(KERN_ERR KBUILD_MODNAME
": usb_register failed. Error number %d\n", retval);
return retval;
}
@ -1315,7 +1316,7 @@ static int __init line6_init(void)
GFP_KERNEL);
if (line6_request_version == NULL) {
err("Out of memory");
printk(KERN_ERR KBUILD_MODNAME ":Out of memory\n");
return -ENOMEM;
}

View File

@ -168,7 +168,7 @@ static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
if (ret < 0) {
err("send failed (error %d)\n", ret);
dev_err(&usbdev->dev, "send failed (error %d)\n", ret);
return ret;
}

View File

@ -1357,10 +1357,8 @@ static int uea_stat_e1(struct uea_softc *sc)
/* release the dsp firmware as it is not needed until
* the next failure
*/
if (sc->dsp_firm) {
release_firmware(sc->dsp_firm);
sc->dsp_firm = NULL;
}
release_firmware(sc->dsp_firm);
sc->dsp_firm = NULL;
}
/* always update it as atm layer could not be init when we switch to
@ -1496,10 +1494,8 @@ static int uea_stat_e4(struct uea_softc *sc)
/* release the dsp firmware as it is not needed until
* the next failure
*/
if (sc->dsp_firm) {
release_firmware(sc->dsp_firm);
sc->dsp_firm = NULL;
}
release_firmware(sc->dsp_firm);
sc->dsp_firm = NULL;
}
/* always update it as atm layer could not be init when we switch to
@ -2240,8 +2236,7 @@ static void uea_stop(struct uea_softc *sc)
/* flush the work item, when no one can schedule it */
flush_work_sync(&sc->task);
if (sc->dsp_firm)
release_firmware(sc->dsp_firm);
release_firmware(sc->dsp_firm);
uea_leaves(INS_TO_USBDEV(sc));
}

View File

@ -374,7 +374,7 @@ static int hidg_setup(struct usb_function *f,
break;
default:
VDBG(cdev, "Unknown decriptor request 0x%x\n",
VDBG(cdev, "Unknown descriptor request 0x%x\n",
value >> 8);
goto stall;
break;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc.
* Copyright (C) 2004-2007,2011-2012 Freescale Semiconductor, Inc.
* All rights reserved.
*
* Author: Li Yang <leoli@freescale.com>
@ -58,9 +58,8 @@ static const char driver_name[] = "fsl-usb2-udc";
static const char driver_desc[] = DRIVER_DESC;
static struct usb_dr_device *dr_regs;
#ifndef CONFIG_ARCH_MXC
static struct usb_sys_interface *usb_sys_regs;
#endif
/* it is initialized in probe() */
static struct fsl_udc *udc_controller = NULL;
@ -244,10 +243,9 @@ static int dr_controller_setup(struct fsl_udc *udc)
{
unsigned int tmp, portctrl, ep_num;
unsigned int max_no_of_ep;
#ifndef CONFIG_ARCH_MXC
unsigned int ctrl;
#endif
unsigned long timeout;
#define FSL_UDC_RESET_TIMEOUT 1000
/* Config PHY interface */
@ -255,12 +253,32 @@ static int dr_controller_setup(struct fsl_udc *udc)
portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
switch (udc->phy_mode) {
case FSL_USB2_PHY_ULPI:
if (udc->pdata->have_sysif_regs) {
if (udc->pdata->controller_ver) {
/* controller version 1.6 or above */
ctrl = __raw_readl(&usb_sys_regs->control);
ctrl &= ~USB_CTRL_UTMI_PHY_EN;
ctrl |= USB_CTRL_USB_EN;
__raw_writel(ctrl, &usb_sys_regs->control);
}
}
portctrl |= PORTSCX_PTS_ULPI;
break;
case FSL_USB2_PHY_UTMI_WIDE:
portctrl |= PORTSCX_PTW_16BIT;
/* fall through */
case FSL_USB2_PHY_UTMI:
if (udc->pdata->have_sysif_regs) {
if (udc->pdata->controller_ver) {
/* controller version 1.6 or above */
ctrl = __raw_readl(&usb_sys_regs->control);
ctrl |= (USB_CTRL_UTMI_PHY_EN |
USB_CTRL_USB_EN);
__raw_writel(ctrl, &usb_sys_regs->control);
mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI
PHY CLK to become stable - 10ms*/
}
}
portctrl |= PORTSCX_PTS_UTMI;
break;
case FSL_USB2_PHY_SERIAL:

View File

@ -1,4 +1,12 @@
/*
* Copyright (C) 2004,2012 Freescale Semiconductor, Inc
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Freescale USB device/endpoint management registers
*/
#ifndef __FSL_USB2_UDC_H
@ -348,6 +356,9 @@ struct usb_sys_interface {
/* control Register Bit Masks */
#define USB_CTRL_IOENB 0x00000004
#define USB_CTRL_ULPI_INT0EN 0x00000001
#define USB_CTRL_UTMI_PHY_EN 0x00000200
#define USB_CTRL_USB_EN 0x00000004
#define USB_CTRL_ULPI_PHY_CLK_SEL 0x00000400
/* Endpoint Queue Head data struct
* Rem: all the variables of qh are LittleEndian Mode

View File

@ -110,13 +110,14 @@ config USB_EHCI_BIG_ENDIAN_MMIO
depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \
ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
PPC_MPC512x || CPU_CAVIUM_OCTEON || \
PMC_MSP || SPARC_LEON)
PMC_MSP || SPARC_LEON || MIPS_SEAD3)
default y
config USB_EHCI_BIG_ENDIAN_DESC
bool
depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
PPC_MPC512x || PMC_MSP || SPARC_LEON)
PPC_MPC512x || PMC_MSP || SPARC_LEON || \
MIPS_SEAD3)
default y
config XPS_USB_HCD_XILINX
@ -373,10 +374,15 @@ config USB_OHCI_HCD_PCI
If unsure, say Y.
config USB_OHCI_HCD_SSB
bool "OHCI support for Broadcom SSB OHCI core"
bool "OHCI support for Broadcom SSB OHCI core (DEPRECATED)"
depends on USB_OHCI_HCD && (SSB = y || SSB = USB_OHCI_HCD) && EXPERIMENTAL
select USB_HCD_SSB
select USB_OHCI_HCD_PLATFORM
default n
---help---
This option is deprecated now and the driver was removed, use
USB_HCD_SSB and USB_OHCI_HCD_PLATFORM instead.
Support for the Sonics Silicon Backplane (SSB) attached
Broadcom USB OHCI core.
@ -638,3 +644,27 @@ config USB_OCTEON_OHCI
config USB_OCTEON2_COMMON
bool
default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI
config USB_HCD_BCMA
tristate "BCMA usb host driver"
depends on BCMA && EXPERIMENTAL
select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
help
Enbale support for the EHCI and OCHI host controller on an bcma bus.
It converts the bcma driver into two platform device drivers
for ehci and ohci.
If unsure, say N.
config USB_HCD_SSB
tristate "SSB usb host driver"
depends on SSB && EXPERIMENTAL
select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
help
Enbale support for the EHCI and OCHI host controller on an bcma bus.
It converts the bcma driver into two platform device drivers
for ehci and ohci.
If unsure, say N.

View File

@ -41,3 +41,5 @@ obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
obj-$(CONFIG_MIPS_ALCHEMY) += alchemy-common.o
obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o

334
drivers/usb/host/bcma-hcd.c Normal file
View File

@ -0,0 +1,334 @@
/*
* Broadcom specific Advanced Microcontroller Bus
* Broadcom USB-core driver (BCMA bus glue)
*
* Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
*
* Based on ssb-ohci driver
* Copyright 2007 Michael Buesch <m@bues.ch>
*
* Derived from the OHCI-PCI driver
* Copyright 1999 Roman Weissgaerber
* Copyright 2000-2002 David Brownell
* Copyright 1999 Linus Torvalds
* Copyright 1999 Gregory P. Smith
*
* Derived from the USBcore related parts of Broadcom-SB
* Copyright 2005-2011 Broadcom Corporation
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include <linux/bcma/bcma.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>
MODULE_AUTHOR("Hauke Mehrtens");
MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
MODULE_LICENSE("GPL");
struct bcma_hcd_device {
struct platform_device *ehci_dev;
struct platform_device *ohci_dev;
};
/* Wait for bitmask in a register to get set or cleared.
* timeout is in units of ten-microseconds.
*/
static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
int timeout)
{
int i;
u32 val;
for (i = 0; i < timeout; i++) {
val = bcma_read32(dev, reg);
if ((val & bitmask) == bitmask)
return 0;
udelay(10);
}
return -ETIMEDOUT;
}
static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
{
#ifdef CONFIG_BCMA_DRIVER_MIPS
/* Work around for 4716 failures. */
if (dev->bus->chipinfo.id == 0x4716) {
u32 tmp;
tmp = bcma_cpu_clock(&dev->bus->drv_mips);
if (tmp >= 480000000)
tmp = 0x1846b; /* set CDR to 0x11(fast) */
else if (tmp == 453000000)
tmp = 0x1046b; /* set CDR to 0x10(slow) */
else
tmp = 0;
/* Change Shim mdio control reg to fix host not acking at
* high frequencies
*/
if (tmp) {
bcma_write32(dev, 0x524, 0x1); /* write sel to enable */
udelay(500);
bcma_write32(dev, 0x524, tmp);
udelay(500);
bcma_write32(dev, 0x524, 0x4ab);
udelay(500);
bcma_read32(dev, 0x528);
bcma_write32(dev, 0x528, 0x80000000);
}
}
#endif /* CONFIG_BCMA_DRIVER_MIPS */
}
/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
static void __devinit bcma_hcd_init_chip(struct bcma_device *dev)
{
u32 tmp;
/*
* USB 2.0 special considerations:
*
* 1. Since the core supports both OHCI and EHCI functions, it must
* only be reset once.
*
* 2. In addition to the standard SI reset sequence, the Host Control
* Register must be programmed to bring the USB core and various
* phy components out of reset.
*/
if (!bcma_core_is_enabled(dev)) {
bcma_core_enable(dev, 0);
mdelay(10);
if (dev->id.rev >= 5) {
/* Enable Misc PLL */
tmp = bcma_read32(dev, 0x1e0);
tmp |= 0x100;
bcma_write32(dev, 0x1e0, tmp);
if (bcma_wait_bits(dev, 0x1e0, 1 << 24, 100))
printk(KERN_EMERG "Failed to enable misc PPL!\n");
/* Take out of resets */
bcma_write32(dev, 0x200, 0x4ff);
udelay(25);
bcma_write32(dev, 0x200, 0x6ff);
udelay(25);
/* Make sure digital and AFE are locked in USB PHY */
bcma_write32(dev, 0x524, 0x6b);
udelay(50);
tmp = bcma_read32(dev, 0x524);
udelay(50);
bcma_write32(dev, 0x524, 0xab);
udelay(50);
tmp = bcma_read32(dev, 0x524);
udelay(50);
bcma_write32(dev, 0x524, 0x2b);
udelay(50);
tmp = bcma_read32(dev, 0x524);
udelay(50);
bcma_write32(dev, 0x524, 0x10ab);
udelay(50);
tmp = bcma_read32(dev, 0x524);
if (bcma_wait_bits(dev, 0x528, 0xc000, 10000)) {
tmp = bcma_read32(dev, 0x528);
printk(KERN_EMERG
"USB20H mdio_rddata 0x%08x\n", tmp);
}
bcma_write32(dev, 0x528, 0x80000000);
tmp = bcma_read32(dev, 0x314);
udelay(265);
bcma_write32(dev, 0x200, 0x7ff);
udelay(10);
/* Take USB and HSIC out of non-driving modes */
bcma_write32(dev, 0x510, 0);
} else {
bcma_write32(dev, 0x200, 0x7ff);
udelay(1);
}
bcma_hcd_4716wa(dev);
}
}
static const struct usb_ehci_pdata ehci_pdata = {
};
static const struct usb_ohci_pdata ohci_pdata = {
};
static struct platform_device * __devinit
bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
{
struct platform_device *hci_dev;
struct resource hci_res[2];
int ret = -ENOMEM;
memset(hci_res, 0, sizeof(hci_res));
hci_res[0].start = addr;
hci_res[0].end = hci_res[0].start + 0x1000 - 1;
hci_res[0].flags = IORESOURCE_MEM;
hci_res[1].start = dev->irq;
hci_res[1].flags = IORESOURCE_IRQ;
hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
"ehci-platform" , 0);
if (!hci_dev)
return NULL;
hci_dev->dev.parent = &dev->dev;
hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
ret = platform_device_add_resources(hci_dev, hci_res,
ARRAY_SIZE(hci_res));
if (ret)
goto err_alloc;
if (ohci)
ret = platform_device_add_data(hci_dev, &ohci_pdata,
sizeof(ohci_pdata));
else
ret = platform_device_add_data(hci_dev, &ehci_pdata,
sizeof(ehci_pdata));
if (ret)
goto err_alloc;
ret = platform_device_add(hci_dev);
if (ret)
goto err_alloc;
return hci_dev;
err_alloc:
platform_device_put(hci_dev);
return ERR_PTR(ret);
}
static int __devinit bcma_hcd_probe(struct bcma_device *dev)
{
int err;
u16 chipid_top;
u32 ohci_addr;
struct bcma_hcd_device *usb_dev;
struct bcma_chipinfo *chipinfo;
chipinfo = &dev->bus->chipinfo;
/* USBcores are only connected on embedded devices. */
chipid_top = (chipinfo->id & 0xFF00);
if (chipid_top != 0x4700 && chipid_top != 0x5300)
return -ENODEV;
/* TODO: Probably need checks here; is the core connected? */
if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
return -EOPNOTSUPP;
usb_dev = kzalloc(sizeof(struct bcma_hcd_device), GFP_KERNEL);
if (!usb_dev)
return -ENOMEM;
bcma_hcd_init_chip(dev);
/* In AI chips EHCI is addrspace 0, OHCI is 1 */
ohci_addr = dev->addr1;
if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
&& chipinfo->rev == 0)
ohci_addr = 0x18009000;
usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
if (IS_ERR(usb_dev->ohci_dev)) {
err = PTR_ERR(usb_dev->ohci_dev);
goto err_free_usb_dev;
}
usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
if (IS_ERR(usb_dev->ehci_dev)) {
err = PTR_ERR(usb_dev->ehci_dev);
goto err_unregister_ohci_dev;
}
bcma_set_drvdata(dev, usb_dev);
return 0;
err_unregister_ohci_dev:
platform_device_unregister(usb_dev->ohci_dev);
err_free_usb_dev:
kfree(usb_dev);
return err;
}
static void __devexit bcma_hcd_remove(struct bcma_device *dev)
{
struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
struct platform_device *ohci_dev = usb_dev->ohci_dev;
struct platform_device *ehci_dev = usb_dev->ehci_dev;
if (ohci_dev)
platform_device_unregister(ohci_dev);
if (ehci_dev)
platform_device_unregister(ehci_dev);
bcma_core_disable(dev, 0);
}
static void bcma_hcd_shutdown(struct bcma_device *dev)
{
bcma_core_disable(dev, 0);
}
#ifdef CONFIG_PM
static int bcma_hcd_suspend(struct bcma_device *dev)
{
bcma_core_disable(dev, 0);
return 0;
}
static int bcma_hcd_resume(struct bcma_device *dev)
{
bcma_core_enable(dev, 0);
return 0;
}
#else /* !CONFIG_PM */
#define bcma_hcd_suspend NULL
#define bcma_hcd_resume NULL
#endif /* CONFIG_PM */
static const struct bcma_device_id bcma_hcd_table[] __devinitconst = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
static struct bcma_driver bcma_hcd_driver = {
.name = KBUILD_MODNAME,
.id_table = bcma_hcd_table,
.probe = bcma_hcd_probe,
.remove = __devexit_p(bcma_hcd_remove),
.shutdown = bcma_hcd_shutdown,
.suspend = bcma_hcd_suspend,
.resume = bcma_hcd_resume,
};
static int __init bcma_hcd_init(void)
{
return bcma_driver_register(&bcma_hcd_driver);
}
module_init(bcma_hcd_init);
static void __exit bcma_hcd_exit(void)
{
bcma_driver_unregister(&bcma_hcd_driver);
}
module_exit(bcma_hcd_exit);

View File

@ -1,6 +1,6 @@
/*
* Copyright 2005-2009 MontaVista Software, Inc.
* Copyright 2008 Freescale Semiconductor, Inc.
* Copyright 2008,2012 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -211,22 +211,32 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
usb_put_hcd(hcd);
}
static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
static void ehci_fsl_setup_phy(struct usb_hcd *hcd,
enum fsl_usb2_phy_modes phy_mode,
unsigned int port_offset)
{
u32 portsc;
struct usb_hcd *hcd = ehci_to_hcd(ehci);
u32 portsc, temp;
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
void __iomem *non_ehci = hcd->regs;
struct fsl_usb2_platform_data *pdata;
struct device *dev = hcd->self.controller;
struct fsl_usb2_platform_data *pdata = dev->platform_data;
pdata = hcd->self.controller->platform_data;
if (pdata->controller_ver < 0) {
dev_warn(hcd->self.controller, "Could not get controller version\n");
return;
}
portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
switch (phy_mode) {
case FSL_USB2_PHY_ULPI:
if (pdata->controller_ver) {
/* controller version 1.6 or above */
temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
USB_CTRL_USB_EN | ULPI_PHY_CLK_SEL);
}
portsc |= PORT_PTS_ULPI;
break;
case FSL_USB2_PHY_SERIAL:
@ -236,6 +246,14 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
portsc |= PORT_PTS_PTW;
/* fall through */
case FSL_USB2_PHY_UTMI:
if (pdata->controller_ver) {
/* controller version 1.6 or above */
temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
UTMI_PHY_EN | USB_CTRL_USB_EN);
mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to
become stable - 10ms*/
}
/* enable UTMI PHY */
if (pdata->have_sysif_regs)
setbits32(non_ehci + FSL_SOC_USB_CTRL,
@ -276,7 +294,7 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
(pdata->operating_mode == FSL_USB2_DR_OTG))
ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
unsigned int chip, rev, svr;
@ -290,9 +308,9 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
ehci->has_fsl_port_bug = 1;
if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1);
}
if (pdata->have_sysif_regs) {

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
/* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc.
* Copyright (c) 2005 MontaVista Software
*
* This program is free software; you can redistribute it and/or modify it
@ -50,4 +50,15 @@
#define CTRL_UTMI_PHY_EN (1<<9)
#define CTRL_PHY_CLK_VALID (1 << 17)
#define SNOOP_SIZE_2GB 0x1e
/* control Register Bit Masks */
#define ULPI_INT_EN (1<<0)
#define WU_INT_EN (1<<1)
#define USB_CTRL_USB_EN (1<<2)
#define LINE_STATE_FILTER__EN (1<<3)
#define KEEP_OTG_ON (1<<4)
#define OTG_PORT (1<<5)
#define PLL_RESET (1<<8)
#define UTMI_PHY_EN (1<<9)
#define ULPI_PHY_CLK_SEL (1<<10)
#endif /* _EHCI_FSL_H */

View File

@ -417,9 +417,6 @@ static void ehci_iaa_watchdog(unsigned long param)
* CMD_IAAD when it sets STS_IAA.)
*/
cmd = ehci_readl(ehci, &ehci->regs->command);
if (cmd & CMD_IAAD)
ehci_writel(ehci, cmd & ~CMD_IAAD,
&ehci->regs->command);
/* If IAA is set here it either legitimately triggered
* before we cleared IAAD above (but _way_ late, so we'll
@ -894,11 +891,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* complete the unlinking of some qh [4.15.2.3] */
if (status & STS_IAA) {
/* guard against (alleged) silicon errata */
if (cmd & CMD_IAAD) {
ehci_writel(ehci, cmd & ~CMD_IAAD,
&ehci->regs->command);
if (cmd & CMD_IAAD)
ehci_dbg(ehci, "IAA with IAAD still set?\n");
}
if (ehci->reclaim) {
COUNT(ehci->stats.reclaim);
end_unlink_async(ehci);
@ -1378,6 +1372,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_ls1x_driver
#endif
#ifdef CONFIG_MIPS_SEAD3
#include "ehci-sead3.c"
#define PLATFORM_DRIVER ehci_hcd_sead3_driver
#endif
#ifdef CONFIG_USB_EHCI_HCD_PLATFORM
#include "ehci-platform.c"
#define PLATFORM_DRIVER ehci_platform_driver

View File

@ -531,7 +531,8 @@ static int check_reset_complete (
if (ehci->has_amcc_usb23)
set_ohci_hcfs(ehci, 1);
} else {
ehci_dbg (ehci, "port %d high speed\n", index + 1);
ehci_dbg(ehci, "port %d reset complete, port enabled\n",
index + 1);
/* ensure 440EPx ohci controller state is suspended */
if (ehci->has_amcc_usb23)
set_ohci_hcfs(ehci, 0);
@ -699,6 +700,7 @@ static int ehci_hub_control (
goto error;
wIndex--;
temp = ehci_readl(ehci, status_reg);
temp &= ~PORT_RWC_BITS;
/*
* Even if OWNER is set, so the port is owned by the
@ -712,8 +714,7 @@ static int ehci_hub_control (
ehci_writel(ehci, temp & ~PORT_PE, status_reg);
break;
case USB_PORT_FEAT_C_ENABLE:
ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
status_reg);
ehci_writel(ehci, temp | PORT_PEC, status_reg);
break;
case USB_PORT_FEAT_SUSPEND:
if (temp & PORT_RESET)
@ -742,7 +743,7 @@ static int ehci_hub_control (
spin_lock_irqsave(&ehci->lock, flags);
}
/* resume signaling for 20 msec */
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
temp &= ~PORT_WAKE_BITS;
ehci_writel(ehci, temp | PORT_RESUME, status_reg);
ehci->reset_done[wIndex] = jiffies
+ msecs_to_jiffies(20);
@ -752,9 +753,8 @@ static int ehci_hub_control (
break;
case USB_PORT_FEAT_POWER:
if (HCS_PPC (ehci->hcs_params))
ehci_writel(ehci,
temp & ~(PORT_RWC_BITS | PORT_POWER),
status_reg);
ehci_writel(ehci, temp & ~PORT_POWER,
status_reg);
break;
case USB_PORT_FEAT_C_CONNECTION:
if (ehci->has_lpm) {
@ -762,12 +762,10 @@ static int ehci_hub_control (
temp &= ~PORT_LPM;
temp &= ~PORT_DEV_ADDR;
}
ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
status_reg);
ehci_writel(ehci, temp | PORT_CSC, status_reg);
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
status_reg);
ehci_writel(ehci, temp | PORT_OCC, status_reg);
break;
case USB_PORT_FEAT_C_RESET:
/* GetPortStatus clears reset */

View File

@ -94,12 +94,12 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
irq = platform_get_irq(dev, 0);
if (irq < 0) {
pr_err("no irq provieded");
pr_err("no irq provided");
return irq;
}
res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res_mem) {
pr_err("no memory recourse provieded");
pr_err("no memory recourse provided");
return -ENXIO;
}

View File

@ -232,6 +232,8 @@ static int s5p_ehci_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
clk_disable(s5p_ehci->clk);
return rc;
}
@ -243,6 +245,8 @@ static int s5p_ehci_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
clk_enable(s5p_ehci->clk);
if (pdata && pdata->phy_init)
pdata->phy_init(pdev, S5P_USB_PHY_HOST);

View File

@ -0,0 +1,266 @@
/*
* MIPS CI13320A EHCI Host Controller driver
* Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
*
* Copyright (C) 2012 MIPS Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/platform_device.h>
static int ehci_sead3_setup(struct usb_hcd *hcd)
{
int ret;
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
ehci->caps = hcd->regs + 0x100;
ret = ehci_setup(hcd);
if (ret)
return ret;
ehci->need_io_watchdog = 0;
#ifdef __BIG_ENDIAN
ehci->big_endian_mmio = 1;
ehci->big_endian_desc = 1;
#endif
/* Set burst length to 16 words. */
ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]);
return ret;
}
const struct hc_driver ehci_sead3_hc_driver = {
.description = hcd_name,
.product_desc = "SEAD-3 EHCI",
.hcd_priv_size = sizeof(struct ehci_hcd),
/*
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2,
/*
* basic lifecycle operations
*
*/
.reset = ehci_sead3_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
/*
* scheduling support
*/
.get_frame_number = ehci_get_frame,
/*
* root hub support
*/
.hub_status_data = ehci_hub_status_data,
.hub_control = ehci_hub_control,
.bus_suspend = ehci_bus_suspend,
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct resource *res;
int ret;
if (usb_disabled())
return -ENODEV;
if (pdev->resource[1].flags != IORESOURCE_IRQ) {
pr_debug("resource[1] is not IORESOURCE_IRQ");
return -ENOMEM;
}
hcd = usb_create_hcd(&ehci_sead3_hc_driver, &pdev->dev, "SEAD-3");
if (!hcd)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
pr_debug("request_mem_region failed");
ret = -EBUSY;
goto err1;
}
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
pr_debug("ioremap failed");
ret = -ENOMEM;
goto err2;
}
/* Root hub has integrated TT. */
hcd->has_tt = 1;
ret = usb_add_hcd(hcd, pdev->resource[1].start,
IRQF_SHARED);
if (ret == 0) {
platform_set_drvdata(pdev, hcd);
return ret;
}
iounmap(hcd->regs);
err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
usb_put_hcd(hcd);
return ret;
}
static int ehci_hcd_sead3_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_remove_hcd(hcd);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
platform_set_drvdata(pdev, NULL);
return 0;
}
#ifdef CONFIG_PM
static int ehci_hcd_sead3_drv_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
unsigned long flags;
int rc = 0;
if (time_before(jiffies, ehci->next_statechange))
msleep(20);
/* Root hub was already suspended. Disable irq emission and
* mark HW unaccessible. The PM and USB cores make sure that
* the root hub is either suspended or stopped.
*/
ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
spin_lock_irqsave(&ehci->lock, flags);
ehci_writel(ehci, 0, &ehci->regs->intr_enable);
(void)ehci_readl(ehci, &ehci->regs->intr_enable);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
spin_unlock_irqrestore(&ehci->lock, flags);
/* could save FLADJ in case of Vaux power loss
* ... we'd only use it to handle clock skew
*/
return rc;
}
static int ehci_hcd_sead3_drv_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
/* maybe restore FLADJ. */
if (time_before(jiffies, ehci->next_statechange))
msleep(100);
/* Mark hardware accessible again as we are out of D3 state by now */
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
/* If CF is still set, we maintained PCI Vaux power.
* Just undo the effect of ehci_pci_suspend().
*/
if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
int mask = INTR_MASK;
ehci_prepare_ports_for_controller_resume(ehci);
if (!hcd->self.root_hub->do_remote_wakeup)
mask &= ~STS_PCD;
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
ehci_readl(ehci, &ehci->regs->intr_enable);
return 0;
}
ehci_dbg(ehci, "lost power, restarting\n");
usb_root_hub_lost_power(hcd->self.root_hub);
/* Else reset, to cope with power loss or flush-to-storage
* style "resume" having let BIOS kick in during reboot.
*/
(void) ehci_halt(ehci);
(void) ehci_reset(ehci);
/* emptying the schedule aborts any urbs */
spin_lock_irq(&ehci->lock);
if (ehci->reclaim)
end_unlink_async(ehci);
ehci_work(ehci);
spin_unlock_irq(&ehci->lock);
ehci_writel(ehci, ehci->command, &ehci->regs->command);
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
/* here we "know" root ports should always stay powered */
ehci_port_power(ehci, 1);
ehci->rh_state = EHCI_RH_SUSPENDED;
return 0;
}
static const struct dev_pm_ops sead3_ehci_pmops = {
.suspend = ehci_hcd_sead3_drv_suspend,
.resume = ehci_hcd_sead3_drv_resume,
};
#define SEAD3_EHCI_PMOPS (&sead3_ehci_pmops)
#else
#define SEAD3_EHCI_PMOPS NULL
#endif
static struct platform_driver ehci_hcd_sead3_driver = {
.probe = ehci_hcd_sead3_drv_probe,
.remove = ehci_hcd_sead3_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.name = "sead3-ehci",
.owner = THIS_MODULE,
.pm = SEAD3_EHCI_PMOPS,
}
};
MODULE_ALIAS("platform:sead3-ehci");

View File

@ -11,6 +11,7 @@
*/
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/platform_data/ehci-sh.h>
struct ehci_sh_priv {
struct clk *iclk, *fclk;
@ -100,6 +101,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
const struct hc_driver *driver = &ehci_sh_hc_driver;
struct resource *res;
struct ehci_sh_priv *priv;
struct ehci_sh_platdata *pdata;
struct usb_hcd *hcd;
int irq, ret;
@ -124,6 +126,9 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
goto fail_create_hcd;
}
if (pdev->dev.platform_data != NULL)
pdata = pdev->dev.platform_data;
/* initialize hcd */
hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev,
dev_name(&pdev->dev));
@ -168,6 +173,9 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
clk_enable(priv->fclk);
clk_enable(priv->iclk);
if (pdata && pdata->phy_init)
pdata->phy_init();
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to add hcd");

View File

@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
@ -25,12 +26,12 @@ struct spear_ehci {
static void spear_start_ehci(struct spear_ehci *ehci)
{
clk_enable(ehci->clk);
clk_prepare_enable(ehci->clk);
}
static void spear_stop_ehci(struct spear_ehci *ehci)
{
clk_disable(ehci->clk);
clk_disable_unprepare(ehci->clk);
}
static int ehci_spear_setup(struct usb_hcd *hcd)
@ -168,6 +169,8 @@ static int ehci_spear_drv_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
ehci_spear_drv_resume);
static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd ;
@ -175,12 +178,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
struct resource *res;
struct clk *usbh_clk;
const struct hc_driver *driver = &ehci_spear_hc_driver;
int *pdata = pdev->dev.platform_data;
int irq, retval;
char clk_name[20] = "usbh_clk";
if (pdata == NULL)
return -EFAULT;
static int instance = -1;
if (usb_disabled())
return -ENODEV;
@ -191,8 +191,22 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
goto fail_irq_get;
}
if (*pdata >= 0)
sprintf(clk_name, "usbh.%01d_clk", *pdata);
/*
* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &spear_ehci_dma_mask;
/*
* Increment the device instance, when probing via device-tree
*/
if (pdev->id < 0)
instance++;
else
instance = pdev->id;
sprintf(clk_name, "usbh.%01d_clk", instance);
usbh_clk = clk_get(NULL, clk_name);
if (IS_ERR(usbh_clk)) {
@ -277,6 +291,11 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
return 0;
}
static struct of_device_id spear_ehci_id_table[] __devinitdata = {
{ .compatible = "st,spear600-ehci", },
{ },
};
static struct platform_driver spear_ehci_hcd_driver = {
.probe = spear_ehci_hcd_drv_probe,
.remove = spear_ehci_hcd_drv_remove,
@ -285,6 +304,7 @@ static struct platform_driver spear_ehci_hcd_driver = {
.name = "spear-ehci",
.bus = &platform_bus_type,
.pm = &ehci_spear_pm_ops,
.of_match_table = of_match_ptr(spear_ehci_id_table),
}
};

View File

@ -148,18 +148,7 @@ static int tegra_ehci_hub_control(
spin_lock_irqsave(&ehci->lock, flags);
/*
* In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits
* that are write on clear, by writing back the register read value, so
* USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits
*/
if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) {
temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
ehci_writel(ehci, temp & ~PORT_PE, status_reg);
goto done;
}
else if (typeReq == GetPortStatus) {
if (typeReq == GetPortStatus) {
temp = ehci_readl(ehci, status_reg);
if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
/* Resume completed, re-enable disconnect detection */
@ -464,26 +453,23 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
}
#endif
struct temp_buffer {
struct dma_aligned_buffer {
void *kmalloc_ptr;
void *old_xfer_buffer;
u8 data[0];
};
static void free_temp_buffer(struct urb *urb)
static void free_dma_aligned_buffer(struct urb *urb)
{
enum dma_data_direction dir;
struct temp_buffer *temp;
struct dma_aligned_buffer *temp;
if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
return;
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
temp = container_of(urb->transfer_buffer,
struct dma_aligned_buffer, data);
temp = container_of(urb->transfer_buffer, struct temp_buffer,
data);
if (dir == DMA_FROM_DEVICE)
if (usb_urb_dir_in(urb))
memcpy(temp->old_xfer_buffer, temp->data,
urb->transfer_buffer_length);
urb->transfer_buffer = temp->old_xfer_buffer;
@ -492,10 +478,9 @@ static void free_temp_buffer(struct urb *urb)
urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
}
static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
static int alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
{
enum dma_data_direction dir;
struct temp_buffer *temp, *kmalloc_ptr;
struct dma_aligned_buffer *temp, *kmalloc_ptr;
size_t kmalloc_size;
if (urb->num_sgs || urb->sg ||
@ -503,22 +488,19 @@ static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
!((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1)))
return 0;
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
/* Allocate a buffer with enough padding for alignment */
kmalloc_size = urb->transfer_buffer_length +
sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1;
sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1;
kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
if (!kmalloc_ptr)
return -ENOMEM;
/* Position our struct temp_buffer such that data is aligned */
/* Position our struct dma_aligned_buffer such that data is aligned */
temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1;
temp->kmalloc_ptr = kmalloc_ptr;
temp->old_xfer_buffer = urb->transfer_buffer;
if (dir == DMA_TO_DEVICE)
if (usb_urb_dir_out(urb))
memcpy(temp->data, urb->transfer_buffer,
urb->transfer_buffer_length);
urb->transfer_buffer = temp->data;
@ -533,13 +515,13 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
{
int ret;
ret = alloc_temp_buffer(urb, mem_flags);
ret = alloc_dma_aligned_buffer(urb, mem_flags);
if (ret)
return ret;
ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
if (ret)
free_temp_buffer(urb);
free_dma_aligned_buffer(urb);
return ret;
}
@ -547,38 +529,39 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
{
usb_hcd_unmap_urb_for_dma(hcd, urb);
free_temp_buffer(urb);
free_dma_aligned_buffer(urb);
}
static const struct hc_driver tegra_ehci_hc_driver = {
.description = hcd_name,
.product_desc = "Tegra EHCI Host Controller",
.hcd_priv_size = sizeof(struct ehci_hcd),
.flags = HCD_USB2 | HCD_MEMORY,
.reset = tegra_ehci_setup,
/* standard ehci functions */
.irq = ehci_irq,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = tegra_ehci_shutdown,
.urb_enqueue = ehci_urb_enqueue,
.urb_dequeue = ehci_urb_dequeue,
.map_urb_for_dma = tegra_ehci_map_urb_for_dma,
.unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma,
.endpoint_disable = ehci_endpoint_disable,
.endpoint_reset = ehci_endpoint_reset,
.get_frame_number = ehci_get_frame,
.hub_status_data = ehci_hub_status_data,
.hub_control = tegra_ehci_hub_control,
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
/* modified ehci functions for tegra */
.reset = tegra_ehci_setup,
.shutdown = tegra_ehci_shutdown,
.map_urb_for_dma = tegra_ehci_map_urb_for_dma,
.unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma,
.hub_control = tegra_ehci_hub_control,
#ifdef CONFIG_PM
.bus_suspend = tegra_ehci_bus_suspend,
.bus_resume = tegra_ehci_bus_resume,
#endif
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
};
static int setup_vbus_gpio(struct platform_device *pdev)

View File

@ -155,7 +155,7 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
struct endpoint *ep;
struct usb_td __iomem *td;
unsigned long ep_offset;
char *err_for = "enpoint PRAM";
char *err_for = "endpoint PRAM";
int ep_mem_size;
u32 i;

View File

@ -119,6 +119,39 @@ struct platform_device * __devinit fsl_usb2_device_register(
static const struct of_device_id fsl_usb2_mph_dr_of_match[];
static int usb_get_ver_info(struct device_node *np)
{
int ver = -1;
/*
* returns 1 for usb controller version 1.6
* returns 2 for usb controller version 2.2
* returns 0 otherwise
*/
if (of_device_is_compatible(np, "fsl-usb2-dr")) {
if (of_device_is_compatible(np, "fsl-usb2-dr-v1.6"))
ver = FSL_USB_VER_1_6;
else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.2"))
ver = FSL_USB_VER_2_2;
else /* for previous controller versions */
ver = FSL_USB_VER_OLD;
if (ver > -1)
return ver;
}
if (of_device_is_compatible(np, "fsl-usb2-mph")) {
if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6"))
ver = FSL_USB_VER_1_6;
else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2"))
ver = FSL_USB_VER_2_2;
else /* for previous controller versions */
ver = FSL_USB_VER_OLD;
}
return ver;
}
static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
@ -166,6 +199,14 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
prop = of_get_property(np, "phy_type", NULL);
pdata->phy_mode = determine_usb_phy(prop);
pdata->controller_ver = usb_get_ver_info(np);
if (pdata->have_sysif_regs) {
if (pdata->controller_ver < 0) {
dev_warn(&ofdev->dev, "Could not get controller version\n");
return -ENODEV;
}
}
for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
if (!dev_data->drivers[i])

View File

@ -1562,11 +1562,14 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
retval = -ESHUTDOWN;
qtd_list_free(&new_qtds);
goto out;
}
retval = usb_hcd_link_urb_to_ep(hcd, urb);
if (retval)
if (retval) {
qtd_list_free(&new_qtds);
goto out;
}
qh = urb->ep->hcpriv;
if (qh) {
@ -1584,6 +1587,7 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
if (!qh) {
retval = -ENOMEM;
usb_hcd_unlink_urb_from_ep(hcd, urb);
qtd_list_free(&new_qtds);
goto out;
}
list_add_tail(&qh->qh_list, ep_queue);
@ -1683,6 +1687,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
list_for_each_entry(qtd, &qh->qtd_list, qtd_list)
if (qtd->urb == urb) {
dequeue_urb_from_qtd(hcd, qh, qtd);
list_move(&qtd->qtd_list, &qh->qtd_list);
break;
}
@ -2176,7 +2181,7 @@ static const struct hc_driver isp1760_hc_driver = {
int __init init_kmem_once(void)
{
urb_listitem_cachep = kmem_cache_create("isp1760 urb_listitem",
urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem",
sizeof(struct urb_listitem), 0, SLAB_TEMPORARY |
SLAB_MEM_SPREAD, NULL);

View File

@ -398,6 +398,9 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev)
hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
irqflags, -ENOENT,
&pdev->dev, dev_name(&pdev->dev), devflags);
dev_set_drvdata(&pdev->dev, hcd);
if (IS_ERR(hcd)) {
pr_warning("isp1760: Failed to register the HCD device\n");
ret = -ENODEV;
@ -417,11 +420,16 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
{
struct resource *mem_res;
resource_size_t mem_size;
struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev);
usb_remove_hcd(hcd);
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mem_size = resource_size(mem_res);
release_mem_region(mem_res->start, mem_size);
usb_put_hcd(hcd);
return 0;
}

View File

@ -1080,11 +1080,6 @@ MODULE_LICENSE ("GPL");
#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver
#endif
#ifdef CONFIG_USB_OHCI_HCD_SSB
#include "ohci-ssb.c"
#define SSB_OHCI_DRIVER ssb_ohci_driver
#endif
#ifdef CONFIG_MFD_SM501
#include "ohci-sm501.c"
#define SM501_OHCI_DRIVER ohci_hcd_sm501_driver
@ -1128,8 +1123,7 @@ MODULE_LICENSE ("GPL");
!defined(SA1111_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && \
!defined(SM501_OHCI_DRIVER) && \
!defined(TMIO_OHCI_DRIVER) && \
!defined(SSB_OHCI_DRIVER)
!defined(TMIO_OHCI_DRIVER)
#error "missing bus glue for ohci-hcd"
#endif
@ -1195,12 +1189,6 @@ static int __init ohci_hcd_mod_init(void)
goto error_pci;
#endif
#ifdef SSB_OHCI_DRIVER
retval = ssb_driver_register(&SSB_OHCI_DRIVER);
if (retval)
goto error_ssb;
#endif
#ifdef SM501_OHCI_DRIVER
retval = platform_driver_register(&SM501_OHCI_DRIVER);
if (retval < 0)
@ -1224,10 +1212,6 @@ static int __init ohci_hcd_mod_init(void)
platform_driver_unregister(&SM501_OHCI_DRIVER);
error_sm501:
#endif
#ifdef SSB_OHCI_DRIVER
ssb_driver_unregister(&SSB_OHCI_DRIVER);
error_ssb:
#endif
#ifdef PCI_DRIVER
pci_unregister_driver(&PCI_DRIVER);
error_pci:
@ -1275,9 +1259,6 @@ static void __exit ohci_hcd_mod_exit(void)
#ifdef SM501_OHCI_DRIVER
platform_driver_unregister(&SM501_OHCI_DRIVER);
#endif
#ifdef SSB_OHCI_DRIVER
ssb_driver_unregister(&SSB_OHCI_DRIVER);
#endif
#ifdef PCI_DRIVER
pci_unregister_driver(&PCI_DRIVER);
#endif

View File

@ -93,13 +93,13 @@ static int __devinit ohci_platform_probe(struct platform_device *dev)
irq = platform_get_irq(dev, 0);
if (irq < 0) {
pr_err("no irq provieded");
pr_err("no irq provided");
return irq;
}
res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res_mem) {
pr_err("no memory recourse provieded");
pr_err("no memory recourse provided");
return -ENXIO;
}

View File

@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match);
#if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \
!defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE)
#error "No endianess selected for ppc-of-ohci"
#error "No endianness selected for ppc-of-ohci"
#endif

View File

@ -14,6 +14,7 @@
#include <linux/signal.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/of.h>
struct spear_ohci {
struct ohci_hcd ohci;
@ -24,12 +25,12 @@ struct spear_ohci {
static void spear_start_ohci(struct spear_ohci *ohci)
{
clk_enable(ohci->clk);
clk_prepare_enable(ohci->clk);
}
static void spear_stop_ohci(struct spear_ohci *ohci)
{
clk_disable(ohci->clk);
clk_disable_unprepare(ohci->clk);
}
static int __devinit ohci_spear_start(struct usb_hcd *hcd)
@ -90,6 +91,8 @@ static const struct hc_driver ohci_spear_hc_driver = {
.start_port_reset = ohci_start_port_reset,
};
static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
{
const struct hc_driver *driver = &ohci_spear_hc_driver;
@ -98,11 +101,8 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
struct spear_ohci *ohci_p;
struct resource *res;
int retval, irq;
int *pdata = pdev->dev.platform_data;
char clk_name[20] = "usbh_clk";
if (pdata == NULL)
return -EFAULT;
static int instance = -1;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@ -110,8 +110,22 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
goto fail_irq_get;
}
if (*pdata >= 0)
sprintf(clk_name, "usbh.%01d_clk", *pdata);
/*
* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &spear_ohci_dma_mask;
/*
* Increment the device instance, when probing via device-tree
*/
if (pdev->id < 0)
instance++;
else
instance = pdev->id;
sprintf(clk_name, "usbh.%01d_clk", instance);
usbh_clk = clk_get(NULL, clk_name);
if (IS_ERR(usbh_clk)) {
@ -222,6 +236,11 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
}
#endif
static struct of_device_id spear_ohci_id_table[] __devinitdata = {
{ .compatible = "st,spear600-ohci", },
{ },
};
/* Driver definition to register with the platform bus */
static struct platform_driver spear_ohci_hcd_driver = {
.probe = spear_ohci_hcd_drv_probe,
@ -233,6 +252,7 @@ static struct platform_driver spear_ohci_hcd_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "spear-ohci",
.of_match_table = of_match_ptr(spear_ohci_id_table),
},
};

View File

@ -1,260 +0,0 @@
/*
* Sonics Silicon Backplane
* Broadcom USB-core OHCI driver
*
* Copyright 2007 Michael Buesch <m@bues.ch>
*
* Derived from the OHCI-PCI driver
* Copyright 1999 Roman Weissgaerber
* Copyright 2000-2002 David Brownell
* Copyright 1999 Linus Torvalds
* Copyright 1999 Gregory P. Smith
*
* Derived from the USBcore related parts of Broadcom-SB
* Copyright 2005 Broadcom Corporation
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include <linux/ssb/ssb.h>
#define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29)
struct ssb_ohci_device {
struct ohci_hcd ohci; /* _must_ be at the beginning. */
u32 enable_flags;
};
static inline
struct ssb_ohci_device *hcd_to_ssb_ohci(struct usb_hcd *hcd)
{
return (struct ssb_ohci_device *)(hcd->hcd_priv);
}
static int ssb_ohci_reset(struct usb_hcd *hcd)
{
struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
struct ohci_hcd *ohci = &ohcidev->ohci;
int err;
ohci_hcd_init(ohci);
err = ohci_init(ohci);
return err;
}
static int ssb_ohci_start(struct usb_hcd *hcd)
{
struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
struct ohci_hcd *ohci = &ohcidev->ohci;
int err;
err = ohci_run(ohci);
if (err < 0) {
ohci_err(ohci, "can't start\n");
ohci_stop(hcd);
}
return err;
}
static const struct hc_driver ssb_ohci_hc_driver = {
.description = "ssb-usb-ohci",
.product_desc = "SSB OHCI Controller",
.hcd_priv_size = sizeof(struct ssb_ohci_device),
.irq = ohci_irq,
.flags = HCD_MEMORY | HCD_USB11,
.reset = ssb_ohci_reset,
.start = ssb_ohci_start,
.stop = ohci_stop,
.shutdown = ohci_shutdown,
.urb_enqueue = ohci_urb_enqueue,
.urb_dequeue = ohci_urb_dequeue,
.endpoint_disable = ohci_endpoint_disable,
.get_frame_number = ohci_get_frame,
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
#ifdef CONFIG_PM
.bus_suspend = ohci_bus_suspend,
.bus_resume = ohci_bus_resume,
#endif
.start_port_reset = ohci_start_port_reset,
};
static void ssb_ohci_detach(struct ssb_device *dev)
{
struct usb_hcd *hcd = ssb_get_drvdata(dev);
if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd);
usb_remove_hcd(hcd);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
ssb_device_disable(dev, 0);
}
static int ssb_ohci_attach(struct ssb_device *dev)
{
struct ssb_ohci_device *ohcidev;
struct usb_hcd *hcd;
int err = -ENOMEM;
u32 tmp, flags = 0;
if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
return -EOPNOTSUPP;
if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) {
/* Put the device into host-mode. */
flags |= SSB_OHCI_TMSLOW_HOSTMODE;
ssb_device_enable(dev, flags);
} else if (dev->id.coreid == SSB_DEV_USB20_HOST) {
/*
* USB 2.0 special considerations:
*
* In addition to the standard SSB reset sequence, the Host
* Control Register must be programmed to bring the USB core
* and various phy components out of reset.
*/
ssb_device_enable(dev, 0);
ssb_write32(dev, 0x200, 0x7ff);
/* Change Flush control reg */
tmp = ssb_read32(dev, 0x400);
tmp &= ~8;
ssb_write32(dev, 0x400, tmp);
tmp = ssb_read32(dev, 0x400);
/* Change Shim control reg */
tmp = ssb_read32(dev, 0x304);
tmp &= ~0x100;
ssb_write32(dev, 0x304, tmp);
tmp = ssb_read32(dev, 0x304);
udelay(1);
/* Work around for 5354 failures */
if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
/* Change syn01 reg */
tmp = 0x00fe00fe;
ssb_write32(dev, 0x894, tmp);
/* Change syn03 reg */
tmp = ssb_read32(dev, 0x89c);
tmp |= 0x1;
ssb_write32(dev, 0x89c, tmp);
}
} else
ssb_device_enable(dev, 0);
hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev,
dev_name(dev->dev));
if (!hcd)
goto err_dev_disable;
ohcidev = hcd_to_ssb_ohci(hcd);
ohcidev->enable_flags = flags;
tmp = ssb_read32(dev, SSB_ADMATCH0);
hcd->rsrc_start = ssb_admatch_base(tmp);
hcd->rsrc_len = ssb_admatch_size(tmp);
hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs)
goto err_put_hcd;
err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
if (err)
goto err_iounmap;
ssb_set_drvdata(dev, hcd);
return err;
err_iounmap:
iounmap(hcd->regs);
err_put_hcd:
usb_put_hcd(hcd);
err_dev_disable:
ssb_device_disable(dev, flags);
return err;
}
static int ssb_ohci_probe(struct ssb_device *dev,
const struct ssb_device_id *id)
{
int err;
u16 chipid_top;
/* USBcores are only connected on embedded devices. */
chipid_top = (dev->bus->chip_id & 0xFF00);
if (chipid_top != 0x4700 && chipid_top != 0x5300)
return -ENODEV;
/* TODO: Probably need checks here; is the core connected? */
if (usb_disabled())
return -ENODEV;
/* We currently always attach SSB_DEV_USB11_HOSTDEV
* as HOST OHCI. If we want to attach it as Client device,
* we must branch here and call into the (yet to
* be written) Client mode driver. Same for remove(). */
err = ssb_ohci_attach(dev);
return err;
}
static void ssb_ohci_remove(struct ssb_device *dev)
{
ssb_ohci_detach(dev);
}
#ifdef CONFIG_PM
static int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state)
{
ssb_device_disable(dev, 0);
return 0;
}
static int ssb_ohci_resume(struct ssb_device *dev)
{
struct usb_hcd *hcd = ssb_get_drvdata(dev);
struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
ssb_device_enable(dev, ohcidev->enable_flags);
ohci_finish_controller_resume(hcd);
return 0;
}
#else /* !CONFIG_PM */
#define ssb_ohci_suspend NULL
#define ssb_ohci_resume NULL
#endif /* CONFIG_PM */
static const struct ssb_device_id ssb_ohci_table[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
SSB_DEVTABLE_END
};
MODULE_DEVICE_TABLE(ssb, ssb_ohci_table);
static struct ssb_driver ssb_ohci_driver = {
.name = KBUILD_MODNAME,
.id_table = ssb_ohci_table,
.probe = ssb_ohci_probe,
.remove = ssb_ohci_remove,
.suspend = ssb_ohci_suspend,
.resume = ssb_ohci_resume,
};

View File

@ -2991,8 +2991,9 @@ static int oxu_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
/* shouldn't happen often, but ...
* FIXME kill those tds' urbs
*/
err("can't reschedule qh %p, err %d",
qh, status);
dev_err(hcd->self.controller,
"can't reschedule qh %p, err %d\n", qh,
status);
}
return status;
}

279
drivers/usb/host/ssb-hcd.c Normal file
View File

@ -0,0 +1,279 @@
/*
* Sonics Silicon Backplane
* Broadcom USB-core driver (SSB bus glue)
*
* Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
*
* Based on ssb-ohci driver
* Copyright 2007 Michael Buesch <m@bues.ch>
*
* Derived from the OHCI-PCI driver
* Copyright 1999 Roman Weissgaerber
* Copyright 2000-2002 David Brownell
* Copyright 1999 Linus Torvalds
* Copyright 1999 Gregory P. Smith
*
* Derived from the USBcore related parts of Broadcom-SB
* Copyright 2005-2011 Broadcom Corporation
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include <linux/ssb/ssb.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>
MODULE_AUTHOR("Hauke Mehrtens");
MODULE_DESCRIPTION("Common USB driver for SSB Bus");
MODULE_LICENSE("GPL");
#define SSB_HCD_TMSLOW_HOSTMODE (1 << 29)
struct ssb_hcd_device {
struct platform_device *ehci_dev;
struct platform_device *ohci_dev;
u32 enable_flags;
};
static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
{
#ifdef CONFIG_SSB_DRIVER_MIPS
/* Work around for 5354 failures */
if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
/* Change syn01 reg */
ssb_write32(dev, 0x894, 0x00fe00fe);
/* Change syn03 reg */
ssb_write32(dev, 0x89c, ssb_read32(dev, 0x89c) | 0x1);
}
#endif
}
static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
{
if (dev->id.coreid == SSB_DEV_USB20_HOST) {
/*
* USB 2.0 special considerations:
*
* In addition to the standard SSB reset sequence, the Host
* Control Register must be programmed to bring the USB core
* and various phy components out of reset.
*/
ssb_write32(dev, 0x200, 0x7ff);
/* Change Flush control reg */
ssb_write32(dev, 0x400, ssb_read32(dev, 0x400) & ~8);
ssb_read32(dev, 0x400);
/* Change Shim control reg */
ssb_write32(dev, 0x304, ssb_read32(dev, 0x304) & ~0x100);
ssb_read32(dev, 0x304);
udelay(1);
ssb_hcd_5354wa(dev);
}
}
/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
static u32 __devinit ssb_hcd_init_chip(struct ssb_device *dev)
{
u32 flags = 0;
if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV)
/* Put the device into host-mode. */
flags |= SSB_HCD_TMSLOW_HOSTMODE;
ssb_device_enable(dev, flags);
ssb_hcd_usb20wa(dev);
return flags;
}
static const struct usb_ehci_pdata ehci_pdata = {
};
static const struct usb_ohci_pdata ohci_pdata = {
};
static struct platform_device * __devinit
ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
{
struct platform_device *hci_dev;
struct resource hci_res[2];
int ret = -ENOMEM;
memset(hci_res, 0, sizeof(hci_res));
hci_res[0].start = addr;
hci_res[0].end = hci_res[0].start + len - 1;
hci_res[0].flags = IORESOURCE_MEM;
hci_res[1].start = dev->irq;
hci_res[1].flags = IORESOURCE_IRQ;
hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
"ehci-platform" , 0);
if (!hci_dev)
return NULL;
hci_dev->dev.parent = dev->dev;
hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
ret = platform_device_add_resources(hci_dev, hci_res,
ARRAY_SIZE(hci_res));
if (ret)
goto err_alloc;
if (ohci)
ret = platform_device_add_data(hci_dev, &ohci_pdata,
sizeof(ohci_pdata));
else
ret = platform_device_add_data(hci_dev, &ehci_pdata,
sizeof(ehci_pdata));
if (ret)
goto err_alloc;
ret = platform_device_add(hci_dev);
if (ret)
goto err_alloc;
return hci_dev;
err_alloc:
platform_device_put(hci_dev);
return ERR_PTR(ret);
}
static int __devinit ssb_hcd_probe(struct ssb_device *dev,
const struct ssb_device_id *id)
{
int err, tmp;
int start, len;
u16 chipid_top;
u16 coreid = dev->id.coreid;
struct ssb_hcd_device *usb_dev;
/* USBcores are only connected on embedded devices. */
chipid_top = (dev->bus->chip_id & 0xFF00);
if (chipid_top != 0x4700 && chipid_top != 0x5300)
return -ENODEV;
/* TODO: Probably need checks here; is the core connected? */
if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
return -EOPNOTSUPP;
usb_dev = kzalloc(sizeof(struct ssb_hcd_device), GFP_KERNEL);
if (!usb_dev)
return -ENOMEM;
/* We currently always attach SSB_DEV_USB11_HOSTDEV
* as HOST OHCI. If we want to attach it as Client device,
* we must branch here and call into the (yet to
* be written) Client mode driver. Same for remove(). */
usb_dev->enable_flags = ssb_hcd_init_chip(dev);
tmp = ssb_read32(dev, SSB_ADMATCH0);
start = ssb_admatch_base(tmp);
len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp);
usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, true, start, len);
if (IS_ERR(usb_dev->ohci_dev)) {
err = PTR_ERR(usb_dev->ohci_dev);
goto err_free_usb_dev;
}
if (coreid == SSB_DEV_USB20_HOST) {
start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */
usb_dev->ehci_dev = ssb_hcd_create_pdev(dev, false, start, len);
if (IS_ERR(usb_dev->ehci_dev)) {
err = PTR_ERR(usb_dev->ehci_dev);
goto err_unregister_ohci_dev;
}
}
ssb_set_drvdata(dev, usb_dev);
return 0;
err_unregister_ohci_dev:
platform_device_unregister(usb_dev->ohci_dev);
err_free_usb_dev:
kfree(usb_dev);
return err;
}
static void __devexit ssb_hcd_remove(struct ssb_device *dev)
{
struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
struct platform_device *ohci_dev = usb_dev->ohci_dev;
struct platform_device *ehci_dev = usb_dev->ehci_dev;
if (ohci_dev)
platform_device_unregister(ohci_dev);
if (ehci_dev)
platform_device_unregister(ehci_dev);
ssb_device_disable(dev, 0);
}
static void __devexit ssb_hcd_shutdown(struct ssb_device *dev)
{
ssb_device_disable(dev, 0);
}
#ifdef CONFIG_PM
static int ssb_hcd_suspend(struct ssb_device *dev, pm_message_t state)
{
ssb_device_disable(dev, 0);
return 0;
}
static int ssb_hcd_resume(struct ssb_device *dev)
{
struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
ssb_device_enable(dev, usb_dev->enable_flags);
return 0;
}
#else /* !CONFIG_PM */
#define ssb_hcd_suspend NULL
#define ssb_hcd_resume NULL
#endif /* CONFIG_PM */
static const struct ssb_device_id ssb_hcd_table[] __devinitconst = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
SSB_DEVTABLE_END
};
MODULE_DEVICE_TABLE(ssb, ssb_hcd_table);
static struct ssb_driver ssb_hcd_driver = {
.name = KBUILD_MODNAME,
.id_table = ssb_hcd_table,
.probe = ssb_hcd_probe,
.remove = __devexit_p(ssb_hcd_remove),
.shutdown = ssb_hcd_shutdown,
.suspend = ssb_hcd_suspend,
.resume = ssb_hcd_resume,
};
static int __init ssb_hcd_init(void)
{
return ssb_driver_register(&ssb_hcd_driver);
}
module_init(ssb_hcd_init);
static void __exit ssb_hcd_exit(void)
{
ssb_driver_unregister(&ssb_hcd_driver);
}
module_exit(ssb_hcd_exit);

View File

@ -78,18 +78,14 @@ static int emi26_load_firmware (struct usb_device *dev)
const struct firmware *bitstream_fw = NULL;
const struct firmware *firmware_fw = NULL;
const struct ihex_binrec *rec;
int err;
int err = -ENOMEM;
int i;
__u32 addr; /* Address to write */
__u8 *buf;
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
if (!buf) {
dev_err(&dev->dev, "%s - error loading firmware: error = %d\n",
__func__, -ENOMEM);
err = -ENOMEM;
if (!buf)
goto wraperr;
}
err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev);
if (err)
@ -111,11 +107,8 @@ static int emi26_load_firmware (struct usb_device *dev)
/* Assert reset (stop the CPU in the EMI) */
err = emi26_set_reset(dev,1);
if (err < 0) {
dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
__func__, err);
if (err < 0)
goto wraperr;
}
rec = (const struct ihex_binrec *)loader_fw->data;
/* 1. We need to put the loader for the FPGA into the EZ-USB */
@ -123,19 +116,15 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
rec = ihex_next_binrec(rec);
}
/* De-assert reset (let the CPU run) */
err = emi26_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
msleep(250); /* let device settle */
/* 2. We upload the FPGA firmware into the EMI
@ -153,18 +142,14 @@ static int emi26_load_firmware (struct usb_device *dev)
rec = ihex_next_binrec(rec);
}
err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
} while (rec);
/* Assert reset (stop the CPU in the EMI) */
err = emi26_set_reset(dev,1);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
for (rec = (const struct ihex_binrec *)loader_fw->data;
@ -172,19 +157,15 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
}
msleep(250); /* let device settle */
/* De-assert reset (let the CPU run) */
err = emi26_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
@ -194,19 +175,15 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_EXTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
}
}
/* Assert reset (stop the CPU in the EMI) */
err = emi26_set_reset(dev,1);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
for (rec = (const struct ihex_binrec *)firmware_fw->data;
rec; rec = ihex_next_binrec(rec)) {
@ -214,19 +191,15 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
}
}
/* De-assert reset (let the CPU run) */
err = emi26_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
msleep(250); /* let device settle */
/* return 1 to fail the driver inialization
@ -234,6 +207,10 @@ static int emi26_load_firmware (struct usb_device *dev)
err = 1;
wraperr:
if (err < 0)
dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
__func__, err);
release_firmware(loader_fw);
release_firmware(bitstream_fw);
release_firmware(firmware_fw);

View File

@ -56,7 +56,7 @@ static int emi62_writememory(struct usb_device *dev, int address,
unsigned char *buffer = kmemdup(data, length, GFP_KERNEL);
if (!buffer) {
err("emi62: kmalloc(%d) failed.", length);
dev_err(&dev->dev, "kmalloc(%d) failed.\n", length);
return -ENOMEM;
}
/* Note: usb_control_msg returns negative value on error or length of the
@ -73,9 +73,8 @@ static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit)
dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit);
response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
if (response < 0) {
err("emi62: set_reset (%d) failed", reset_bit);
}
if (response < 0)
dev_err(&dev->dev, "set_reset (%d) failed\n", reset_bit);
return response;
}
@ -87,18 +86,15 @@ static int emi62_load_firmware (struct usb_device *dev)
const struct firmware *bitstream_fw = NULL;
const struct firmware *firmware_fw = NULL;
const struct ihex_binrec *rec;
int err;
int err = -ENOMEM;
int i;
__u32 addr; /* Address to write */
__u8 *buf;
dev_dbg(&dev->dev, "load_firmware\n");
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
if (!buf) {
err( "%s - error loading firmware: error = %d", __func__, -ENOMEM);
err = -ENOMEM;
if (!buf)
goto wraperr;
}
err = request_ihex_firmware(&loader_fw, "emi62/loader.fw", &dev->dev);
if (err)
@ -112,16 +108,13 @@ static int emi62_load_firmware (struct usb_device *dev)
err = request_ihex_firmware(&firmware_fw, FIRMWARE_FW, &dev->dev);
if (err) {
nofw:
err( "%s - request_firmware() failed", __func__);
goto wraperr;
}
/* Assert reset (stop the CPU in the EMI) */
err = emi62_set_reset(dev,1);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
rec = (const struct ihex_binrec *)loader_fw->data;
@ -130,19 +123,15 @@ static int emi62_load_firmware (struct usb_device *dev)
err = emi62_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
rec = ihex_next_binrec(rec);
}
/* De-assert reset (let the CPU run) */
err = emi62_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
msleep(250); /* let device settle */
/* 2. We upload the FPGA firmware into the EMI
@ -160,18 +149,14 @@ static int emi62_load_firmware (struct usb_device *dev)
rec = ihex_next_binrec(rec);
}
err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
} while (rec);
/* Assert reset (stop the CPU in the EMI) */
err = emi62_set_reset(dev,1);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
for (rec = (const struct ihex_binrec *)loader_fw->data;
@ -179,18 +164,14 @@ static int emi62_load_firmware (struct usb_device *dev)
err = emi62_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
}
/* De-assert reset (let the CPU run) */
err = emi62_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
msleep(250); /* let device settle */
/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
@ -201,19 +182,15 @@ static int emi62_load_firmware (struct usb_device *dev)
err = emi62_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_EXTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
}
}
/* Assert reset (stop the CPU in the EMI) */
err = emi62_set_reset(dev,1);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
for (rec = (const struct ihex_binrec *)firmware_fw->data;
rec; rec = ihex_next_binrec(rec)) {
@ -221,19 +198,15 @@ static int emi62_load_firmware (struct usb_device *dev)
err = emi62_writememory(dev, be32_to_cpu(rec->addr),
rec->data, be16_to_cpu(rec->len),
ANCHOR_LOAD_EXTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
}
}
/* De-assert reset (let the CPU run) */
err = emi62_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __func__, err);
if (err < 0)
goto wraperr;
}
msleep(250); /* let device settle */
release_firmware(loader_fw);
@ -247,6 +220,9 @@ static int emi62_load_firmware (struct usb_device *dev)
return 1;
wraperr:
if (err < 0)
dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
__func__, err);
release_firmware(loader_fw);
release_firmware(bitstream_fw);
release_firmware(firmware_fw);

View File

@ -366,14 +366,14 @@ static int idmouse_probe(struct usb_interface *interface,
kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
if (!dev->bulk_in_buffer) {
err("Unable to allocate input buffer.");
dev_err(&interface->dev, "Unable to allocate input buffer.\n");
idmouse_delete(dev);
return -ENOMEM;
}
}
if (!(dev->bulk_in_endpointAddr)) {
err("Unable to find bulk-in endpoint.");
dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
idmouse_delete(dev);
return -ENODEV;
}
@ -385,7 +385,7 @@ static int idmouse_probe(struct usb_interface *interface,
result = usb_register_dev(interface, &idmouse_class);
if (result) {
/* something prevented us from registering this device */
err("Unble to allocate minor number.");
dev_err(&interface->dev, "Unble to allocate minor number.\n");
usb_set_intfdata(interface, NULL);
idmouse_delete(dev);
return result;

View File

@ -610,8 +610,8 @@ static int iowarrior_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&iowarrior_driver, subminor);
if (!interface) {
mutex_unlock(&iowarrior_mutex);
err("%s - error, can't find device for minor %d", __func__,
subminor);
printk(KERN_ERR "%s - error, can't find device for minor %d\n",
__func__, subminor);
return -ENODEV;
}

View File

@ -334,8 +334,8 @@ static int ld_usb_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&ld_usb_driver, subminor);
if (!interface) {
err("%s - error, can't find device for minor %d\n",
__func__, subminor);
printk(KERN_ERR "%s - error, can't find device for minor %d\n",
__func__, subminor);
return -ENODEV;
}
@ -485,7 +485,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
goto unlock_exit;
}
@ -565,7 +565,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
goto unlock_exit;
}
@ -603,7 +603,9 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
bytes_to_write,
USB_CTRL_SET_TIMEOUT * HZ);
if (retval < 0)
err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval);
dev_err(&dev->intf->dev,
"Couldn't submit HID_REQ_SET_REPORT %d\n",
retval);
goto unlock_exit;
}
@ -624,7 +626,8 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
if (retval) {
dev->interrupt_out_busy = 0;
err("Couldn't submit interrupt_out_urb %d\n", retval);
dev_err(&dev->intf->dev,
"Couldn't submit interrupt_out_urb %d\n", retval);
goto unlock_exit;
}
retval = bytes_to_write;

View File

@ -354,8 +354,8 @@ static int tower_open (struct inode *inode, struct file *file)
interface = usb_find_interface (&tower_driver, subminor);
if (!interface) {
err ("%s - error, can't find device for minor %d",
__func__, subminor);
printk(KERN_ERR "%s - error, can't find device for minor %d\n",
__func__, subminor);
retval = -ENODEV;
goto exit;
}
@ -397,7 +397,8 @@ static int tower_open (struct inode *inode, struct file *file)
sizeof(reset_reply),
1000);
if (result < 0) {
err("LEGO USB Tower reset control request failed");
dev_err(&dev->udev->dev,
"LEGO USB Tower reset control request failed\n");
retval = result;
goto unlock_exit;
}
@ -420,7 +421,8 @@ static int tower_open (struct inode *inode, struct file *file)
retval = usb_submit_urb (dev->interrupt_in_urb, GFP_KERNEL);
if (retval) {
err("Couldn't submit interrupt_in_urb %d", retval);
dev_err(&dev->udev->dev,
"Couldn't submit interrupt_in_urb %d\n", retval);
dev->interrupt_in_running = 0;
dev->open_count = 0;
goto unlock_exit;
@ -608,7 +610,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count,
/* verify that the device wasn't unplugged */
if (dev->udev == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d", retval);
printk(KERN_ERR "legousbtower: No device or device unplugged %d\n", retval);
goto unlock_exit;
}
@ -697,7 +699,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
/* verify that the device wasn't unplugged */
if (dev->udev == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d", retval);
printk(KERN_ERR "legousbtower: No device or device unplugged %d\n", retval);
goto unlock_exit;
}
@ -744,7 +746,8 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
retval = usb_submit_urb (dev->interrupt_out_urb, GFP_KERNEL);
if (retval) {
dev->interrupt_out_busy = 0;
err("Couldn't submit interrupt_out_urb %d", retval);
dev_err(&dev->udev->dev,
"Couldn't submit interrupt_out_urb %d\n", retval);
goto unlock_exit;
}
retval = bytes_to_write;
@ -803,9 +806,10 @@ static void tower_interrupt_in_callback (struct urb *urb)
/* resubmit if we're still running */
if (dev->interrupt_in_running && dev->udev) {
retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC);
if (retval) {
err("%s: usb_submit_urb failed (%d)", __func__, retval);
}
if (retval)
dev_err(&dev->udev->dev,
"%s: usb_submit_urb failed (%d)\n",
__func__, retval);
}
exit:
@ -852,6 +856,7 @@ static void tower_interrupt_out_callback (struct urb *urb)
*/
static int tower_probe (struct usb_interface *interface, const struct usb_device_id *id)
{
struct device *idev = &interface->dev;
struct usb_device *udev = interface_to_usbdev(interface);
struct lego_usb_tower *dev = NULL;
struct usb_host_interface *iface_desc;
@ -871,7 +876,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
if (dev == NULL) {
err ("Out of memory");
dev_err(idev, "Out of memory\n");
goto exit;
}
@ -915,37 +920,37 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
}
}
if(dev->interrupt_in_endpoint == NULL) {
err("interrupt in endpoint not found");
dev_err(idev, "interrupt in endpoint not found\n");
goto error;
}
if (dev->interrupt_out_endpoint == NULL) {
err("interrupt out endpoint not found");
dev_err(idev, "interrupt out endpoint not found\n");
goto error;
}
dev->read_buffer = kmalloc (read_buffer_size, GFP_KERNEL);
if (!dev->read_buffer) {
err("Couldn't allocate read_buffer");
dev_err(idev, "Couldn't allocate read_buffer\n");
goto error;
}
dev->interrupt_in_buffer = kmalloc (usb_endpoint_maxp(dev->interrupt_in_endpoint), GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
err("Couldn't allocate interrupt_in_buffer");
dev_err(idev, "Couldn't allocate interrupt_in_buffer\n");
goto error;
}
dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->interrupt_in_urb) {
err("Couldn't allocate interrupt_in_urb");
dev_err(idev, "Couldn't allocate interrupt_in_urb\n");
goto error;
}
dev->interrupt_out_buffer = kmalloc (write_buffer_size, GFP_KERNEL);
if (!dev->interrupt_out_buffer) {
err("Couldn't allocate interrupt_out_buffer");
dev_err(idev, "Couldn't allocate interrupt_out_buffer\n");
goto error;
}
dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->interrupt_out_urb) {
err("Couldn't allocate interrupt_out_urb");
dev_err(idev, "Couldn't allocate interrupt_out_urb\n");
goto error;
}
dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
@ -958,7 +963,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
if (retval) {
/* something prevented us from registering this driver */
err ("Not able to get a minor for this device.");
dev_err(idev, "Not able to get a minor for this device.\n");
usb_set_intfdata (interface, NULL);
goto error;
}
@ -980,7 +985,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
sizeof(get_version_reply),
1000);
if (result < 0) {
err("LEGO USB Tower get version control request failed");
dev_err(idev, "LEGO USB Tower get version control request failed\n");
retval = result;
goto error;
}

View File

@ -171,7 +171,9 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
if (result == -ETIMEDOUT)
retries--;
else if (result < 0) {
err("Error executing ioctrl. code = %d", result);
dev_err(&rio->rio_dev->dev,
"Error executing ioctrl. code = %d\n",
result);
retries = 0;
} else {
dbg("Executed ioctl. Result = %d (data=%02x)",
@ -238,7 +240,9 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
if (result == -ETIMEDOUT)
retries--;
else if (result < 0) {
err("Error executing ioctrl. code = %d", result);
dev_err(&rio->rio_dev->dev,
"Error executing ioctrl. code = %d\n",
result);
retries = 0;
} else {
dbg("Executed ioctl. Result = %d", result);
@ -332,7 +336,8 @@ write_rio(struct file *file, const char __user *buffer,
break;
};
if (result) {
err("Write Whoops - %x", result);
dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n",
result);
errn = -EIO;
goto error;
}
@ -401,7 +406,8 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
} else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
if (!maxretry--) {
mutex_unlock(&(rio->lock));
err("read_rio: maxretry timeout");
dev_err(&rio->rio_dev->dev,
"read_rio: maxretry timeout\n");
return -ETIME;
}
prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
@ -410,8 +416,9 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
continue;
} else if (result != -EREMOTEIO) {
mutex_unlock(&(rio->lock));
err("Read Whoops - result:%u partial:%u this_read:%u",
result, partial, this_read);
dev_err(&rio->rio_dev->dev,
"Read Whoops - result:%u partial:%u this_read:%u\n",
result, partial, this_read);
return -EIO;
} else {
mutex_unlock(&(rio->lock));
@ -459,21 +466,24 @@ static int probe_rio(struct usb_interface *intf,
retval = usb_register_dev(intf, &usb_rio_class);
if (retval) {
err("Not able to get a minor for this device.");
dev_err(&dev->dev,
"Not able to get a minor for this device.\n");
return -ENOMEM;
}
rio->rio_dev = dev;
if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
err("probe_rio: Not enough memory for the output buffer");
dev_err(&dev->dev,
"probe_rio: Not enough memory for the output buffer\n");
usb_deregister_dev(intf, &usb_rio_class);
return -ENOMEM;
}
dbg("probe_rio: obuf address:%p", rio->obuf);
if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
err("probe_rio: Not enough memory for the input buffer");
dev_err(&dev->dev,
"probe_rio: Not enough memory for the input buffer\n");
usb_deregister_dev(intf, &usb_rio_class);
kfree(rio->obuf);
return -ENOMEM;

View File

@ -87,8 +87,8 @@ static int lcd_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&lcd_driver, subminor);
if (!interface) {
mutex_unlock(&lcd_mutex);
err("USBLCD: %s - error, can't find device for minor %d",
__func__, subminor);
printk(KERN_ERR "USBLCD: %s - error, can't find device for minor %d\n",
__func__, subminor);
return -ENODEV;
}
@ -268,8 +268,9 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer,
/* send the data out the bulk port */
retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval) {
err("USBLCD: %s - failed submitting write urb, error %d",
__func__, retval);
dev_err(&dev->udev->dev,
"%s - failed submitting write urb, error %d\n",
__func__, retval);
goto error_unanchor;
}
@ -322,7 +323,7 @@ static int lcd_probe(struct usb_interface *interface,
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
err("Out of memory");
dev_err(&interface->dev, "Out of memory\n");
goto error;
}
kref_init(&dev->kref);
@ -352,7 +353,8 @@ static int lcd_probe(struct usb_interface *interface,
dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!dev->bulk_in_buffer) {
err("Could not allocate bulk_in_buffer");
dev_err(&interface->dev,
"Could not allocate bulk_in_buffer\n");
goto error;
}
}
@ -364,7 +366,8 @@ static int lcd_probe(struct usb_interface *interface,
}
}
if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
err("Could not find both bulk-in and bulk-out endpoints");
dev_err(&interface->dev,
"Could not find both bulk-in and bulk-out endpoints\n");
goto error;
}
@ -375,7 +378,8 @@ static int lcd_probe(struct usb_interface *interface,
retval = usb_register_dev(interface, &lcd_class);
if (retval) {
/* something prevented us from registering this driver */
err("Not able to get a minor for this device.");
dev_err(&interface->dev,
"Not able to get a minor for this device.\n");
usb_set_intfdata(interface, NULL);
goto error;
}

View File

@ -118,7 +118,8 @@ static void async_complete(struct urb *urb)
priv = rq->priv;
pp = priv->pp;
if (status) {
err("async_complete: urb error %d", status);
dev_err(&urb->dev->dev, "async_complete: urb error %d\n",
status);
} else if (rq->dr.bRequest == 3) {
memcpy(priv->reg, rq->reg, sizeof(priv->reg));
#if 0
@ -151,7 +152,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
return NULL;
rq = kmalloc(sizeof(struct uss720_async_request), mem_flags);
if (!rq) {
err("submit_async_request out of memory");
dev_err(&usbdev->dev, "submit_async_request out of memory\n");
return NULL;
}
kref_init(&rq->ref_count);
@ -162,7 +163,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
rq->urb = usb_alloc_urb(0, mem_flags);
if (!rq->urb) {
kref_put(&rq->ref_count, destroy_async);
err("submit_async_request out of memory");
dev_err(&usbdev->dev, "submit_async_request out of memory\n");
return NULL;
}
rq->dr.bRequestType = requesttype;
@ -182,7 +183,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
if (!ret)
return rq;
destroy_async(&rq->ref_count);
err("submit_async_request submit_urb failed with %d", ret);
dev_err(&usbdev->dev, "submit_async_request submit_urb failed with %d\n", ret);
return NULL;
}
@ -217,7 +218,8 @@ static int get_1284_register(struct parport *pp, unsigned char reg, unsigned cha
priv = pp->private_data;
rq = submit_async_request(priv, 3, 0xc0, ((unsigned int)reg) << 8, 0, mem_flags);
if (!rq) {
err("get_1284_register(%u) failed", (unsigned int)reg);
dev_err(&priv->usbdev->dev, "get_1284_register(%u) failed",
(unsigned int)reg);
return -EIO;
}
if (!val) {
@ -248,7 +250,8 @@ static int set_1284_register(struct parport *pp, unsigned char reg, unsigned cha
priv = pp->private_data;
rq = submit_async_request(priv, 4, 0x40, (((unsigned int)reg) << 8) | val, 0, mem_flags);
if (!rq) {
err("set_1284_register(%u,%u) failed", (unsigned int)reg, (unsigned int)val);
dev_err(&priv->usbdev->dev, "set_1284_register(%u,%u) failed",
(unsigned int)reg, (unsigned int)val);
return -EIO;
}
kref_put(&rq->ref_count, destroy_async);

View File

@ -83,7 +83,8 @@ static void yurex_control_callback(struct urb *urb)
int status = urb->status;
if (status) {
err("%s - control failed: %d\n", __func__, status);
dev_err(&urb->dev->dev, "%s - control failed: %d\n",
__func__, status);
wake_up_interruptible(&dev->waitq);
return;
}
@ -137,8 +138,9 @@ static void yurex_interrupt(struct urb *urb)
case 0: /*success*/
break;
case -EOVERFLOW:
err("%s - overflow with length %d, actual length is %d",
__func__, YUREX_BUF_SIZE, dev->urb->actual_length);
dev_err(&dev->interface->dev,
"%s - overflow with length %d, actual length is %d\n",
__func__, YUREX_BUF_SIZE, dev->urb->actual_length);
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
@ -146,7 +148,8 @@ static void yurex_interrupt(struct urb *urb)
/* The device is terminated, clean up */
return;
default:
err("%s - unknown status received: %d", __func__, status);
dev_err(&dev->interface->dev,
"%s - unknown status received: %d\n", __func__, status);
goto exit;
}
@ -179,7 +182,7 @@ static void yurex_interrupt(struct urb *urb)
exit:
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
if (retval) {
err("%s - usb_submit_urb failed: %d",
dev_err(&dev->interface->dev, "%s - usb_submit_urb failed: %d\n",
__func__, retval);
}
}
@ -196,7 +199,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
err("Out of memory");
dev_err(&interface->dev, "Out of memory\n");
goto error;
}
kref_init(&dev->kref);
@ -219,7 +222,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
}
if (!dev->int_in_endpointAddr) {
retval = -ENODEV;
err("Could not find endpoints");
dev_err(&interface->dev, "Could not find endpoints\n");
goto error;
}
@ -227,14 +230,14 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
/* allocate control URB */
dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->cntl_urb) {
err("Could not allocate control URB");
dev_err(&interface->dev, "Could not allocate control URB\n");
goto error;
}
/* allocate buffer for control req */
dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
if (!dev->cntl_req) {
err("Could not allocate cntl_req");
dev_err(&interface->dev, "Could not allocate cntl_req\n");
goto error;
}
@ -243,7 +246,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
GFP_KERNEL,
&dev->cntl_urb->transfer_dma);
if (!dev->cntl_buffer) {
err("Could not allocate cntl_buffer");
dev_err(&interface->dev, "Could not allocate cntl_buffer\n");
goto error;
}
@ -265,7 +268,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
/* allocate interrupt URB */
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->urb) {
err("Could not allocate URB");
dev_err(&interface->dev, "Could not allocate URB\n");
goto error;
}
@ -273,7 +276,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
GFP_KERNEL, &dev->urb->transfer_dma);
if (!dev->int_buffer) {
err("Could not allocate int_buffer");
dev_err(&interface->dev, "Could not allocate int_buffer\n");
goto error;
}
@ -285,7 +288,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
retval = -EIO;
err("Could not submitting URB");
dev_err(&interface->dev, "Could not submitting URB\n");
goto error;
}
@ -295,7 +298,8 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
/* we can register the device now, as it is ready */
retval = usb_register_dev(interface, &yurex_class);
if (retval) {
err("Not able to get a minor for this device.");
dev_err(&interface->dev,
"Not able to get a minor for this device.\n");
usb_set_intfdata(interface, NULL);
goto error;
}
@ -368,8 +372,8 @@ static int yurex_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&yurex_driver, subminor);
if (!interface) {
err("%s - error, can't find device for minor %d",
__func__, subminor);
printk(KERN_ERR "%s - error, can't find device for minor %d",
__func__, subminor);
retval = -ENODEV;
goto exit;
}
@ -514,7 +518,9 @@ static ssize_t yurex_write(struct file *file, const char *user_buffer, size_t co
mutex_unlock(&dev->io_mutex);
if (retval < 0) {
err("%s - failed to send bulk msg, error %d", __func__, retval);
dev_err(&dev->interface->dev,
"%s - failed to send bulk msg, error %d\n",
__func__, retval);
goto error;
}
if (set && timeout)

View File

@ -113,7 +113,8 @@ static int usb_console_setup(struct console *co, char *options)
serial = usb_serial_get_by_index(co->index);
if (serial == NULL) {
/* no device is connected yet, sorry :( */
err("No USB device connected to ttyUSB%i", co->index);
printk(KERN_ERR "No USB device connected to ttyUSB%i\n",
co->index);
return -ENODEV;
}
@ -137,7 +138,7 @@ static int usb_console_setup(struct console *co, char *options)
tty = kzalloc(sizeof(*tty), GFP_KERNEL);
if (!tty) {
retval = -ENOMEM;
err("no more memory");
dev_err(&port->dev, "no more memory\n");
goto reset_open_count;
}
kref_init(&tty->kref);
@ -146,7 +147,7 @@ static int usb_console_setup(struct console *co, char *options)
tty->index = co->index;
if (tty_init_termios(tty)) {
retval = -ENOMEM;
err("no more memory");
dev_err(&port->dev, "no more memory\n");
goto free_tty;
}
}
@ -159,7 +160,7 @@ static int usb_console_setup(struct console *co, char *options)
retval = usb_serial_generic_open(NULL, port);
if (retval) {
err("could not open USB console port");
dev_err(&port->dev, "could not open USB console port\n");
goto fail;
}

View File

@ -547,6 +547,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
{
int baud_rate;
struct tty_struct *tty = tty_port_tty_get(&port->port->port);
struct usb_serial *serial = port->port->serial;
wait_queue_t wait;
unsigned long flags;
@ -561,7 +562,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
set_current_state(TASK_INTERRUPTIBLE);
if (kfifo_len(&port->write_fifo) == 0
|| timeout == 0 || signal_pending(current)
|| !usb_get_intfdata(port->port->serial->interface))
|| serial->disconnected)
/* disconnect */
break;
spin_unlock_irqrestore(&port->ep_lock, flags);
@ -578,7 +579,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
/* wait for data to drain from the device */
timeout += jiffies;
while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
&& usb_get_intfdata(port->port->serial->interface)) {
&& !serial->disconnected) {
/* not disconnected */
if (!tx_active(port))
break;
@ -586,7 +587,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
}
/* disconnected */
if (!usb_get_intfdata(port->port->serial->interface))
if (serial->disconnected)
return;
/* wait one more character time, based on baud rate */
@ -2003,8 +2004,8 @@ static void edge_close(struct usb_serial_port *port)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
struct usb_serial *serial = port->serial;
int port_number;
int status;
dbg("%s - port %d", __func__, port->number);
@ -2028,12 +2029,18 @@ static void edge_close(struct usb_serial_port *port)
* send a close port command to it */
dbg("%s - send umpc_close_port", __func__);
port_number = port->number - port->serial->minor;
status = send_cmd(port->serial->dev,
mutex_lock(&serial->disc_mutex);
if (!serial->disconnected) {
send_cmd(serial->dev,
UMPC_CLOSE_PORT,
(__u8)(UMPM_UART1_PORT + port_number),
0,
NULL,
0);
}
mutex_unlock(&serial->disc_mutex);
mutex_lock(&edge_serial->es_lock);
--edge_port->edge_serial->num_ports_open;
if (edge_port->edge_serial->num_ports_open <= 0) {

View File

@ -33,7 +33,6 @@
#define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
#define DRIVER_DESC "USB PocketPC PDA driver"
static __u16 product, vendor;
static bool debug;
static int connect_retries = KP_RETRIES;
static int initial_wait;
@ -45,8 +44,6 @@ static int ipaq_calc_num_ports(struct usb_serial *serial);
static int ipaq_startup(struct usb_serial *serial);
static struct usb_device_id ipaq_id_table [] = {
/* The first entry is a placeholder for the insmod-specified device */
{ USB_DEVICE(0x049F, 0x0003) },
{ USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
{ USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */
{ USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */
@ -623,30 +620,7 @@ static int ipaq_startup(struct usb_serial *serial)
return usb_reset_configuration(serial->dev);
}
static int __init ipaq_init(void)
{
int retval;
if (vendor) {
ipaq_id_table[0].idVendor = vendor;
ipaq_id_table[0].idProduct = product;
}
retval = usb_serial_register_drivers(&ipaq_driver, serial_drivers);
if (retval == 0)
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
DRIVER_DESC "\n");
return retval;
}
static void __exit ipaq_exit(void)
{
usb_serial_deregister_drivers(&ipaq_driver, serial_drivers);
}
module_init(ipaq_init);
module_exit(ipaq_exit);
module_usb_serial_driver(ipaq_driver, serial_drivers);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@ -655,12 +629,6 @@ MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(vendor, ushort, 0);
MODULE_PARM_DESC(vendor, "User specified USB idVendor");
module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified USB idProduct");
module_param(connect_retries, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(connect_retries,
"Maximum number of connect retries (one second each)");

View File

@ -17,7 +17,6 @@
#include <linux/tty_flip.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/uaccess.h>
#include <linux/usb/serial.h>
@ -56,6 +55,47 @@ MODULE_DEVICE_TABLE(usb, id_table);
/* Input parameter constants. */
static bool debug;
/* UNI-Directional mode commands for device configure */
#define UNI_CMD_OPEN 0x80
#define UNI_CMD_CLOSE 0xFF
inline int metrousb_is_unidirectional_mode(struct usb_serial_port *port)
{
__u16 product_id = le16_to_cpu(
port->serial->dev->descriptor.idProduct);
return product_id == FOCUS_PRODUCT_ID_UNI;
}
static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port)
{
int ret;
int actual_len;
u8 *buffer_cmd = NULL;
if (!metrousb_is_unidirectional_mode(port))
return 0;
buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL);
if (!buffer_cmd)
return -ENOMEM;
*buffer_cmd = cmd;
ret = usb_interrupt_msg(port->serial->dev,
usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
buffer_cmd, sizeof(cmd),
&actual_len, USB_CTRL_SET_TIMEOUT);
kfree(buffer_cmd);
if (ret < 0)
return ret;
else if (actual_len != sizeof(cmd))
return -EIO;
return 0;
}
static void metrousb_read_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
@ -78,12 +118,12 @@ static void metrousb_read_int_callback(struct urb *urb)
/* urb has been terminated. */
dev_dbg(&port->dev,
"%s - urb shutting down, error code=%d\n",
__func__, result);
__func__, urb->status);
return;
default:
dev_dbg(&port->dev,
"%s - non-zero urb received, error code=%d\n",
__func__, result);
__func__, urb->status);
goto exit;
}
@ -91,7 +131,7 @@ static void metrousb_read_int_callback(struct urb *urb)
/* Set the data read from the usb port into the serial port buffer. */
tty = tty_port_tty_get(&port->port);
if (!tty) {
dev_dbg(&port->dev, "%s - bad tty pointer - exiting\n",
dev_err(&port->dev, "%s - bad tty pointer - exiting\n",
__func__);
return;
}
@ -121,7 +161,7 @@ static void metrousb_read_int_callback(struct urb *urb)
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
dev_dbg(&port->dev,
dev_err(&port->dev,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
}
@ -131,11 +171,19 @@ static void metrousb_read_int_callback(struct urb *urb)
/* Try to resubmit the urb. */
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
dev_dbg(&port->dev,
dev_err(&port->dev,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
}
static void metrousb_write_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
dev_warn(&port->dev, "%s not implemented yet.\n",
__func__);
}
static void metrousb_cleanup(struct usb_serial_port *port)
{
dev_dbg(&port->dev, "%s\n", __func__);
@ -146,6 +194,9 @@ static void metrousb_cleanup(struct usb_serial_port *port)
usb_unlink_urb(port->interrupt_in_urb);
usb_kill_urb(port->interrupt_in_urb);
}
/* Send deactivate cmd to device */
metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
}
}
@ -160,7 +211,7 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
/* Make sure the urb is initialized. */
if (!port->interrupt_in_urb) {
dev_dbg(&port->dev, "%s - interrupt urb not initialized\n",
dev_err(&port->dev, "%s - interrupt urb not initialized\n",
__func__);
return -ENODEV;
}
@ -191,12 +242,21 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result) {
dev_dbg(&port->dev,
dev_err(&port->dev,
"%s - failed submitting interrupt in urb, error code=%d\n",
__func__, result);
goto exit;
}
/* Send activate cmd to device */
result = metrousb_send_unidirectional_cmd(UNI_CMD_OPEN, port);
if (result) {
dev_err(&port->dev,
"%s - failed to configure device for port number=%d, error code=%d\n",
__func__, port->number, result);
goto exit;
}
dev_dbg(&port->dev, "%s - port open\n", __func__);
exit:
return result;
@ -221,7 +281,7 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr
METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST,
control_state, 0, NULL, 0, WDR_TIMEOUT);
if (retval < 0)
dev_dbg(&serial->dev->dev,
dev_err(&serial->dev->dev,
"%s - set modem ctrl=0x%x failed, error code=%d\n",
__func__, mcr, retval);
@ -354,7 +414,7 @@ static void metrousb_unthrottle(struct tty_struct *tty)
port->interrupt_in_urb->dev = port->serial->dev;
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
dev_dbg(tty->dev,
dev_err(tty->dev,
"failed submitting interrupt in urb error code=%d\n",
result);
}
@ -371,12 +431,13 @@ static struct usb_serial_driver metrousb_device = {
.owner = THIS_MODULE,
.name = "metro-usb",
},
.description = "Metrologic USB to serial converter.",
.description = "Metrologic USB to Serial",
.id_table = id_table,
.num_ports = 1,
.open = metrousb_open,
.close = metrousb_cleanup,
.read_int_callback = metrousb_read_int_callback,
.write_int_callback = metrousb_write_int_callback,
.attach = metrousb_startup,
.release = metrousb_shutdown,
.throttle = metrousb_throttle,

View File

@ -114,6 +114,7 @@
#define USB_VENDOR_ID_MOSCHIP 0x9710
#define MOSCHIP_DEVICE_ID_7840 0x7840
#define MOSCHIP_DEVICE_ID_7820 0x7820
#define MOSCHIP_DEVICE_ID_7810 0x7810
/* The native component can have its vendor/device id's overridden
* in vendor-specific implementations. Such devices can be handled
* by making a change here, in moschip_port_id_table, and in
@ -184,10 +185,16 @@
#define NUM_URBS 16 /* URB Count */
#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
/* LED on/off milliseconds*/
#define LED_ON_MS 500
#define LED_OFF_MS 500
static int device_type;
static const struct usb_device_id moschip_port_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@ -209,6 +216,7 @@ static const struct usb_device_id moschip_port_id_table[] = {
static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@ -261,8 +269,13 @@ struct moschip_port {
struct urb *write_urb_pool[NUM_URBS];
char busy[NUM_URBS];
bool read_urb_busy;
};
/* For device(s) with LED indicator */
bool has_led;
bool led_flag;
struct timer_list led_timer1; /* Timer for LED on */
struct timer_list led_timer2; /* Timer for LED off */
};
static bool debug;
@ -572,6 +585,69 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
return ret;
}
static void mos7840_set_led_callback(struct urb *urb)
{
switch (urb->status) {
case 0:
/* Success */
break;
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* This urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d", __func__,
urb->status);
break;
default:
dbg("%s - nonzero urb status received: %d", __func__,
urb->status);
}
}
static void mos7840_set_led_async(struct moschip_port *mcs, __u16 wval,
__u16 reg)
{
struct usb_device *dev = mcs->port->serial->dev;
struct usb_ctrlrequest *dr = mcs->dr;
dr->bRequestType = MCS_WR_RTYPE;
dr->bRequest = MCS_WRREQ;
dr->wValue = cpu_to_le16(wval);
dr->wIndex = cpu_to_le16(reg);
dr->wLength = cpu_to_le16(0);
usb_fill_control_urb(mcs->control_urb, dev, usb_sndctrlpipe(dev, 0),
(unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL);
usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
}
static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg,
__u16 val)
{
struct usb_device *dev = port->serial->dev;
usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, MCS_WR_RTYPE,
val, reg, NULL, 0, MOS_WDR_TIMEOUT);
}
static void mos7840_led_off(unsigned long arg)
{
struct moschip_port *mcs = (struct moschip_port *) arg;
/* Turn off LED */
mos7840_set_led_async(mcs, 0x0300, MODEM_CONTROL_REGISTER);
mod_timer(&mcs->led_timer2,
jiffies + msecs_to_jiffies(LED_OFF_MS));
}
static void mos7840_led_flag_off(unsigned long arg)
{
struct moschip_port *mcs = (struct moschip_port *) arg;
mcs->led_flag = false;
}
/*****************************************************************************
* mos7840_interrupt_callback
* this is the callback function for when we have received data on the
@ -792,6 +868,14 @@ static void mos7840_bulk_in_callback(struct urb *urb)
return;
}
/* Turn on LED */
if (mos7840_port->has_led && !mos7840_port->led_flag) {
mos7840_port->led_flag = true;
mos7840_set_led_async(mos7840_port, 0x0301,
MODEM_CONTROL_REGISTER);
mod_timer(&mos7840_port->led_timer1,
jiffies + msecs_to_jiffies(LED_ON_MS));
}
mos7840_port->read_urb_busy = true;
retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
@ -1554,6 +1638,14 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
data1 = urb->transfer_buffer;
dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
/* Turn on LED */
if (mos7840_port->has_led && !mos7840_port->led_flag) {
mos7840_port->led_flag = true;
mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0301);
mod_timer(&mos7840_port->led_timer1,
jiffies + msecs_to_jiffies(LED_ON_MS));
}
/* send it down the pipe */
status = usb_submit_urb(urb, GFP_ATOMIC);
@ -2327,28 +2419,74 @@ static int mos7840_ioctl(struct tty_struct *tty,
return -ENOIOCTLCMD;
}
static int mos7810_check(struct usb_serial *serial)
{
int i, pass_count = 0;
__u16 data = 0, mcr_data = 0;
__u16 test_pattern = 0x55AA;
/* Store MCR setting */
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
&mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
for (i = 0; i < 16; i++) {
/* Send the 1-bit test pattern out to MCS7810 test pin */
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
MCS_WRREQ, MCS_WR_RTYPE,
(0x0300 | (((test_pattern >> i) & 0x0001) << 1)),
MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
/* Read the test pattern back */
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
/* If this is a MCS7810 device, both test patterns must match */
if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
break;
pass_count++;
}
/* Restore MCR setting */
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCS_WRREQ,
MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
0, MOS_WDR_TIMEOUT);
if (pass_count == 16)
return 1;
return 0;
}
static int mos7840_calc_num_ports(struct usb_serial *serial)
{
__u16 Data = 0x00;
int ret = 0;
__u16 data = 0x00;
int mos7840_num_ports;
ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data,
usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
if ((Data & 0x01) == 0) {
mos7840_num_ports = 2;
serial->num_bulk_in = 2;
serial->num_bulk_out = 2;
serial->num_ports = 2;
if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
device_type = serial->dev->descriptor.idProduct;
} else {
mos7840_num_ports = 4;
serial->num_bulk_in = 4;
serial->num_bulk_out = 4;
serial->num_ports = 4;
/* For a MCS7840 device GPIO0 must be set to 1 */
if ((data & 0x01) == 1)
device_type = MOSCHIP_DEVICE_ID_7840;
else if (mos7810_check(serial))
device_type = MOSCHIP_DEVICE_ID_7810;
else
device_type = MOSCHIP_DEVICE_ID_7820;
}
mos7840_num_ports = (device_type >> 4) & 0x000F;
serial->num_bulk_in = mos7840_num_ports;
serial->num_bulk_out = mos7840_num_ports;
serial->num_ports = mos7840_num_ports;
return mos7840_num_ports;
}
@ -2563,6 +2701,34 @@ static int mos7840_startup(struct usb_serial *serial)
status = -ENOMEM;
goto error;
}
mos7840_port->has_led = false;
/* Initialize LED timers */
if (device_type == MOSCHIP_DEVICE_ID_7810) {
mos7840_port->has_led = true;
init_timer(&mos7840_port->led_timer1);
mos7840_port->led_timer1.function = mos7840_led_off;
mos7840_port->led_timer1.expires =
jiffies + msecs_to_jiffies(LED_ON_MS);
mos7840_port->led_timer1.data =
(unsigned long)mos7840_port;
init_timer(&mos7840_port->led_timer2);
mos7840_port->led_timer2.function =
mos7840_led_flag_off;
mos7840_port->led_timer2.expires =
jiffies + msecs_to_jiffies(LED_OFF_MS);
mos7840_port->led_timer2.data =
(unsigned long)mos7840_port;
mos7840_port->led_flag = false;
/* Turn off LED */
mos7840_set_led_sync(serial->port[i],
MODEM_CONTROL_REGISTER, 0x0300);
}
}
dbg ("mos7840_startup: all ports configured...........");
@ -2654,6 +2820,14 @@ static void mos7840_release(struct usb_serial *serial)
mos7840_port = mos7840_get_port_private(serial->port[i]);
dbg("mos7840_port %d = %p", i, mos7840_port);
if (mos7840_port) {
if (mos7840_port->has_led) {
/* Turn off LED */
mos7840_set_led_sync(mos7840_port->port,
MODEM_CONTROL_REGISTER, 0x0300);
del_timer_sync(&mos7840_port->led_timer1);
del_timer_sync(&mos7840_port->led_timer2);
}
kfree(mos7840_port->ctrl_buf);
kfree(mos7840_port->dr);
kfree(mos7840_port);

View File

@ -1413,7 +1413,7 @@ static void option_instat_callback(struct urb *urb)
req_pkt->bRequestType, req_pkt->bRequest);
}
} else
err("%s: error %d", __func__, status);
dev_err(&port->dev, "%s: error %d\n", __func__, status);
/* Resubmit urb so we continue receiving IRQ data */
if (status != -ESHUTDOWN && status != -ENOENT) {

View File

@ -394,7 +394,9 @@ static int ti_startup(struct usb_serial *serial)
/* if we have only 1 configuration, download firmware */
if (dev->descriptor.bNumConfigurations == 1) {
if ((status = ti_download_firmware(tdev)) != 0)
status = ti_download_firmware(tdev);
if (status != 0)
goto free_tdev;
/* 3410 must be reset, 5052 resets itself */
@ -1683,7 +1685,9 @@ static int ti_download_firmware(struct ti_device *tdev)
/* try ID specific firmware first, then try generic firmware */
sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
dev->descriptor.idProduct);
if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) {
status = request_firmware(&fw_p, buf, &dev->dev);
if (status != 0) {
buf[0] = '\0';
if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
switch (dev->descriptor.idProduct) {

View File

@ -725,8 +725,8 @@ int usb_wwan_resume(struct usb_serial *serial)
err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
dbg("Submitted interrupt URB for port %d (result %d)", i, err);
if (err < 0) {
err("%s: Error %d for interrupt URB of port%d",
__func__, err, i);
dev_err(&port->dev, "%s: Error %d for interrupt URB\n",
__func__, err);
goto err_out;
}
}
@ -747,8 +747,8 @@ int usb_wwan_resume(struct usb_serial *serial)
urb = portdata->in_urbs[j];
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
err("%s: Error %d for bulk URB %d",
__func__, err, i);
dev_err(&port->dev, "%s: Error %d for bulk URB %d\n",
__func__, err, i);
spin_unlock_irq(&intfdata->susp_lock);
goto err_out;
}

View File

@ -53,8 +53,6 @@ static int palm_os_4_probe(struct usb_serial *serial,
/* Parameters that may be passed into the module. */
static bool debug;
static __u16 vendor;
static __u16 product;
static struct usb_device_id id_table [] = {
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
@ -115,14 +113,12 @@ static struct usb_device_id id_table [] = {
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ }, /* optional parameter entry */
{ } /* Terminating entry */
};
static struct usb_device_id clie_id_5_table [] = {
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ }, /* optional parameter entry */
{ } /* Terminating entry */
};
@ -162,7 +158,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) },
{ }, /* optional parameter entry */
{ } /* Terminating entry */
};
@ -648,59 +643,7 @@ static int clie_5_attach(struct usb_serial *serial)
return 0;
}
static int __init visor_init(void)
{
int i, retval;
/* Only if parameters were passed to us */
if (vendor > 0 && product > 0) {
struct usb_device_id usb_dev_temp[] = {
{
USB_DEVICE(vendor, product),
.driver_info =
(kernel_ulong_t) &palm_os_4_probe
}
};
/* Find the last entry in id_table */
for (i = 0;; i++) {
if (id_table[i].idVendor == 0) {
id_table[i] = usb_dev_temp[0];
break;
}
}
/* Find the last entry in id_table_combined */
for (i = 0;; i++) {
if (id_table_combined[i].idVendor == 0) {
id_table_combined[i] = usb_dev_temp[0];
break;
}
}
printk(KERN_INFO KBUILD_MODNAME
": Untested USB device specified at time of module insertion\n");
printk(KERN_INFO KBUILD_MODNAME
": Warning: This is not guaranteed to work\n");
printk(KERN_INFO KBUILD_MODNAME
": Using a newer kernel is preferred to this method\n");
printk(KERN_INFO KBUILD_MODNAME
": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n",
vendor, product);
}
retval = usb_serial_register_drivers(&visor_driver, serial_drivers);
if (retval == 0)
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
return retval;
}
static void __exit visor_exit (void)
{
usb_serial_deregister_drivers(&visor_driver, serial_drivers);
}
module_init(visor_init);
module_exit(visor_exit);
module_usb_serial_driver(visor_driver, serial_drivers);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@ -708,9 +651,3 @@ MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(vendor, ushort, 0);
MODULE_PARM_DESC(vendor, "User specified vendor ID");
module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified product ID");

View File

@ -45,7 +45,6 @@ static bool debug;
/*
* Version Information
*/
#define DRIVER_VERSION "v2.0"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Stuart MacDonald <stuartm@connecttech.com>"
#define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
@ -96,10 +95,6 @@ static void whiteheat_release(struct usb_serial *serial);
static int whiteheat_open(struct tty_struct *tty,
struct usb_serial_port *port);
static void whiteheat_close(struct usb_serial_port *port);
static int whiteheat_write(struct tty_struct *tty,
struct usb_serial_port *port,
const unsigned char *buf, int count);
static int whiteheat_write_room(struct tty_struct *tty);
static int whiteheat_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
static void whiteheat_set_termios(struct tty_struct *tty,
@ -108,11 +103,6 @@ static int whiteheat_tiocmget(struct tty_struct *tty);
static int whiteheat_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
static int whiteheat_chars_in_buffer(struct tty_struct *tty);
static void whiteheat_throttle(struct tty_struct *tty);
static void whiteheat_unthrottle(struct tty_struct *tty);
static void whiteheat_read_callback(struct urb *urb);
static void whiteheat_write_callback(struct urb *urb);
static struct usb_serial_driver whiteheat_fake_device = {
.driver = {
@ -138,18 +128,13 @@ static struct usb_serial_driver whiteheat_device = {
.release = whiteheat_release,
.open = whiteheat_open,
.close = whiteheat_close,
.write = whiteheat_write,
.write_room = whiteheat_write_room,
.ioctl = whiteheat_ioctl,
.set_termios = whiteheat_set_termios,
.break_ctl = whiteheat_break_ctl,
.tiocmget = whiteheat_tiocmget,
.tiocmset = whiteheat_tiocmset,
.chars_in_buffer = whiteheat_chars_in_buffer,
.throttle = whiteheat_throttle,
.unthrottle = whiteheat_unthrottle,
.read_bulk_callback = whiteheat_read_callback,
.write_bulk_callback = whiteheat_write_callback,
.throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle,
};
static struct usb_serial_driver * const serial_drivers[] = {
@ -166,29 +151,8 @@ struct whiteheat_command_private {
__u8 result_buffer[64];
};
#define THROTTLED 0x01
#define ACTUALLY_THROTTLED 0x02
static int urb_pool_size = 8;
struct whiteheat_urb_wrap {
struct list_head list;
struct urb *urb;
};
struct whiteheat_private {
spinlock_t lock;
__u8 flags;
__u8 mcr; /* FIXME: no locking on mcr */
struct list_head rx_urbs_free;
struct list_head rx_urbs_submitted;
struct list_head rx_urb_q;
struct work_struct rx_work;
struct usb_serial_port *port;
struct list_head tx_urbs_free;
struct list_head tx_urbs_submitted;
struct mutex deathwarrant;
};
@ -198,12 +162,6 @@ static void stop_command_port(struct usb_serial *serial);
static void command_port_write_callback(struct urb *urb);
static void command_port_read_callback(struct urb *urb);
static int start_port_read(struct usb_serial_port *port);
static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
struct list_head *head);
static struct list_head *list_first(struct list_head *head);
static void rx_data_softint(struct work_struct *work);
static int firm_send_command(struct usb_serial_port *port, __u8 command,
__u8 *data, __u8 datasize);
static int firm_open(struct usb_serial_port *port);
@ -349,11 +307,6 @@ static int whiteheat_attach(struct usb_serial *serial)
__u8 *command;
__u8 *result;
int i;
int j;
struct urb *urb;
int buf_size;
struct whiteheat_urb_wrap *wrap;
struct list_head *tmp;
command_port = serial->port[COMMAND_PORT];
@ -408,8 +361,8 @@ static int whiteheat_attach(struct usb_serial *serial)
hw_info = (struct whiteheat_hw_info *)&result[1];
dev_info(&serial->dev->dev, "%s: Driver %s: Firmware v%d.%02d\n",
serial->type->description, DRIVER_VERSION,
dev_info(&serial->dev->dev, "%s: Firmware v%d.%02d\n",
serial->type->description,
hw_info->sw_major_rev, hw_info->sw_minor_rev);
for (i = 0; i < serial->num_ports; i++) {
@ -423,72 +376,7 @@ static int whiteheat_attach(struct usb_serial *serial)
goto no_private;
}
spin_lock_init(&info->lock);
mutex_init(&info->deathwarrant);
info->flags = 0;
info->mcr = 0;
INIT_WORK(&info->rx_work, rx_data_softint);
info->port = port;
INIT_LIST_HEAD(&info->rx_urbs_free);
INIT_LIST_HEAD(&info->rx_urbs_submitted);
INIT_LIST_HEAD(&info->rx_urb_q);
INIT_LIST_HEAD(&info->tx_urbs_free);
INIT_LIST_HEAD(&info->tx_urbs_submitted);
for (j = 0; j < urb_pool_size; j++) {
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
dev_err(&port->dev, "No free urbs available\n");
goto no_rx_urb;
}
buf_size = port->read_urb->transfer_buffer_length;
urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
if (!urb->transfer_buffer) {
dev_err(&port->dev,
"Couldn't allocate urb buffer\n");
goto no_rx_buf;
}
wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
if (!wrap) {
dev_err(&port->dev,
"Couldn't allocate urb wrapper\n");
goto no_rx_wrap;
}
usb_fill_bulk_urb(urb, serial->dev,
usb_rcvbulkpipe(serial->dev,
port->bulk_in_endpointAddress),
urb->transfer_buffer, buf_size,
whiteheat_read_callback, port);
wrap->urb = urb;
list_add(&wrap->list, &info->rx_urbs_free);
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
dev_err(&port->dev, "No free urbs available\n");
goto no_tx_urb;
}
buf_size = port->write_urb->transfer_buffer_length;
urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
if (!urb->transfer_buffer) {
dev_err(&port->dev,
"Couldn't allocate urb buffer\n");
goto no_tx_buf;
}
wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
if (!wrap) {
dev_err(&port->dev,
"Couldn't allocate urb wrapper\n");
goto no_tx_wrap;
}
usb_fill_bulk_urb(urb, serial->dev,
usb_sndbulkpipe(serial->dev,
port->bulk_out_endpointAddress),
urb->transfer_buffer, buf_size,
whiteheat_write_callback, port);
wrap->urb = urb;
list_add(&wrap->list, &info->tx_urbs_free);
}
usb_set_serial_port_data(port, info);
}
@ -531,29 +419,6 @@ static int whiteheat_attach(struct usb_serial *serial)
for (i = serial->num_ports - 1; i >= 0; i--) {
port = serial->port[i];
info = usb_get_serial_port_data(port);
for (j = urb_pool_size - 1; j >= 0; j--) {
tmp = list_first(&info->tx_urbs_free);
list_del(tmp);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
kfree(wrap);
no_tx_wrap:
kfree(urb->transfer_buffer);
no_tx_buf:
usb_free_urb(urb);
no_tx_urb:
tmp = list_first(&info->rx_urbs_free);
list_del(tmp);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
kfree(wrap);
no_rx_wrap:
kfree(urb->transfer_buffer);
no_rx_buf:
usb_free_urb(urb);
no_rx_urb:
;
}
kfree(info);
no_private:
;
@ -569,12 +434,7 @@ static int whiteheat_attach(struct usb_serial *serial)
static void whiteheat_release(struct usb_serial *serial)
{
struct usb_serial_port *command_port;
struct usb_serial_port *port;
struct whiteheat_private *info;
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
struct list_head *tmp;
struct list_head *tmp2;
int i;
dbg("%s", __func__);
@ -584,31 +444,14 @@ static void whiteheat_release(struct usb_serial *serial)
kfree(usb_get_serial_port_data(command_port));
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
info = usb_get_serial_port_data(port);
list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
list_del(tmp);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
kfree(wrap);
kfree(urb->transfer_buffer);
usb_free_urb(urb);
}
list_for_each_safe(tmp, tmp2, &info->tx_urbs_free) {
list_del(tmp);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
kfree(wrap);
kfree(urb->transfer_buffer);
usb_free_urb(urb);
}
info = usb_get_serial_port_data(serial->port[i]);
kfree(info);
}
}
static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
{
int retval = 0;
int retval;
dbg("%s - port %d", __func__, port->number);
@ -616,9 +459,6 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
if (retval)
goto exit;
if (tty)
tty->low_latency = 1;
/* send an open port command */
retval = firm_open(port);
if (retval) {
@ -640,17 +480,12 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
usb_clear_halt(port->serial->dev, port->read_urb->pipe);
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
/* Start reading from the device */
retval = start_port_read(port);
retval = usb_serial_generic_open(tty, port);
if (retval) {
dev_err(&port->dev,
"%s - failed submitting read urb, error %d\n",
__func__, retval);
firm_close(port);
stop_command_port(port->serial);
goto exit;
}
exit:
dbg("%s - exit, retval = %d", __func__, retval);
return retval;
@ -659,127 +494,16 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
static void whiteheat_close(struct usb_serial_port *port)
{
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
struct list_head *tmp;
struct list_head *tmp2;
dbg("%s - port %d", __func__, port->number);
firm_report_tx_done(port);
firm_close(port);
/* shutdown our bulk reads and writes */
mutex_lock(&info->deathwarrant);
spin_lock_irq(&info->lock);
list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
list_del(tmp);
spin_unlock_irq(&info->lock);
usb_kill_urb(urb);
spin_lock_irq(&info->lock);
list_add(tmp, &info->rx_urbs_free);
}
list_for_each_safe(tmp, tmp2, &info->rx_urb_q)
list_move(tmp, &info->rx_urbs_free);
list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) {
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
list_del(tmp);
spin_unlock_irq(&info->lock);
usb_kill_urb(urb);
spin_lock_irq(&info->lock);
list_add(tmp, &info->tx_urbs_free);
}
spin_unlock_irq(&info->lock);
mutex_unlock(&info->deathwarrant);
usb_serial_generic_close(port);
stop_command_port(port->serial);
}
static int whiteheat_write(struct tty_struct *tty,
struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
int result;
int bytes;
int sent = 0;
unsigned long flags;
struct list_head *tmp;
dbg("%s - port %d", __func__, port->number);
if (count == 0) {
dbg("%s - write request of 0 bytes", __func__);
return (0);
}
while (count) {
spin_lock_irqsave(&info->lock, flags);
if (list_empty(&info->tx_urbs_free)) {
spin_unlock_irqrestore(&info->lock, flags);
break;
}
tmp = list_first(&info->tx_urbs_free);
list_del(tmp);
spin_unlock_irqrestore(&info->lock, flags);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
bytes = (count > port->bulk_out_size) ?
port->bulk_out_size : count;
memcpy(urb->transfer_buffer, buf + sent, bytes);
usb_serial_debug_data(debug, &port->dev,
__func__, bytes, urb->transfer_buffer);
urb->transfer_buffer_length = bytes;
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
dev_err_console(port,
"%s - failed submitting write urb, error %d\n",
__func__, result);
sent = result;
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->tx_urbs_free);
spin_unlock_irqrestore(&info->lock, flags);
break;
} else {
sent += bytes;
count -= bytes;
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->tx_urbs_submitted);
spin_unlock_irqrestore(&info->lock, flags);
}
}
return sent;
}
static int whiteheat_write_room(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct list_head *tmp;
int room = 0;
unsigned long flags;
dbg("%s - port %d", __func__, port->number);
spin_lock_irqsave(&info->lock, flags);
list_for_each(tmp, &info->tx_urbs_free)
room++;
spin_unlock_irqrestore(&info->lock, flags);
room *= port->bulk_out_size;
dbg("%s - returns %d", __func__, room);
return (room);
}
static int whiteheat_tiocmget(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
@ -837,7 +561,7 @@ static int whiteheat_ioctl(struct tty_struct *tty,
serstruct.line = port->serial->minor;
serstruct.port = port->number;
serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
serstruct.xmit_fifo_size = port->bulk_out_size;
serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo);
serstruct.custom_divisor = 0;
serstruct.baud_base = 460800;
serstruct.close_delay = CLOSING_DELAY;
@ -867,60 +591,6 @@ static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
}
static int whiteheat_chars_in_buffer(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct list_head *tmp;
struct whiteheat_urb_wrap *wrap;
int chars = 0;
unsigned long flags;
dbg("%s - port %d", __func__, port->number);
spin_lock_irqsave(&info->lock, flags);
list_for_each(tmp, &info->tx_urbs_submitted) {
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
chars += wrap->urb->transfer_buffer_length;
}
spin_unlock_irqrestore(&info->lock, flags);
dbg("%s - returns %d", __func__, chars);
return chars;
}
static void whiteheat_throttle(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
dbg("%s - port %d", __func__, port->number);
spin_lock_irq(&info->lock);
info->flags |= THROTTLED;
spin_unlock_irq(&info->lock);
}
static void whiteheat_unthrottle(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct whiteheat_private *info = usb_get_serial_port_data(port);
int actually_throttled;
dbg("%s - port %d", __func__, port->number);
spin_lock_irq(&info->lock);
actually_throttled = info->flags & ACTUALLY_THROTTLED;
info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
spin_unlock_irq(&info->lock);
if (actually_throttled)
rx_data_softint(&info->rx_work);
}
/*****************************************************************************
* Connect Tech's White Heat callback routines
*****************************************************************************/
@ -989,80 +659,6 @@ static void command_port_read_callback(struct urb *urb)
}
static void whiteheat_read_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct whiteheat_urb_wrap *wrap;
unsigned char *data = urb->transfer_buffer;
struct whiteheat_private *info = usb_get_serial_port_data(port);
int status = urb->status;
dbg("%s - port %d", __func__, port->number);
spin_lock(&info->lock);
wrap = urb_to_wrap(urb, &info->rx_urbs_submitted);
if (!wrap) {
spin_unlock(&info->lock);
dev_err(&port->dev, "%s - Not my urb!\n", __func__);
return;
}
list_del(&wrap->list);
spin_unlock(&info->lock);
if (status) {
dbg("%s - nonzero read bulk status received: %d",
__func__, status);
spin_lock(&info->lock);
list_add(&wrap->list, &info->rx_urbs_free);
spin_unlock(&info->lock);
return;
}
usb_serial_debug_data(debug, &port->dev,
__func__, urb->actual_length, data);
spin_lock(&info->lock);
list_add_tail(&wrap->list, &info->rx_urb_q);
if (info->flags & THROTTLED) {
info->flags |= ACTUALLY_THROTTLED;
spin_unlock(&info->lock);
return;
}
spin_unlock(&info->lock);
schedule_work(&info->rx_work);
}
static void whiteheat_write_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct whiteheat_urb_wrap *wrap;
int status = urb->status;
dbg("%s - port %d", __func__, port->number);
spin_lock(&info->lock);
wrap = urb_to_wrap(urb, &info->tx_urbs_submitted);
if (!wrap) {
spin_unlock(&info->lock);
dev_err(&port->dev, "%s - Not my urb!\n", __func__);
return;
}
list_move(&wrap->list, &info->tx_urbs_free);
spin_unlock(&info->lock);
if (status) {
dbg("%s - nonzero write bulk status received: %d",
__func__, status);
return;
}
usb_serial_port_softint(port);
}
/*****************************************************************************
* Connect Tech's White Heat firmware interface
*****************************************************************************/
@ -1337,123 +933,6 @@ static void stop_command_port(struct usb_serial *serial)
mutex_unlock(&command_info->mutex);
}
static int start_port_read(struct usb_serial_port *port)
{
struct whiteheat_private *info = usb_get_serial_port_data(port);
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
int retval = 0;
unsigned long flags;
struct list_head *tmp;
struct list_head *tmp2;
spin_lock_irqsave(&info->lock, flags);
list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
list_del(tmp);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
spin_unlock_irqrestore(&info->lock, flags);
retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval) {
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->rx_urbs_free);
list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
list_del(tmp);
spin_unlock_irqrestore(&info->lock, flags);
usb_kill_urb(urb);
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->rx_urbs_free);
}
break;
}
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->rx_urbs_submitted);
}
spin_unlock_irqrestore(&info->lock, flags);
return retval;
}
static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
struct list_head *head)
{
struct whiteheat_urb_wrap *wrap;
struct list_head *tmp;
list_for_each(tmp, head) {
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
if (wrap->urb == urb)
return wrap;
}
return NULL;
}
static struct list_head *list_first(struct list_head *head)
{
return head->next;
}
static void rx_data_softint(struct work_struct *work)
{
struct whiteheat_private *info =
container_of(work, struct whiteheat_private, rx_work);
struct usb_serial_port *port = info->port;
struct tty_struct *tty = tty_port_tty_get(&port->port);
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
unsigned long flags;
struct list_head *tmp;
struct list_head *tmp2;
int result;
int sent = 0;
spin_lock_irqsave(&info->lock, flags);
if (info->flags & THROTTLED) {
spin_unlock_irqrestore(&info->lock, flags);
goto out;
}
list_for_each_safe(tmp, tmp2, &info->rx_urb_q) {
list_del(tmp);
spin_unlock_irqrestore(&info->lock, flags);
wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
urb = wrap->urb;
if (tty && urb->actual_length)
sent += tty_insert_flip_string(tty,
urb->transfer_buffer, urb->actual_length);
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
dev_err(&port->dev,
"%s - failed resubmitting read urb, error %d\n",
__func__, result);
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->rx_urbs_free);
continue;
}
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->rx_urbs_submitted);
}
spin_unlock_irqrestore(&info->lock, flags);
if (sent)
tty_flip_buffer_push(tty);
out:
tty_kref_put(tty);
}
module_usb_serial_driver(whiteheat_driver, serial_drivers);
MODULE_AUTHOR(DRIVER_AUTHOR);
@ -1463,8 +942,5 @@ MODULE_LICENSE("GPL");
MODULE_FIRMWARE("whiteheat.fw");
MODULE_FIRMWARE("whiteheat_loader.fw");
module_param(urb_pool_size, int, 0);
MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");

View File

@ -1933,11 +1933,7 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag)
kfree(buf);
nofw:
if (sd_fw != NULL) {
release_firmware(sd_fw);
sd_fw = NULL;
}
release_firmware(sd_fw);
return result;
}

View File

@ -139,6 +139,7 @@ struct bcma_device {
u8 core_unit;
u32 addr;
u32 addr1;
u32 wrap;
void __iomem *io_addr;

View File

@ -6,7 +6,7 @@
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
*
* Copyright 2004 Freescale Semiconductor, Inc
* Copyright 2004,2012 Freescale Semiconductor, Inc
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -17,6 +17,12 @@
#ifndef _FSL_DEVICE_H_
#define _FSL_DEVICE_H_
#define FSL_UTMI_PHY_DLY 10 /*As per P1010RM, delay for UTMI
PHY CLK to become stable - 10ms*/
#define FSL_USB_VER_OLD 0
#define FSL_USB_VER_1_6 1
#define FSL_USB_VER_2_2 2
#include <linux/types.h>
/*
@ -63,6 +69,7 @@ struct platform_device;
struct fsl_usb2_platform_data {
/* board specific information */
int controller_ver;
enum fsl_usb2_operating_modes operating_mode;
enum fsl_usb2_phy_modes phy_mode;
unsigned int port_enables;

View File

@ -0,0 +1,28 @@
/*
* EHCI SuperH driver platform data
*
* Copyright (C) 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
* Copyright (C) 2012 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __USB_EHCI_SH_H
#define __USB_EHCI_SH_H
struct ehci_sh_platdata {
void (*phy_init)(void); /* Phy init function */
};
#endif /* __USB_EHCI_SH_H */

View File

@ -1627,6 +1627,7 @@ static inline int usb_translate_errors(int error_code)
case 0:
case -ENOMEM:
case -ENODEV:
case -EOPNOTSUPP:
return error_code;
default:
return -EIO;