Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (29 commits) USB: Add support for Olimex arm-usb-ocd JTAG interface serial port USB: Add support for Sierra Wireless Aircard 595U USB: ldusb bugfix USB: ftdi_sio: Add USB Product Id for OpenDCC USB: fix ratelimit call semantics USB: handle errors in power/level attribute USB: make the autosuspend workqueue thread freezable USB: Fix USB OHCI Subvendor for Toshiba Portege 4000 USB: usblp: Use correct DMA address in case of probe error USB: Fix debug output of ark3116 USB: Onetouch - switch to using input_dev->dev.parent USB: don't try to kzalloc 0 bytes USB: remove short initial timeout for device descriptor fetch USB: Deref URB after usbmon is done with it USB: Remove duplicate IDs from option card driver USB: auerswald: fix file release handler USB: fsl_usb2_udc: Fix UMTI_WIDE support and a compile warning USB: set the correct Interrupt interval in usb_bulk_msg USB: New device PID for ftdi_sio driver USB: remove unneeded WARN_ON ...
This commit is contained in:
commit
641e22e04c
|
@ -52,7 +52,7 @@
|
|||
|
||||
<toc></toc>
|
||||
|
||||
<chapter><title>Introduction</title>
|
||||
<chapter id="intro"><title>Introduction</title>
|
||||
|
||||
<para>This document presents a Linux-USB "Gadget"
|
||||
kernel mode
|
||||
|
|
|
@ -185,7 +185,7 @@
|
|||
|
||||
</chapter>
|
||||
|
||||
<chapter><title>USB-Standard Types</title>
|
||||
<chapter id="types"><title>USB-Standard Types</title>
|
||||
|
||||
<para>In <filename><linux/usb/ch9.h></filename> you will find
|
||||
the USB data types defined in chapter 9 of the USB specification.
|
||||
|
@ -197,7 +197,7 @@
|
|||
|
||||
</chapter>
|
||||
|
||||
<chapter><title>Host-Side Data Types and Macros</title>
|
||||
<chapter id="hostside"><title>Host-Side Data Types and Macros</title>
|
||||
|
||||
<para>The host side API exposes several layers to drivers, some of
|
||||
which are more necessary than others.
|
||||
|
@ -211,7 +211,7 @@
|
|||
|
||||
</chapter>
|
||||
|
||||
<chapter><title>USB Core APIs</title>
|
||||
<chapter id="usbcore"><title>USB Core APIs</title>
|
||||
|
||||
<para>There are two basic I/O models in the USB API.
|
||||
The most elemental one is asynchronous: drivers submit requests
|
||||
|
@ -248,7 +248,7 @@
|
|||
!Edrivers/usb/core/hub.c
|
||||
</chapter>
|
||||
|
||||
<chapter><title>Host Controller APIs</title>
|
||||
<chapter id="hcd"><title>Host Controller APIs</title>
|
||||
|
||||
<para>These APIs are only for use by host controller drivers,
|
||||
most of which implement standard register interfaces such as
|
||||
|
@ -285,7 +285,7 @@
|
|||
!Idrivers/usb/core/buffer.c
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<chapter id="usbfs">
|
||||
<title>The USB Filesystem (usbfs)</title>
|
||||
|
||||
<para>This chapter presents the Linux <emphasis>usbfs</emphasis>.
|
||||
|
@ -317,7 +317,7 @@
|
|||
not it has a kernel driver.
|
||||
</para>
|
||||
|
||||
<sect1>
|
||||
<sect1 id="usbfs-files">
|
||||
<title>What files are in "usbfs"?</title>
|
||||
|
||||
<para>Conventionally mounted at
|
||||
|
@ -356,7 +356,7 @@
|
|||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<sect1 id="usbfs-fstab">
|
||||
<title>Mounting and Access Control</title>
|
||||
|
||||
<para>There are a number of mount options for usbfs, which will
|
||||
|
@ -439,7 +439,7 @@
|
|||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<sect1 id="usbfs-devices">
|
||||
<title>/proc/bus/usb/devices</title>
|
||||
|
||||
<para>This file is handy for status viewing tools in user
|
||||
|
@ -473,7 +473,7 @@ for (;;) {
|
|||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<sect1 id="usbfs-bbbddd">
|
||||
<title>/proc/bus/usb/BBB/DDD</title>
|
||||
|
||||
<para>Use these files in one of these basic ways:
|
||||
|
@ -510,7 +510,7 @@ for (;;) {
|
|||
</sect1>
|
||||
|
||||
|
||||
<sect1>
|
||||
<sect1 id="usbfs-lifecycle">
|
||||
<title>Life Cycle of User Mode Drivers</title>
|
||||
|
||||
<para>Such a driver first needs to find a device file
|
||||
|
@ -565,7 +565,7 @@ for (;;) {
|
|||
|
||||
</sect1>
|
||||
|
||||
<sect1><title>The ioctl() Requests</title>
|
||||
<sect1 id="usbfs-ioctl"><title>The ioctl() Requests</title>
|
||||
|
||||
<para>To use these ioctls, you need to include the following
|
||||
headers in your userspace program:
|
||||
|
@ -604,7 +604,7 @@ for (;;) {
|
|||
</para>
|
||||
|
||||
|
||||
<sect2>
|
||||
<sect2 id="usbfs-mgmt">
|
||||
<title>Management/Status Requests</title>
|
||||
|
||||
<para>A number of usbfs requests don't deal very directly
|
||||
|
@ -736,7 +736,7 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<sect2 id="usbfs-sync">
|
||||
<title>Synchronous I/O Support</title>
|
||||
|
||||
<para>Synchronous requests involve the kernel blocking
|
||||
|
@ -865,7 +865,7 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
|
|||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<sect2 id="usbfs-async">
|
||||
<title>Asynchronous I/O Support</title>
|
||||
|
||||
<para>As mentioned above, there are situations where it may be
|
||||
|
|
|
@ -91,6 +91,22 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
"CDC descriptors on config\n");
|
||||
}
|
||||
|
||||
/* Maybe CDC descriptors are after the endpoint? This bug has
|
||||
* been seen on some 2Wire Inc RNDIS-ish products.
|
||||
*/
|
||||
if (len == 0) {
|
||||
struct usb_host_endpoint *hep;
|
||||
|
||||
hep = intf->cur_altsetting->endpoint;
|
||||
if (hep) {
|
||||
buf = hep->extra;
|
||||
len = hep->extralen;
|
||||
}
|
||||
if (len)
|
||||
dev_dbg(&intf->dev,
|
||||
"CDC descriptors on endpoint\n");
|
||||
}
|
||||
|
||||
/* this assumes that if there's a non-RNDIS vendor variant
|
||||
* of cdc-acm, it'll fail RNDIS requests cleanly.
|
||||
*/
|
||||
|
|
|
@ -515,6 +515,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
dev_err(&intf->dev,
|
||||
"dev can't take %u byte packets (max %u)\n",
|
||||
dev->hard_mtu, tmp);
|
||||
retval = -EINVAL;
|
||||
goto fail_and_release;
|
||||
}
|
||||
|
||||
|
|
|
@ -1252,20 +1252,23 @@ EXPORT_SYMBOL_GPL(usbnet_probe);
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* FIXME these suspend/resume methods assume non-CDC style
|
||||
* devices, with only one interface.
|
||||
/*
|
||||
* suspend the whole driver as soon as the first interface is suspended
|
||||
* resume only when the last interface is resumed
|
||||
*/
|
||||
|
||||
int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
|
||||
{
|
||||
struct usbnet *dev = usb_get_intfdata(intf);
|
||||
|
||||
/* accelerate emptying of the rx and queues, to avoid
|
||||
* having everything error out.
|
||||
*/
|
||||
netif_device_detach (dev->net);
|
||||
(void) unlink_urbs (dev, &dev->rxq);
|
||||
(void) unlink_urbs (dev, &dev->txq);
|
||||
if (!dev->suspend_count++) {
|
||||
/* accelerate emptying of the rx and queues, to avoid
|
||||
* having everything error out.
|
||||
*/
|
||||
netif_device_detach (dev->net);
|
||||
(void) unlink_urbs (dev, &dev->rxq);
|
||||
(void) unlink_urbs (dev, &dev->txq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_suspend);
|
||||
|
@ -1274,8 +1277,10 @@ int usbnet_resume (struct usb_interface *intf)
|
|||
{
|
||||
struct usbnet *dev = usb_get_intfdata(intf);
|
||||
|
||||
netif_device_attach (dev->net);
|
||||
tasklet_schedule (&dev->bh);
|
||||
if (!--dev->suspend_count) {
|
||||
netif_device_attach (dev->net);
|
||||
tasklet_schedule (&dev->bh);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usbnet_resume);
|
||||
|
|
|
@ -32,6 +32,7 @@ struct usbnet {
|
|||
const char *driver_name;
|
||||
wait_queue_head_t *wait;
|
||||
struct mutex phy_mutex;
|
||||
unsigned char suspend_count;
|
||||
|
||||
/* i/o info: pipes etc */
|
||||
unsigned in, out;
|
||||
|
|
|
@ -1003,7 +1003,7 @@ abort:
|
|||
usblp->writebuf, usblp->writeurb->transfer_dma);
|
||||
if (usblp->readbuf)
|
||||
usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
|
||||
usblp->readbuf, usblp->writeurb->transfer_dma);
|
||||
usblp->readbuf, usblp->readurb->transfer_dma);
|
||||
kfree(usblp->statusbuf);
|
||||
kfree(usblp->device_id_string);
|
||||
usb_free_urb(usblp->writeurb);
|
||||
|
|
|
@ -185,10 +185,12 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
|
|||
num_ep = USB_MAXENDPOINTS;
|
||||
}
|
||||
|
||||
len = sizeof(struct usb_host_endpoint) * num_ep;
|
||||
alt->endpoint = kzalloc(len, GFP_KERNEL);
|
||||
if (!alt->endpoint)
|
||||
return -ENOMEM;
|
||||
if (num_ep > 0) { /* Can't allocate 0 bytes */
|
||||
len = sizeof(struct usb_host_endpoint) * num_ep;
|
||||
alt->endpoint = kzalloc(len, GFP_KERNEL);
|
||||
if (!alt->endpoint)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Parse all the endpoint descriptors */
|
||||
n = 0;
|
||||
|
|
|
@ -983,7 +983,10 @@ static int autosuspend_check(struct usb_device *udev)
|
|||
|
||||
#else
|
||||
|
||||
#define autosuspend_check(udev) 0
|
||||
static inline int autosuspend_check(struct usb_device *udev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USB_SUSPEND */
|
||||
|
||||
|
@ -1041,7 +1044,6 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
|||
if (status < 0)
|
||||
goto done;
|
||||
}
|
||||
cancel_delayed_work(&udev->autosuspend);
|
||||
|
||||
/* Suspend all the interfaces and then udev itself */
|
||||
if (udev->actconfig) {
|
||||
|
@ -1062,9 +1064,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
|||
usb_resume_interface(intf);
|
||||
}
|
||||
|
||||
/* Try another autosuspend when the interfaces aren't busy */
|
||||
if (udev->auto_pm)
|
||||
autosuspend_check(udev);
|
||||
|
||||
/* If the suspend succeeded, propagate it up the tree */
|
||||
} else if (parent)
|
||||
usb_autosuspend_device(parent);
|
||||
} else {
|
||||
cancel_delayed_work(&udev->autosuspend);
|
||||
if (parent)
|
||||
usb_autosuspend_device(parent);
|
||||
}
|
||||
|
||||
done:
|
||||
// dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
|
||||
|
@ -1475,6 +1484,7 @@ int usb_external_resume_device(struct usb_device *udev)
|
|||
usb_pm_lock(udev);
|
||||
udev->auto_pm = 0;
|
||||
status = usb_resume_both(udev);
|
||||
udev->last_busy = jiffies;
|
||||
usb_pm_unlock(udev);
|
||||
|
||||
/* Now that the device is awake, we can start trying to autosuspend
|
||||
|
|
|
@ -1018,8 +1018,8 @@ done:
|
|||
atomic_dec (&urb->use_count);
|
||||
if (urb->reject)
|
||||
wake_up (&usb_kill_urb_queue);
|
||||
usb_put_urb (urb);
|
||||
usbmon_urb_submit_error(&hcd->self, urb, status);
|
||||
usb_put_urb (urb);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -1175,10 +1175,6 @@ void usb_hcd_endpoint_disable (struct usb_device *udev,
|
|||
struct urb *urb;
|
||||
|
||||
hcd = bus_to_hcd(udev->bus);
|
||||
|
||||
WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT &&
|
||||
udev->state != USB_STATE_NOTATTACHED);
|
||||
|
||||
local_irq_disable ();
|
||||
|
||||
/* ep is already gone from udev->ep_{in,out}[]; no more submits */
|
||||
|
|
|
@ -2201,14 +2201,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Use a short timeout the first time through,
|
||||
* so that recalcitrant full-speed devices with
|
||||
* 8- or 16-byte ep0-maxpackets won't slow things
|
||||
* down tremendously by NAKing the unexpectedly
|
||||
* early status stage. Also, retry on all errors;
|
||||
* some devices are flakey.
|
||||
* 255 is for WUSB devices, we actually need to use 512.
|
||||
* WUSB1.0[4.8.1].
|
||||
/* Retry on all errors; some devices are flakey.
|
||||
* 255 is for WUSB devices, we actually need to use
|
||||
* 512 (WUSB1.0[4.8.1]).
|
||||
*/
|
||||
for (j = 0; j < 3; ++j) {
|
||||
buf->bMaxPacketSize0 = 0;
|
||||
|
@ -2216,7 +2211,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
USB_DT_DEVICE << 8, 0,
|
||||
buf, GET_DESCRIPTOR_BUFSIZE,
|
||||
(i ? USB_CTRL_GET_TIMEOUT : 1000));
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
switch (buf->bMaxPacketSize0) {
|
||||
case 8: case 16: case 32: case 64: case 255:
|
||||
if (buf->bDescriptorType ==
|
||||
|
@ -2426,10 +2421,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
|||
|
||||
if (portchange & USB_PORT_STAT_C_CONNECTION) {
|
||||
status = hub_port_debounce(hub, port1);
|
||||
if (status < 0 && printk_ratelimit()) {
|
||||
dev_err (hub_dev,
|
||||
"connect-debounce failed, port %d disabled\n",
|
||||
port1);
|
||||
if (status < 0) {
|
||||
if (printk_ratelimit())
|
||||
dev_err (hub_dev, "connect-debounce failed, "
|
||||
"port %d disabled\n", port1);
|
||||
goto done;
|
||||
}
|
||||
portstatus = status;
|
||||
|
|
|
@ -221,15 +221,10 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
|
|||
|
||||
if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
|
||||
USB_ENDPOINT_XFER_INT) {
|
||||
int interval;
|
||||
|
||||
if (usb_dev->speed == USB_SPEED_HIGH)
|
||||
interval = 1 << min(15, ep->desc.bInterval - 1);
|
||||
else
|
||||
interval = ep->desc.bInterval;
|
||||
pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
|
||||
usb_fill_int_urb(urb, usb_dev, pipe, data, len,
|
||||
usb_api_blocking_completion, NULL, interval);
|
||||
usb_api_blocking_completion, NULL,
|
||||
ep->desc.bInterval);
|
||||
} else
|
||||
usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
|
||||
usb_api_blocking_completion, NULL);
|
||||
|
|
|
@ -232,12 +232,15 @@ set_level(struct device *dev, struct device_attribute *attr,
|
|||
int len = count;
|
||||
char *cp;
|
||||
int rc = 0;
|
||||
int old_autosuspend_disabled, old_autoresume_disabled;
|
||||
|
||||
cp = memchr(buf, '\n', count);
|
||||
if (cp)
|
||||
len = cp - buf;
|
||||
|
||||
usb_lock_device(udev);
|
||||
old_autosuspend_disabled = udev->autosuspend_disabled;
|
||||
old_autoresume_disabled = udev->autoresume_disabled;
|
||||
|
||||
/* Setting the flags without calling usb_pm_lock is a subject to
|
||||
* races, but who cares...
|
||||
|
@ -263,6 +266,10 @@ set_level(struct device *dev, struct device_attribute *attr,
|
|||
} else
|
||||
rc = -EINVAL;
|
||||
|
||||
if (rc) {
|
||||
udev->autosuspend_disabled = old_autosuspend_disabled;
|
||||
udev->autoresume_disabled = old_autoresume_disabled;
|
||||
}
|
||||
usb_unlock_device(udev);
|
||||
return (rc < 0 ? rc : count);
|
||||
}
|
||||
|
|
|
@ -205,7 +205,11 @@ struct device_type usb_device_type = {
|
|||
|
||||
static int ksuspend_usb_init(void)
|
||||
{
|
||||
ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd");
|
||||
/* This workqueue is supposed to be both freezable and
|
||||
* singlethreaded. Its job doesn't justify running on more
|
||||
* than one CPU.
|
||||
*/
|
||||
ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
|
||||
if (!ksuspend_usb_wq)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
|
|
|
@ -228,13 +228,15 @@ static int dr_controller_setup(struct fsl_udc *udc)
|
|||
|
||||
/* Config PHY interface */
|
||||
portctrl = fsl_readl(&dr_regs->portsc1);
|
||||
portctrl &= ~PORTSCX_PHY_TYPE_SEL;
|
||||
portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH);
|
||||
switch (udc->phy_mode) {
|
||||
case FSL_USB2_PHY_ULPI:
|
||||
portctrl |= PORTSCX_PTS_ULPI;
|
||||
break;
|
||||
case FSL_USB2_PHY_UTMI:
|
||||
case FSL_USB2_PHY_UTMI_WIDE:
|
||||
portctrl |= PORTSCX_PTW_16BIT;
|
||||
/* fall through */
|
||||
case FSL_USB2_PHY_UTMI:
|
||||
portctrl |= PORTSCX_PTS_UTMI;
|
||||
break;
|
||||
case FSL_USB2_PHY_SERIAL:
|
||||
|
@ -625,7 +627,7 @@ static void fsl_free_buffer(struct usb_ep *_ep, void *buf,
|
|||
struct fsl_ep *ep;
|
||||
|
||||
if (!_ep)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
ep = container_of(_ep, struct fsl_ep, ep);
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ static const struct pci_device_id ohci_pci_quirks[] = {
|
|||
/* Toshiba portege 4000 */
|
||||
.vendor = PCI_VENDOR_ID_AL,
|
||||
.device = 0x5237,
|
||||
.subvendor = PCI_VENDOR_ID_TOSHIBA_2,
|
||||
.subvendor = PCI_VENDOR_ID_TOSHIBA,
|
||||
.subdevice = 0x0004,
|
||||
.driver_data = (unsigned long) broken_suspend,
|
||||
},
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define EHCI_USBSTS 4 /* status register */
|
||||
#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
|
||||
#define EHCI_USBINTR 8 /* interrupt register */
|
||||
#define EHCI_CONFIGFLAG 0x40 /* configured flag register */
|
||||
#define EHCI_USBLEGSUP 0 /* legacy support register */
|
||||
#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
|
||||
#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
|
||||
|
@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
|||
u32 hcc_params, val;
|
||||
u8 offset, cap_length;
|
||||
int count = 256/4;
|
||||
int tried_handoff = 0;
|
||||
|
||||
if (!mmio_resource_enabled(pdev, 0))
|
||||
return;
|
||||
|
@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
|||
*/
|
||||
msec = 5000;
|
||||
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
|
||||
tried_handoff = 1;
|
||||
msleep(10);
|
||||
msec -= 10;
|
||||
pci_read_config_dword(pdev, offset, &cap);
|
||||
|
@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
|||
pci_write_config_dword(pdev,
|
||||
offset + EHCI_USBLEGCTLSTS,
|
||||
0);
|
||||
|
||||
/* If the BIOS ever owned the controller then we
|
||||
* can't expect any power sessions to remain intact.
|
||||
*/
|
||||
if (tried_handoff)
|
||||
writel(0, op_reg_base + EHCI_CONFIGFLAG);
|
||||
break;
|
||||
case 0: /* illegal reserved capability */
|
||||
cap = 0;
|
||||
|
|
|
@ -57,6 +57,13 @@
|
|||
#include <asm/system.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include "../core/hcd.h"
|
||||
|
||||
/* FIXME ohci.h is ONLY for internal use by the OHCI driver.
|
||||
* If you're going to try stuff like this, you need to split
|
||||
* out shareable stuff (register declarations?) into its own
|
||||
* file, maybe name <linux/usb/ohci.h>
|
||||
*/
|
||||
|
||||
#include "ohci.h"
|
||||
#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
|
||||
#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
|
||||
|
@ -173,11 +180,6 @@ struct u132_ring {
|
|||
struct u132_endp *curr_endp;
|
||||
struct delayed_work scheduler;
|
||||
};
|
||||
#define OHCI_QUIRK_AMD756 0x01
|
||||
#define OHCI_QUIRK_SUPERIO 0x02
|
||||
#define OHCI_QUIRK_INITRESET 0x04
|
||||
#define OHCI_BIG_ENDIAN 0x08
|
||||
#define OHCI_QUIRK_ZFMICRO 0x10
|
||||
struct u132 {
|
||||
struct kref kref;
|
||||
struct list_head u132_list;
|
||||
|
|
|
@ -1822,16 +1822,10 @@ static int auerchar_release (struct inode *inode, struct file *file)
|
|||
pauerswald_t cp;
|
||||
dbg("release");
|
||||
|
||||
/* get the mutexes */
|
||||
if (down_interruptible (&ccp->mutex)) {
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
down(&ccp->mutex);
|
||||
cp = ccp->auerdev;
|
||||
if (cp) {
|
||||
if (down_interruptible (&cp->mutex)) {
|
||||
up (&ccp->mutex);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
down(&cp->mutex);
|
||||
/* remove an open service */
|
||||
auerswald_removeservice (cp, &ccp->scontext);
|
||||
/* detach from device */
|
||||
|
|
|
@ -73,6 +73,13 @@ static struct list_head ftdi_static_list;
|
|||
#include "usb_u132.h"
|
||||
#include <asm/io.h>
|
||||
#include "../core/hcd.h"
|
||||
|
||||
/* FIXME ohci.h is ONLY for internal use by the OHCI driver.
|
||||
* If you're going to try stuff like this, you need to split
|
||||
* out shareable stuff (register declarations?) into its own
|
||||
* file, maybe name <linux/usb/ohci.h>
|
||||
*/
|
||||
|
||||
#include "../host/ohci.h"
|
||||
/* Define these values to match your devices*/
|
||||
#define USB_FTDI_ELAN_VENDOR_ID 0x0403
|
||||
|
@ -2300,10 +2307,7 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi)
|
|||
offsetof(struct ohci_regs, member), 0, data);
|
||||
#define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \
|
||||
offsetof(struct ohci_regs, member), 0, data);
|
||||
#define OHCI_QUIRK_AMD756 0x01
|
||||
#define OHCI_QUIRK_SUPERIO 0x02
|
||||
#define OHCI_QUIRK_INITRESET 0x04
|
||||
#define OHCI_BIG_ENDIAN 0x08
|
||||
|
||||
#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
|
||||
#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
|
||||
OHCI_INTR_WDH)
|
||||
|
|
|
@ -165,6 +165,8 @@ struct ld_usb {
|
|||
size_t interrupt_in_endpoint_size;
|
||||
int interrupt_in_running;
|
||||
int interrupt_in_done;
|
||||
int buffer_overflow;
|
||||
spinlock_t rbsl;
|
||||
|
||||
char* interrupt_out_buffer;
|
||||
struct usb_endpoint_descriptor* interrupt_out_endpoint;
|
||||
|
@ -230,10 +232,12 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
|
|||
} else {
|
||||
dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
|
||||
__FUNCTION__, urb->status);
|
||||
spin_lock(&dev->rbsl);
|
||||
goto resubmit; /* maybe we can recover */
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock(&dev->rbsl);
|
||||
if (urb->actual_length > 0) {
|
||||
next_ring_head = (dev->ring_head+1) % ring_buffer_size;
|
||||
if (next_ring_head != dev->ring_tail) {
|
||||
|
@ -244,21 +248,25 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
|
|||
dev->ring_head = next_ring_head;
|
||||
dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
|
||||
__FUNCTION__, urb->actual_length);
|
||||
} else
|
||||
} else {
|
||||
dev_warn(&dev->intf->dev,
|
||||
"Ring buffer overflow, %d bytes dropped\n",
|
||||
urb->actual_length);
|
||||
dev->buffer_overflow = 1;
|
||||
}
|
||||
}
|
||||
|
||||
resubmit:
|
||||
/* resubmit if we're still running */
|
||||
if (dev->interrupt_in_running && dev->intf) {
|
||||
if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) {
|
||||
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
if (retval) {
|
||||
dev_err(&dev->intf->dev,
|
||||
"usb_submit_urb failed (%d)\n", retval);
|
||||
dev->buffer_overflow = 1;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&dev->rbsl);
|
||||
exit:
|
||||
dev->interrupt_in_done = 1;
|
||||
wake_up_interruptible(&dev->read_wait);
|
||||
|
@ -330,6 +338,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
|
|||
/* initialize in direction */
|
||||
dev->ring_head = 0;
|
||||
dev->ring_tail = 0;
|
||||
dev->buffer_overflow = 0;
|
||||
usb_fill_int_urb(dev->interrupt_in_urb,
|
||||
interface_to_usbdev(interface),
|
||||
usb_rcvintpipe(interface_to_usbdev(interface),
|
||||
|
@ -439,6 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
|
|||
size_t *actual_buffer;
|
||||
size_t bytes_to_read;
|
||||
int retval = 0;
|
||||
int rv;
|
||||
|
||||
dev = file->private_data;
|
||||
|
||||
|
@ -460,7 +470,10 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
|
|||
}
|
||||
|
||||
/* wait for data */
|
||||
spin_lock_irq(&dev->rbsl);
|
||||
if (dev->ring_head == dev->ring_tail) {
|
||||
dev->interrupt_in_done = 0;
|
||||
spin_unlock_irq(&dev->rbsl);
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
retval = -EAGAIN;
|
||||
goto unlock_exit;
|
||||
|
@ -468,6 +481,8 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
|
|||
retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
|
||||
if (retval < 0)
|
||||
goto unlock_exit;
|
||||
} else {
|
||||
spin_unlock_irq(&dev->rbsl);
|
||||
}
|
||||
|
||||
/* actual_buffer contains actual_length + interrupt_in_buffer */
|
||||
|
@ -486,6 +501,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
|
|||
|
||||
retval = bytes_to_read;
|
||||
|
||||
spin_lock_irq(&dev->rbsl);
|
||||
if (dev->buffer_overflow) {
|
||||
dev->buffer_overflow = 0;
|
||||
spin_unlock_irq(&dev->rbsl);
|
||||
rv = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
|
||||
if (rv < 0)
|
||||
dev->buffer_overflow = 1;
|
||||
} else {
|
||||
spin_unlock_irq(&dev->rbsl);
|
||||
}
|
||||
|
||||
unlock_exit:
|
||||
/* unlock the device */
|
||||
up(&dev->sem);
|
||||
|
@ -635,6 +661,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *
|
|||
goto exit;
|
||||
}
|
||||
init_MUTEX(&dev->sem);
|
||||
spin_lock_init(&dev->rbsl);
|
||||
dev->intf = intf;
|
||||
init_waitqueue_head(&dev->read_wait);
|
||||
init_waitqueue_head(&dev->write_wait);
|
||||
|
|
|
@ -63,7 +63,8 @@ static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
|
|||
request, requesttype, value, index,
|
||||
buf, 0x0000001, 1000);
|
||||
if (result)
|
||||
dbg("%03d < %d bytes [0x%02X]", seq, result, buf[0]);
|
||||
dbg("%03d < %d bytes [0x%02X]", seq, result,
|
||||
((unsigned char *)buf)[0]);
|
||||
else
|
||||
dbg("%03d < 0 bytes", seq);
|
||||
}
|
||||
|
|
|
@ -273,12 +273,18 @@ static __u16 product;
|
|||
|
||||
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
|
||||
struct ftdi_sio_quirk {
|
||||
int (*probe)(struct usb_serial *);
|
||||
void (*setup)(struct usb_serial *); /* Special settings during startup. */
|
||||
};
|
||||
|
||||
static int ftdi_olimex_probe (struct usb_serial *serial);
|
||||
static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
|
||||
static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
|
||||
|
||||
static struct ftdi_sio_quirk ftdi_olimex_quirk = {
|
||||
.probe = ftdi_olimex_probe,
|
||||
};
|
||||
|
||||
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
|
||||
.setup = ftdi_USB_UIRT_setup,
|
||||
};
|
||||
|
@ -319,6 +325,7 @@ static struct usb_device_id id_table_combined [] = {
|
|||
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
|
||||
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
|
||||
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
|
||||
|
@ -525,6 +532,9 @@ static struct usb_device_id id_table_combined [] = {
|
|||
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
|
||||
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
|
||||
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
|
||||
{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
|
||||
{ }, /* Optional parameter entry */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
@ -669,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = {
|
|||
|
||||
/*
|
||||
* ***************************************************************************
|
||||
* Utlity functions
|
||||
* Utility functions
|
||||
* ***************************************************************************
|
||||
*/
|
||||
|
||||
|
@ -1171,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
|
|||
/* Probe function to check for special devices */
|
||||
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
|
||||
{
|
||||
struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
|
||||
|
||||
if (quirk && quirk->probe) {
|
||||
int ret = quirk->probe(serial);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
usb_set_serial_data(serial, (void *)id->driver_info);
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ftdi_sio_port_probe(struct usb_serial_port *port)
|
||||
|
@ -1268,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
|
|||
priv->force_rtscts = 1;
|
||||
} /* ftdi_HE_TIRA1_setup */
|
||||
|
||||
/*
|
||||
* First port on Olimex arm-usb-ocd is reserved for JTAG interface
|
||||
* and can be accessed from userspace using openocd.
|
||||
*/
|
||||
static int ftdi_olimex_probe(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_device *udev = serial->dev;
|
||||
struct usb_interface *interface = serial->interface;
|
||||
|
||||
dbg("%s",__FUNCTION__);
|
||||
|
||||
if (interface == udev->actconfig->interface[0]) {
|
||||
info("Ignoring reserved serial port on Olimex arm-usb-ocd\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
|
||||
* it is called when the usb device is disconnected
|
||||
|
|
|
@ -60,6 +60,9 @@
|
|||
/* DMX4ALL DMX Interfaces */
|
||||
#define FTDI_DMX4ALL 0xC850
|
||||
|
||||
/* OpenDCC (www.opendcc.de) product id */
|
||||
#define FTDI_OPENDCC_PID 0xBFD8
|
||||
|
||||
/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
|
||||
/* they use the ftdi chipset for the USB interface and the vendor id is the same */
|
||||
#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */
|
||||
|
@ -518,6 +521,15 @@
|
|||
#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */
|
||||
#define FTDI_IBS_PROD_PID 0xff3f /* future device */
|
||||
|
||||
/*
|
||||
* MaxStream devices www.maxstream.net
|
||||
*/
|
||||
#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */
|
||||
|
||||
/* Olimex */
|
||||
#define OLIMEX_VID 0x15BA
|
||||
#define OLIMEX_ARM_USB_OCD_PID 0x0003
|
||||
|
||||
/* Commands */
|
||||
#define FTDI_SIO_RESET 0 /* Reset the port */
|
||||
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
|
||||
|
|
|
@ -769,11 +769,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!mos7840_port) {
|
||||
dbg("%s", "NULL mos7840_port pointer \n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) {
|
||||
dbg("%s", "Port Paranoia failed \n");
|
||||
return;
|
||||
|
|
|
@ -165,12 +165,10 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
|
|||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct usb_serial_port *wport;
|
||||
struct omninet_data *od = usb_get_serial_port_data(port);
|
||||
int result = 0;
|
||||
|
||||
dbg("%s - port %d", __FUNCTION__, port->number);
|
||||
|
||||
od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
|
||||
wport = serial->port[1];
|
||||
wport->tty = port->tty;
|
||||
|
||||
|
|
|
@ -165,7 +165,6 @@ static struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel XU870 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
|
||||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
|
||||
|
|
|
@ -35,6 +35,7 @@ static struct usb_device_id id_table [] = {
|
|||
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
|
||||
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
|
||||
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
|
||||
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
|
||||
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
|
||||
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
|
||||
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
|
||||
|
@ -60,6 +61,7 @@ static struct usb_device_id id_table_3port [] = {
|
|||
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
|
||||
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
|
||||
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
|
||||
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
|
||||
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
|
||||
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
|
||||
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
|
||||
|
|
|
@ -84,7 +84,7 @@ resubmit:
|
|||
|
||||
static int usb_onetouch_open(struct input_dev *dev)
|
||||
{
|
||||
struct usb_onetouch *onetouch = dev->private;
|
||||
struct usb_onetouch *onetouch = input_get_drvdata(dev);
|
||||
|
||||
onetouch->is_open = 1;
|
||||
onetouch->irq->dev = onetouch->udev;
|
||||
|
@ -98,7 +98,7 @@ static int usb_onetouch_open(struct input_dev *dev)
|
|||
|
||||
static void usb_onetouch_close(struct input_dev *dev)
|
||||
{
|
||||
struct usb_onetouch *onetouch = dev->private;
|
||||
struct usb_onetouch *onetouch = input_get_drvdata(dev);
|
||||
|
||||
usb_kill_urb(onetouch->irq);
|
||||
onetouch->is_open = 0;
|
||||
|
@ -185,13 +185,14 @@ int onetouch_connect_input(struct us_data *ss)
|
|||
input_dev->name = onetouch->name;
|
||||
input_dev->phys = onetouch->phys;
|
||||
usb_to_input_id(udev, &input_dev->id);
|
||||
input_dev->cdev.dev = &udev->dev;
|
||||
input_dev->dev.parent = &udev->dev;
|
||||
|
||||
set_bit(EV_KEY, input_dev->evbit);
|
||||
set_bit(ONETOUCH_BUTTON, input_dev->keybit);
|
||||
clear_bit(0, input_dev->keybit);
|
||||
|
||||
input_dev->private = onetouch;
|
||||
input_set_drvdata(input_dev, onetouch);
|
||||
|
||||
input_dev->open = usb_onetouch_open;
|
||||
input_dev->close = usb_onetouch_close;
|
||||
|
||||
|
|
|
@ -1179,14 +1179,20 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
|
|||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_FIX_INQUIRY ),
|
||||
|
||||
/* This is a virtual windows driver CD, which the zd1211rw driver automatically
|
||||
* converts into a WLAN device. */
|
||||
/* These are virtual windows driver CDs, which the zd1211rw driver automatically
|
||||
* converts into a WLAN devices. */
|
||||
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
|
||||
"ZyXEL",
|
||||
"G-220F USB-WLAN Install",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_DEVICE ),
|
||||
|
||||
UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
|
||||
"SiteCom",
|
||||
"WL-117 USB-WLAN Install",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_DEVICE ),
|
||||
|
||||
#ifdef CONFIG_USB_STORAGE_ISD200
|
||||
UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
|
||||
"ATI",
|
||||
|
|
Loading…
Reference in New Issue