Commit 90eb29ef authored by Linus Torvalds's avatar Linus Torvalds

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: (24 commits)
  Revert "[PATCH] USB: move usb_device_class class devices to be real devices"
  Revert "[PATCH] USB: convert usb class devices to real devices"
  USB: UHCI: Don't test the Short Packet Detect bit
  USB: unusual_devs entry for Nokia 3250
  USB: dummy-hcd: disable interrupts during req->complete
  USB: fix the USB_GADGET_DUMMY_HCD dependencies
  USB: ati_remote.c: autorepeat fix
  USB: doc: fixes devio.c location in proc_usb_info.txt.
  USB: doc: usb-help.txt update.
  USB: Patch for rtl8150 to fix unplug problems
  USB: cypress driver comment updates
  USB: unusual_devs device removal
  usb-storage: Add US_FL_IGNORE_DEVICE flag; ignore ZyXEL G220F
  USB: New USB ID for Belkin Serial Adapter
  USB: Additional PID for the ftdi_sio driver
  USB: adding support for SHARP WS003SH to ipaq.c
  USB: Fix Freescale high-speed USB host dependency
  USB: Removed 3-port device handler from Option driver
  USB: Drop Sierra Wireless MC8755 from the Option driver
  USB: Let option driver handle Anydata CDMA modems. Remove anydata driver.
  ...
parents 1398ab7c cae74b30
...@@ -59,7 +59,7 @@ bind to an interface (or perhaps several) using an ioctl call. You ...@@ -59,7 +59,7 @@ bind to an interface (or perhaps several) using an ioctl call. You
would issue more ioctls to the device to communicate to it using would issue more ioctls to the device to communicate to it using
control, bulk, or other kinds of USB transfers. The IOCTLs are control, bulk, or other kinds of USB transfers. The IOCTLs are
listed in the <linux/usbdevice_fs.h> file, and at this writing the listed in the <linux/usbdevice_fs.h> file, and at this writing the
source code (linux/drivers/usb/devio.c) is the primary reference source code (linux/drivers/usb/core/devio.c) is the primary reference
for how to access devices through those files. for how to access devices through those files.
Note that since by default these BBB/DDD files are writable only by Note that since by default these BBB/DDD files are writable only by
......
...@@ -5,8 +5,7 @@ For USB help other than the readme files that are located in ...@@ -5,8 +5,7 @@ For USB help other than the readme files that are located in
Documentation/usb/*, see the following: Documentation/usb/*, see the following:
Linux-USB project: http://www.linux-usb.org Linux-USB project: http://www.linux-usb.org
mirrors at http://www.suse.cz/development/linux-usb/ mirrors at http://usb.in.tum.de/linux-usb/
and http://usb.in.tum.de/linux-usb/
and http://it.linux-usb.org and http://it.linux-usb.org
Linux USB Guide: http://linux-usb.sourceforge.net Linux USB Guide: http://linux-usb.sourceforge.net
Linux-USB device overview (working devices and drivers): Linux-USB device overview (working devices and drivers):
......
...@@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI ...@@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI
default y if ARCH_S3C2410 default y if ARCH_S3C2410
default y if PXA27x default y if PXA27x
default y if ARCH_EP93XX default y if ARCH_EP93XX
default y if ARCH_AT91RM9200 default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261)
# PPC: # PPC:
default y if STB03xxx default y if STB03xxx
default y if PPC_MPC52xx default y if PPC_MPC52xx
......
...@@ -517,19 +517,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig ...@@ -517,19 +517,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
static struct usb_device *usbdev_lookup_minor(int minor) static struct usb_device *usbdev_lookup_minor(int minor)
{ {
struct device *device; struct class_device *class_dev;
struct usb_device *udev = NULL; struct usb_device *dev = NULL;
down(&usb_device_class->sem); down(&usb_device_class->sem);
list_for_each_entry(device, &usb_device_class->devices, node) { list_for_each_entry(class_dev, &usb_device_class->children, node) {
if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
udev = device->platform_data; dev = class_dev->class_data;
break; break;
} }
} }
up(&usb_device_class->sem); up(&usb_device_class->sem);
return udev; return dev;
}; };
/* /*
...@@ -1580,16 +1580,16 @@ static void usbdev_add(struct usb_device *dev) ...@@ -1580,16 +1580,16 @@ static void usbdev_add(struct usb_device *dev)
{ {
int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
dev->usbfs_dev = device_create(usb_device_class, &dev->dev, dev->class_dev = class_device_create(usb_device_class, NULL,
MKDEV(USB_DEVICE_MAJOR, minor), MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
"usbdev%d.%d", dev->bus->busnum, dev->devnum); "usbdev%d.%d", dev->bus->busnum, dev->devnum);
dev->usbfs_dev->platform_data = dev; dev->class_dev->class_data = dev;
} }
static void usbdev_remove(struct usb_device *dev) static void usbdev_remove(struct usb_device *dev)
{ {
device_unregister(dev->usbfs_dev); class_device_unregister(dev->class_dev);
} }
static int usbdev_notify(struct notifier_block *self, unsigned long action, static int usbdev_notify(struct notifier_block *self, unsigned long action,
......
...@@ -194,13 +194,14 @@ int usb_register_dev(struct usb_interface *intf, ...@@ -194,13 +194,14 @@ int usb_register_dev(struct usb_interface *intf,
++temp; ++temp;
else else
temp = name; temp = name;
intf->usb_dev = device_create(usb_class->class, &intf->dev, intf->class_dev = class_device_create(usb_class->class, NULL,
MKDEV(USB_MAJOR, minor), "%s", temp); MKDEV(USB_MAJOR, minor),
if (IS_ERR(intf->usb_dev)) { &intf->dev, "%s", temp);
if (IS_ERR(intf->class_dev)) {
spin_lock (&minor_lock); spin_lock (&minor_lock);
usb_minors[intf->minor] = NULL; usb_minors[intf->minor] = NULL;
spin_unlock (&minor_lock); spin_unlock (&minor_lock);
retval = PTR_ERR(intf->usb_dev); retval = PTR_ERR(intf->class_dev);
} }
exit: exit:
return retval; return retval;
...@@ -241,8 +242,8 @@ void usb_deregister_dev(struct usb_interface *intf, ...@@ -241,8 +242,8 @@ void usb_deregister_dev(struct usb_interface *intf,
spin_unlock (&minor_lock); spin_unlock (&minor_lock);
snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
intf->usb_dev = NULL; intf->class_dev = NULL;
intf->minor = -1; intf->minor = -1;
destroy_usb_class(); destroy_usb_class();
} }
......
...@@ -207,7 +207,7 @@ config USB_AT91 ...@@ -207,7 +207,7 @@ config USB_AT91
config USB_GADGET_DUMMY_HCD config USB_GADGET_DUMMY_HCD
boolean "Dummy HCD (DEVELOPMENT)" boolean "Dummy HCD (DEVELOPMENT)"
depends on USB && EXPERIMENTAL depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
select USB_GADGET_DUALSPEED select USB_GADGET_DUALSPEED
help help
This host controller driver emulates USB, looping all data transfer This host controller driver emulates USB, looping all data transfer
......
This diff is collapsed.
...@@ -141,6 +141,7 @@ struct at91_udc { ...@@ -141,6 +141,7 @@ struct at91_udc {
struct clk *iclk, *fclk; struct clk *iclk, *fclk;
struct platform_device *pdev; struct platform_device *pdev;
struct proc_dir_entry *pde; struct proc_dir_entry *pde;
int udp_irq;
}; };
static inline struct at91_udc *to_udc(struct usb_gadget *g) static inline struct at91_udc *to_udc(struct usb_gadget *g)
......
...@@ -609,7 +609,8 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) ...@@ -609,7 +609,8 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
if (!dum->driver) if (!dum->driver)
return -ESHUTDOWN; return -ESHUTDOWN;
spin_lock_irqsave (&dum->lock, flags); local_irq_save (flags);
spin_lock (&dum->lock);
list_for_each_entry (req, &ep->queue, queue) { list_for_each_entry (req, &ep->queue, queue) {
if (&req->req == _req) { if (&req->req == _req) {
list_del_init (&req->queue); list_del_init (&req->queue);
...@@ -618,7 +619,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) ...@@ -618,7 +619,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
break; break;
} }
} }
spin_unlock_irqrestore (&dum->lock, flags); spin_unlock (&dum->lock);
if (retval == 0) { if (retval == 0) {
dev_dbg (udc_dev(dum), dev_dbg (udc_dev(dum),
...@@ -626,6 +627,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) ...@@ -626,6 +627,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
req, _ep->name, _req->length, _req->buf); req, _ep->name, _req->length, _req->buf);
_req->complete (_ep, _req); _req->complete (_ep, _req);
} }
local_irq_restore (flags);
return retval; return retval;
} }
......
...@@ -892,7 +892,7 @@ MODULE_LICENSE ("GPL"); ...@@ -892,7 +892,7 @@ MODULE_LICENSE ("GPL");
#define PCI_DRIVER ehci_pci_driver #define PCI_DRIVER ehci_pci_driver
#endif #endif
#ifdef CONFIG_PPC_83xx #ifdef CONFIG_MPC834x
#include "ehci-fsl.c" #include "ehci-fsl.c"
#define PLATFORM_DRIVER ehci_fsl_driver #define PLATFORM_DRIVER ehci_fsl_driver
#endif #endif
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (C) 2004 SAN People (Pty) Ltd. * Copyright (C) 2004 SAN People (Pty) Ltd.
* Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
* *
* AT91RM9200 Bus Glue * AT91 Bus Glue
* *
* Based on fragments of 2.4 driver by Rick Bronson. * Based on fragments of 2.4 driver by Rick Bronson.
* Based on ohci-omap.c * Based on ohci-omap.c
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/arch/board.h> #include <asm/arch/board.h>
#ifndef CONFIG_ARCH_AT91RM9200 #ifndef CONFIG_ARCH_AT91
#error "CONFIG_ARCH_AT91RM9200 must be defined." #error "CONFIG_ARCH_AT91 must be defined."
#endif #endif
/* interface and function clocks */ /* interface and function clocks */
static struct clk *iclk, *fclk; static struct clk *iclk, *fclk;
static int clocked;
extern int usb_disabled(void); extern int usb_disabled(void);
...@@ -35,13 +36,14 @@ static void at91_start_hc(struct platform_device *pdev) ...@@ -35,13 +36,14 @@ static void at91_start_hc(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev); struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd->regs; struct ohci_regs __iomem *regs = hcd->regs;
dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n"); dev_dbg(&pdev->dev, "start\n");
/* /*
* Start the USB clocks. * Start the USB clocks.
*/ */
clk_enable(iclk); clk_enable(iclk);
clk_enable(fclk); clk_enable(fclk);
clocked = 1;
/* /*
* The USB host controller must remain in reset. * The USB host controller must remain in reset.
...@@ -54,7 +56,7 @@ static void at91_stop_hc(struct platform_device *pdev) ...@@ -54,7 +56,7 @@ static void at91_stop_hc(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev); struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_regs __iomem *regs = hcd->regs; struct ohci_regs __iomem *regs = hcd->regs;
dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n"); dev_dbg(&pdev->dev, "stop\n");
/* /*
* Put the USB host controller into reset. * Put the USB host controller into reset.
...@@ -66,6 +68,7 @@ static void at91_stop_hc(struct platform_device *pdev) ...@@ -66,6 +68,7 @@ static void at91_stop_hc(struct platform_device *pdev)
*/ */
clk_disable(fclk); clk_disable(fclk);
clk_disable(iclk); clk_disable(iclk);
clocked = 0;
} }
...@@ -78,14 +81,15 @@ static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); ...@@ -78,14 +81,15 @@ static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
/** /**
* usb_hcd_at91_probe - initialize AT91RM9200-based HCDs * usb_hcd_at91_probe - initialize AT91-based HCDs
* Context: !in_interrupt() * Context: !in_interrupt()
* *
* Allocates basic resources for this USB host controller, and * Allocates basic resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it * then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data. * through the hotplug entry's driver_data.
*/ */
int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev) static int usb_hcd_at91_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{ {
int retval; int retval;
struct usb_hcd *hcd = NULL; struct usb_hcd *hcd = NULL;
...@@ -95,12 +99,13 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device * ...@@ -95,12 +99,13 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *
return -ENODEV; return -ENODEV;
} }
if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) { if ((pdev->resource[0].flags != IORESOURCE_MEM)
|| (pdev->resource[1].flags != IORESOURCE_IRQ)) {
pr_debug("hcd probe: invalid resource type\n"); pr_debug("hcd probe: invalid resource type\n");
return -ENODEV; return -ENODEV;
} }
hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200"); hcd = usb_create_hcd(driver, &pdev->dev, "at91");
if (!hcd) if (!hcd)
return -ENOMEM; return -ENOMEM;
hcd->rsrc_start = pdev->resource[0].start; hcd->rsrc_start = pdev->resource[0].start;
...@@ -149,21 +154,23 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device * ...@@ -149,21 +154,23 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *
/* may be called with controller, bus, and devices active */ /* may be called with controller, bus, and devices active */
/** /**
* usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
* @dev: USB Host Controller being removed * @dev: USB Host Controller being removed
* Context: !in_interrupt() * Context: !in_interrupt()
* *
* Reverses the effect of usb_hcd_at91_probe(), first invoking * Reverses the effect of usb_hcd_at91_probe(), first invoking
* the HCD's stop() method. It is always called from a thread * the HCD's stop() method. It is always called from a thread
* context, normally "rmmod", "apmd", or something similar. * context, "rmmod" or something similar.
* *
*/ */
static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev) static int usb_hcd_at91_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{ {
usb_remove_hcd(hcd); usb_remove_hcd(hcd);
at91_stop_hc(pdev); at91_stop_hc(pdev);
iounmap(hcd->regs); iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len); release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
disable_irq_wake(hcd->irq);
clk_put(fclk); clk_put(fclk);
clk_put(iclk); clk_put(iclk);
...@@ -178,19 +185,21 @@ static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pde ...@@ -178,19 +185,21 @@ static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pde
static int __devinit static int __devinit
ohci_at91_start (struct usb_hcd *hcd) ohci_at91_start (struct usb_hcd *hcd)
{ {
// struct at91_ohci_data *board = hcd->self.controller->platform_data; struct at91_usbh_data *board = hcd->self.controller->platform_data;
struct ohci_hcd *ohci = hcd_to_ohci (hcd); struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct usb_device *root = hcd->self.root_hub;
int ret; int ret;
if ((ret = ohci_init(ohci)) < 0) if ((ret = ohci_init(ohci)) < 0)
return ret; return ret;
root->maxchild = board->ports;
if ((ret = ohci_run(ohci)) < 0) { if ((ret = ohci_run(ohci)) < 0) {
err("can't start %s", hcd->self.bus_name); err("can't start %s", hcd->self.bus_name);
ohci_stop(hcd); ohci_stop(hcd);
return ret; return ret;
} }
// hcd->self.root_hub->maxchild = board->ports;
return 0; return 0;
} }
...@@ -198,7 +207,7 @@ ohci_at91_start (struct usb_hcd *hcd) ...@@ -198,7 +207,7 @@ ohci_at91_start (struct usb_hcd *hcd)
static const struct hc_driver ohci_at91_hc_driver = { static const struct hc_driver ohci_at91_hc_driver = {
.description = hcd_name, .description = hcd_name,
.product_desc = "AT91RM9200 OHCI", .product_desc = "AT91 OHCI",
.hcd_priv_size = sizeof(struct ohci_hcd), .hcd_priv_size = sizeof(struct ohci_hcd),
/* /*
...@@ -240,33 +249,54 @@ static const struct hc_driver ohci_at91_hc_driver = { ...@@ -240,33 +249,54 @@ static const struct hc_driver ohci_at91_hc_driver = {
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int ohci_hcd_at91_drv_probe(struct platform_device *dev) static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{ {
return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev); device_init_wakeup(&pdev->dev, 1);
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
} }
static int ohci_hcd_at91_drv_remove(struct platform_device *dev) static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
{ {
return usb_hcd_at91_remove(platform_get_drvdata(dev), dev); device_init_wakeup(&pdev->dev, 0);
return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* REVISIT suspend/resume look "too" simple here */
static int static int
ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg) ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
{ {
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(hcd->irq);
else
disable_irq_wake(hcd->irq);
/*
* The integrated transceivers seem unable to notice disconnect,
* reconnect, or wakeup without the 48 MHz clock active. so for
* correctness, always discard connection state (using reset).
*
* REVISIT: some boards will be able to turn VBUS off...
*/
if (at91_suspend_entering_slow_clock()) {
ohci_usb_reset (ohci);
clk_disable(fclk); clk_disable(fclk);
clk_disable(iclk); clk_disable(iclk);
clocked = 0;
}
return 0; return 0;
} }
static int ohci_hcd_at91_drv_resume(struct platform_device *dev) static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
{ {
if (!clocked) {
clk_enable(iclk); clk_enable(iclk);
clk_enable(fclk); clk_enable(fclk);
}
return 0; return 0;
} }
...@@ -275,7 +305,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *dev) ...@@ -275,7 +305,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *dev)
#define ohci_hcd_at91_drv_resume NULL #define ohci_hcd_at91_drv_resume NULL
#endif #endif
MODULE_ALIAS("at91rm9200-ohci"); MODULE_ALIAS("at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = { static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe, .probe = ohci_hcd_at91_drv_probe,
...@@ -283,7 +313,7 @@ static struct platform_driver ohci_hcd_at91_driver = { ...@@ -283,7 +313,7 @@ static struct platform_driver ohci_hcd_at91_driver = {
.suspend = ohci_hcd_at91_drv_suspend, .suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume, .resume = ohci_hcd_at91_drv_resume,
.driver = { .driver = {
.name = "at91rm9200-ohci", .name = "at91_ohci",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
}; };
......
...@@ -913,7 +913,7 @@ MODULE_LICENSE ("GPL"); ...@@ -913,7 +913,7 @@ MODULE_LICENSE ("GPL");
#include "ohci-ppc-soc.c" #include "ohci-ppc-soc.c"
#endif #endif
#ifdef CONFIG_ARCH_AT91RM9200 #if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)
#include "ohci-at91.c" #include "ohci-at91.c"
#endif #endif
...@@ -927,6 +927,7 @@ MODULE_LICENSE ("GPL"); ...@@ -927,6 +927,7 @@ MODULE_LICENSE ("GPL");
|| defined (CONFIG_SOC_AU1X00) \ || defined (CONFIG_SOC_AU1X00) \
|| defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
|| defined (CONFIG_ARCH_AT91RM9200) \ || defined (CONFIG_ARCH_AT91RM9200) \
|| defined (CONFIG_ARCH_AT91SAM9261) \
) )
#error "missing bus glue for ohci-hcd" #error "missing bus glue for ohci-hcd"
#endif #endif
...@@ -943,7 +943,9 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) ...@@ -943,7 +943,9 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
/* We received a short packet */ /* We received a short packet */
if (urb->transfer_flags & URB_SHORT_NOT_OK) if (urb->transfer_flags & URB_SHORT_NOT_OK)
ret = -EREMOTEIO; ret = -EREMOTEIO;
else if (ctrlstat & TD_CTRL_SPD)
/* Fixup needed only if this isn't the URB's last TD */
else if (&td->list != urbp->td_list.prev)
ret = 1; ret = 1;
} }
......
...@@ -152,9 +152,8 @@ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; ...@@ -152,9 +152,8 @@ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
* events. The hardware generates 5 events for the first keypress * events. The hardware generates 5 events for the first keypress
* and we have to take this into account for an accurate repeat * and we have to take this into account for an accurate repeat
* behaviour. * behaviour.
* (HZ / 20) == 50 ms and works well for me.
*/ */
#define FILTER_TIME (HZ / 20) #define FILTER_TIME 60 /* msec */
struct ati_remote { struct ati_remote {
struct input_dev *idev; struct input_dev *idev;
...@@ -467,7 +466,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) ...@@ -467,7 +466,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
/* Filter duplicate events which happen "too close" together. */ /* Filter duplicate events which happen "too close" together. */
if ((ati_remote->old_data[0] == data[1]) && if ((ati_remote->old_data[0] == data[1]) &&
(ati_remote->old_data[1] == data[2]) && (ati_remote->old_data[1] == data[2]) &&
time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) { time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(FILTER_TIME))) {
ati_remote->repeat_count++; ati_remote->repeat_count++;
} else { } else {
ati_remote->repeat_count = 0; ati_remote->repeat_count = 0;
......
...@@ -12,8 +12,13 @@ ...@@ -12,8 +12,13 @@
* the single I/O ports of the device. * the single I/O ports of the device.
* *
* Supported vendors: AK Modul-Bus Computer GmbH * Supported vendors: AK Modul-Bus Computer GmbH
* Supported devices: CY7C63001A-PC (to be continued...) * (Firmware "Port-Chip")
* Supported functions: Read/Write Ports (to be continued...) *
* Supported devices: CY7C63001A-PC
* CY7C63001C-PXC
* CY7C63001C-SXC
*
* Supported functions: Read/Write Ports
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
......
...@@ -175,6 +175,8 @@ static inline struct sk_buff *pull_skb(rtl8150_t *); ...@@ -175,6 +175,8 @@ static inline struct sk_buff *pull_skb(rtl8150_t *);
static void rtl8150_disconnect(struct usb_interface *intf); static void rtl8150_disconnect(struct usb_interface *intf);
static int rtl8150_probe(struct usb_interface *intf, static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id); const struct usb_device_id *id);
static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message);
static int rtl8150_resume(struct usb_interface *intf);
static const char driver_name [] = "rtl8150"; static const char driver_name [] = "rtl8150";
...@@ -183,6 +185,8 @@ static struct usb_driver rtl8150_driver = { ...@@ -183,6 +185,8 @@ static struct usb_driver rtl8150_driver = {
.probe = rtl8150_probe, .probe = rtl8150_probe,
.disconnect = rtl8150_disconnect, .disconnect = rtl8150_disconnect,
.id_table = rtl8150_table, .id_table = rtl8150_table,
.suspend = rtl8150_suspend,
.resume = rtl8150_resume
}; };
/* /*
...@@ -238,9 +242,11 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size) ...@@ -238,9 +242,11 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
usb_fill_control_urb(dev->ctrl_urb, dev->udev, usb_fill_control_urb(dev->ctrl_urb, dev->udev,
usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
&dev->rx_creg, size, ctrl_callback, dev); &dev->rx_creg, size, ctrl_callback, dev);
if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
if (ret == -ENODEV)
netif_device_detach(dev->netdev);
err("control request submission failed: %d", ret); err("control request submission failed: %d", ret);
else } else
set_bit(RX_REG_SET, &dev->flags); set_bit(RX_REG_SET, &dev->flags);
return ret; return ret;
...@@ -416,6 +422,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) ...@@ -416,6 +422,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
struct sk_buff *skb; struct sk_buff *skb;
struct net_device *netdev; struct net_device *netdev;
u16 rx_stat; u16 rx_stat;
int status;
dev = urb->context; dev = urb->context;
if (!dev) if (!dev)
...@@ -465,7 +472,10 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) ...@@ -465,7 +472,10 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
goon: goon:
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
if (status == -ENODEV)
netif_device_detach(dev->netdev);
else if (status) {
set_bit(RX_URB_FAIL, &dev->flags); set_bit(RX_URB_FAIL, &dev->flags);
goto resched; goto resched;
} else { } else {
...@@ -481,6 +491,7 @@ static void rx_fixup(unsigned long data) ...@@ -481,6 +491,7 @@ static void rx_fixup(unsigned long data)
{ {
rtl8150_t *dev; rtl8150_t *dev;
struct sk_buff *skb; struct sk_buff *skb;
int status;
dev = (rtl8150_t *)data; dev = (rtl8150_t *)data;
...@@ -499,7 +510,10 @@ static void rx_fixup(unsigned long data) ...@@ -499,7 +510,10 @@ static void rx_fixup(unsigned long data)
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
try_again: try_again:
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
if (status == -ENODEV) {
netif_device_detach(dev->netdev);
} else if (status) {
set_bit(RX_URB_FAIL, &dev->flags); set_bit(RX_URB_FAIL, &dev->flags);
goto tlsched; goto tlsched;
} else { } else {
...@@ -574,12 +588,43 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs) ...@@ -574,12 +588,43 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs)
resubmit: resubmit:
status = usb_submit_urb (urb, SLAB_ATOMIC); status = usb_submit_urb (urb, SLAB_ATOMIC);
if (status) if (status == -ENODEV)
netif_device_detach(dev->netdev);
else if (status)
err ("can't resubmit intr, %s-%s/input0, status %d", err ("can't resubmit intr, %s-%s/input0, status %d",
dev->udev->bus->bus_name, dev->udev->bus->bus_name,
dev->udev->devpath, status); dev->udev->devpath, status);
} }
static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message)
{
rtl8150_t *dev = usb_get_intfdata(intf);
netif_device_detach(dev->netdev);
if (netif_running(dev->netdev)) {
usb_kill_urb(dev->rx_urb);
usb_kill_urb(dev->intr_urb);
}
return 0;
}
static int rtl8150_resume(struct usb_interface *intf)
{
rtl8150_t *dev = usb_get_intfdata(intf);
netif_device_attach(dev->netdev);
if (netif_running(dev->netdev)) {
dev->rx_urb->status = 0;
dev->rx_urb->actual_length = 0;
read_bulk_callback(dev->rx_urb, NULL);
dev->intr_urb->status = 0;
dev->intr_urb->actual_length = 0;
intr_callback(dev->intr_urb, NULL);
}
return 0;
}
/* /*
** **
...@@ -690,9 +735,14 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -690,9 +735,14 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
skb->data, count, write_bulk_callback, dev); skb->data, count, write_bulk_callback, dev);
if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) { if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
/* Can we get/handle EPIPE here? */
if (res == -ENODEV)
netif_device_detach(dev->netdev);
else {
warn("failed tx_urb %d\n", res); warn("failed tx_urb %d\n", res);
dev->stats.tx_errors++; dev->stats.tx_errors++;
netif_start_queue(netdev); netif_start_queue(netdev);
}
} else { } else {
dev->stats.tx_packets++; dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
...@@ -729,16 +779,25 @@ static int rtl8150_open(struct net_device *netdev) ...@@ -729,16 +779,25 @@ static int rtl8150_open(struct net_device *netdev)
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
if (res == -ENODEV)
netif_device_detach(dev->netdev);
warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
return res;
}
usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
dev->intr_buff, INTBUFSIZE, intr_callback, dev->intr_buff, INTBUFSIZE, intr_callback,
dev, dev->intr_interval); dev, dev->intr_interval);
if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
if (res == -ENODEV)
netif_device_detach(dev->netdev);
warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
netif_start_queue(netdev); usb_kill_urb(dev->rx_urb);
return res;
}
enable_net_traffic(dev); enable_net_traffic(dev);
set_carrier(netdev); set_carrier(netdev);
netif_start_queue(netdev);
return res; return res;
} }
......
...@@ -62,15 +62,6 @@ config USB_SERIAL_AIRPRIME ...@@ -62,15 +62,6 @@ config USB_SERIAL_AIRPRIME
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called airprime. module will be called airprime.
config USB_SERIAL_ANYDATA
tristate "USB AnyData CDMA Wireless Driver"
depends on USB_SERIAL
help
Say Y here if you want to use a AnyData CDMA device.
To compile this driver as a module, choose M here: the
module will be called anydata.
config USB_SERIAL_ARK3116 config USB_SERIAL_ARK3116
tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL depends on USB_SERIAL && EXPERIMENTAL
...@@ -502,15 +493,18 @@ config USB_SERIAL_XIRCOM ...@@ -502,15 +493,18 @@ config USB_SERIAL_XIRCOM
module will be called keyspan_pda. module will be called keyspan_pda.
config USB_SERIAL_OPTION config USB_SERIAL_OPTION
tristate "USB driver for GSM modems" tristate "USB driver for GSM and CDMA modems"
depends on USB_SERIAL depends on USB_SERIAL
help help
Say Y here if you have an "Option" GSM PCMCIA card Say Y here if you have a GSM or CDMA modem that's connected to USB.
(or an OEM version: branded Huawei, Audiovox, or Novatel).
This driver also supports several PCMCIA cards which have a
built-in OHCI-USB adapter and an internally-connected GSM modem.
The USB bus on these cards is not accessible externally.
These cards feature a built-in OHCI-USB adapter and an Supported devices include (some of?) those made by:
internally-connected GSM modem. The USB bus is not Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or
accessible externally. Anydata.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called option. module will be called option.
......
...@@ -12,7 +12,6 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o ...@@ -12,7 +12,6 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o
usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y)
obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o
obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o
obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o
obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o
obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o
......
/*
* AnyData CDMA Serial USB driver
*
* Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
/* if overridden by the user, then use their value for the size of the
* read and write urbs */
static int buffer_size;
static int debug;
static struct usb_driver anydata_driver = {
.name = "anydata",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
.no_dynamic_id = 1,
};
static int anydata_open(struct usb_serial_port *port, struct file *filp)
{
char *buffer;
int result = 0;
dbg("%s - port %d", __FUNCTION__, port->number);
if (buffer_size) {
/* override the default buffer sizes */
buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!buffer) {
dev_err(&port->dev, "%s - out of memory.\n",
__FUNCTION__);
return -ENOMEM;
}
kfree (port->read_urb->transfer_buffer);
port->read_urb->transfer_buffer = buffer;
port->read_urb->transfer_buffer_length = buffer_size;
buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!buffer) {
dev_err(&port->dev, "%s - out of memory.\n",
__FUNCTION__);
return -ENOMEM;
}
kfree (port->write_urb->transfer_buffer);
port->write_urb->transfer_buffer = buffer;
port->write_urb->transfer_buffer_length = buffer_size;
port->bulk_out_size = buffer_size;
}
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, port->serial->dev,
usb_rcvbulkpipe(port->serial->dev,
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
usb_serial_generic_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
dev_err(&port->dev,
"%s - failed submitting read urb, error %d\n",
__FUNCTION__, result);
return result;
}
static struct usb_serial_driver anydata_device = {
.driver = {
.owner = THIS_MODULE,
.name = "anydata",
},
.id_table = id_table,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 1,
.open = anydata_open,
};
static int __init anydata_init(void)
{
int retval;
retval = usb_serial_register(&anydata_device);
if (retval)
return retval;
retval = usb_register(&anydata_driver);
if (retval)
usb_serial_deregister(&anydata_device);
return retval;
}
static void __exit anydata_exit(void)
{
usb_deregister(&anydata_driver);
usb_serial_deregister(&anydata_device);
}
module_init(anydata_init);
module_exit(anydata_exit);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(buffer_size, int, 0);
MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");
...@@ -337,6 +337,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -337,6 +337,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
......
...@@ -182,6 +182,10 @@ ...@@ -182,6 +182,10 @@
/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ #define FTDI_USB_UIRT_PID 0xF850 /* Product Id */
/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */
#define FTDI_TNC_X_PID 0xEBE0
/* /*
* ELV USB devices submitted by Christian Abt of ELV (www.elv.de). * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
* All of these devices use FTDI's vendor ID (0x0403). * All of these devices use FTDI's vendor ID (0x0403).
......
...@@ -250,6 +250,7 @@ static struct usb_device_id ipaq_id_table [] = { ...@@ -250,6 +250,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
{ USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
{ USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */
{ USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
{ USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
{ USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
......
...@@ -9,40 +9,14 @@ ...@@ -9,40 +9,14 @@
Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
History: History: see the git log.
2005-05-19 v0.1 Initial version, based on incomplete docs
and analysis of misbehavior with the standard driver
2005-05-20 v0.2 Extended the input buffer to avoid losing
random 64-byte chunks of data
2005-05-21 v0.3 implemented chars_in_buffer()
turned on low_latency
simplified the code somewhat
2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load
removed some dead code
added sponsor notice
coding style clean-up
2005-06-20 v0.4.1 add missing braces :-/
killed end-of-line whitespace
2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2
2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard
2005-09-20 v0.4.4 increased recv buffer size: the card sometimes
wants to send >2000 bytes.
2006-04-10 v0.5 fixed two array overrun errors :-/
2006-04-21 v0.5.1 added support for Sierra Wireless MC8755
2006-05-15 v0.6 re-enable multi-port support
2006-06-01 v0.6.1 add COBRA
2006-06-01 v0.6.2 add backwards-compatibility stuff
2006-06-01 v0.6.3 add Novatel Wireless
2006-06-01 v0.7 Option => GSM
2006-06-01 v0.7.1 add COBRA2
Work sponsored by: Sigos GmbH, Germany <info@sigos.de> Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
This driver exists because the "normal" serial driver doesn't work too well This driver exists because the "normal" serial driver doesn't work too well
with GSM modems. Issues: with GSM modems. Issues:
- data loss -- one single Receive URB is not nearly enough - data loss -- one single Receive URB is not nearly enough
- nonstandard flow (Option devices) and multiplex (Sierra) control - nonstandard flow (Option devices) control
- controlling the baud rate doesn't make sense - controlling the baud rate doesn't make sense
This driver is named "option" because the most common device it's This driver is named "option" because the most common device it's
...@@ -96,8 +70,8 @@ static int option_send_setup(struct usb_serial_port *port); ...@@ -96,8 +70,8 @@ static int option_send_setup(struct usb_serial_port *port);
#define OPTION_VENDOR_ID 0x0AF0 #define OPTION_VENDOR_ID 0x0AF0
#define HUAWEI_VENDOR_ID 0x12D1 #define HUAWEI_VENDOR_ID 0x12D1
#define AUDIOVOX_VENDOR_ID 0x0F3D #define AUDIOVOX_VENDOR_ID 0x0F3D
#define SIERRAWIRELESS_VENDOR_ID 0x1199
#define NOVATELWIRELESS_VENDOR_ID 0x1410 #define NOVATELWIRELESS_VENDOR_ID 0x1410
#define ANYDATA_VENDOR_ID 0x16d5
#define OPTION_PRODUCT_OLD 0x5000 #define OPTION_PRODUCT_OLD 0x5000
#define OPTION_PRODUCT_FUSION 0x6000 #define OPTION_PRODUCT_FUSION 0x6000
...@@ -106,8 +80,8 @@ static int option_send_setup(struct usb_serial_port *port); ...@@ -106,8 +80,8 @@ static int option_send_setup(struct usb_serial_port *port);
#define OPTION_PRODUCT_COBRA2 0x6600 #define OPTION_PRODUCT_COBRA2 0x6600
#define HUAWEI_PRODUCT_E600 0x1001 #define HUAWEI_PRODUCT_E600 0x1001
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112 #define AUDIOVOX_PRODUCT_AIRCARD 0x0112
#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802
#define NOVATELWIRELESS_PRODUCT_U740 0x1400 #define NOVATELWIRELESS_PRODUCT_U740 0x1400
#define ANYDATA_PRODUCT_ID 0x6501
static struct usb_device_id option_ids[] = { static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
...@@ -117,8 +91,8 @@ static struct usb_device_id option_ids[] = { ...@@ -117,8 +91,8 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -131,10 +105,7 @@ static struct usb_device_id option_ids1[] = { ...@@ -131,10 +105,7 @@ static struct usb_device_id option_ids1[] = {
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ } /* Terminating entry */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
};
static struct usb_device_id option_ids3[] = {
{ USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -151,37 +122,11 @@ static struct usb_driver option_driver = { ...@@ -151,37 +122,11 @@ static struct usb_driver option_driver = {
/* The card has three separate interfaces, which the serial driver /* The card has three separate interfaces, which the serial driver
* recognizes separately, thus num_port=1. * recognizes separately, thus num_port=1.
*/ */
static struct usb_serial_driver option_3port_device = {
.driver = {
.owner = THIS_MODULE,
.name = "option",
},
.description = "GSM modem (3-port)",
.id_table = option_ids3,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 3,
.open = option_open,
.close = option_close,
.write = option_write,
.write_room = option_write_room,
.chars_in_buffer = option_chars_in_buffer,
.throttle = option_rx_throttle,
.unthrottle = option_rx_unthrottle,
.set_termios = option_set_termios,
.break_ctl = option_break_ctl,
.tiocmget = option_tiocmget,
.tiocmset = option_tiocmset,
.attach = option_startup,
.shutdown = option_shutdown,
.read_int_callback = option_instat_callback,
};
static struct usb_serial_driver option_1port_device = { static struct usb_serial_driver option_1port_device = {
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "option", .name = "option1",
}, },
.description = "GSM modem (1-port)", .description = "GSM modem (1-port)",
.id_table = option_ids1, .id_table = option_ids1,
...@@ -245,9 +190,6 @@ static int __init option_init(void) ...@@ -245,9 +190,6 @@ static int __init option_init(void)
retval = usb_serial_register(&option_1port_device); retval = usb_serial_register(&option_1port_device);
if (retval) if (retval)
goto failed_1port_device_register; goto failed_1port_device_register;
retval = usb_serial_register(&option_3port_device);
if (retval)
goto failed_3port_device_register;
retval = usb_register(&option_driver); retval = usb_register(&option_driver);
if (retval) if (retval)
goto failed_driver_register; goto failed_driver_register;
...@@ -257,8 +199,6 @@ static int __init option_init(void) ...@@ -257,8 +199,6 @@ static int __init option_init(void)
return 0; return 0;
failed_driver_register: failed_driver_register:
usb_serial_deregister (&option_3port_device);
failed_3port_device_register:
usb_serial_deregister (&option_1port_device); usb_serial_deregister (&option_1port_device);
failed_1port_device_register: failed_1port_device_register:
return retval; return retval;
...@@ -267,7 +207,6 @@ static int __init option_init(void) ...@@ -267,7 +207,6 @@ static int __init option_init(void)
static void __exit option_exit(void) static void __exit option_exit(void)
{ {
usb_deregister (&option_driver); usb_deregister (&option_driver);
usb_serial_deregister (&option_3port_device);
usb_serial_deregister (&option_1port_device); usb_serial_deregister (&option_1port_device);
} }
...@@ -656,7 +595,6 @@ static void option_setup_urbs(struct usb_serial *serial) ...@@ -656,7 +595,6 @@ static void option_setup_urbs(struct usb_serial *serial)
dbg("%s", __FUNCTION__); dbg("%s", __FUNCTION__);
for (i = 0; i < serial->num_ports; i++) { for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i]; port = serial->port[i];
portdata = usb_get_serial_port_data(port); portdata = usb_get_serial_port_data(port);
......
...@@ -81,6 +81,7 @@ static struct usb_device_id id_table [] = { ...@@ -81,6 +81,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
{ USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) },
{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -89,3 +89,7 @@ ...@@ -89,3 +89,7 @@
/* DATAPILOT Universal-2 Phone Cable */ /* DATAPILOT Universal-2 Phone Cable */
#define DATAPILOT_U2_VENDOR_ID 0x0731 #define DATAPILOT_U2_VENDOR_ID 0x0731
#define DATAPILOT_U2_PRODUCT_ID 0x2003 #define DATAPILOT_U2_PRODUCT_ID 0x2003
/* Belkin "F5U257" Serial Adapter */
#define BELKIN_VENDOR_ID 0x050d
#define BELKIN_PRODUCT_ID 0x0257
...@@ -145,6 +145,13 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, ...@@ -145,6 +145,13 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ), US_FL_IGNORE_RESIDUE ),
/* Reported by Mario Rettig <mariorettig@web.de> */
UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100,
"Nokia",
"Nokia 3250",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
/* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and /* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and
* Einar Th. Einarsson <einarthered@gmail.com> */ * Einar Th. Einarsson <einarthered@gmail.com> */
UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100, UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100,
...@@ -627,18 +634,6 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, ...@@ -627,18 +634,6 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
"Digital Camera EX-20 DSC", "Digital Camera EX-20 DSC",
US_SC_8070, US_PR_DEVICE, NULL, 0 ), US_SC_8070, US_PR_DEVICE, NULL, 0 ),
/* The entry was here before I took over, and had US_SC_RBC. It turns
* out that isn't needed. Additionally, Torsten Eriksson
* <Torsten.Eriksson@bergianska.se> is able to use his device fine
* without this entry at all - but I don't suspect that will be true
* for all users (the protocol is likely needed), so is staying at
* this time. - Phil Dibowitz <phil@ipom.com>
*/
UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200,
"LaCie",
"USB Hard Disk",
US_SC_DEVICE, US_PR_CB, NULL, 0 ),
/* Submitted by Joel Bourquard <numlock@freesurf.ch> /* Submitted by Joel Bourquard <numlock@freesurf.ch>
* Some versions of this device need the SubClass and Protocol overrides * Some versions of this device need the SubClass and Protocol overrides
* while others don't. * while others don't.
...@@ -1107,6 +1102,14 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, ...@@ -1107,6 +1102,14 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ), US_FL_FIX_INQUIRY ),
/* This is a virtual windows driver CD, which the zd1211rw driver automatically
* converts into a WLAN device. */
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
"ZyXEL",
"G-220F USB-WLAN Install",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_DEVICE ),
#ifdef CONFIG_USB_STORAGE_ISD200 #ifdef CONFIG_USB_STORAGE_ISD200
UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
"ATI", "ATI",
......
...@@ -483,7 +483,7 @@ static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) ...@@ -483,7 +483,7 @@ static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
} }
/* Get the unusual_devs entries and the string descriptors */ /* Get the unusual_devs entries and the string descriptors */
static void get_device_info(struct us_data *us, const struct usb_device_id *id) static int get_device_info(struct us_data *us, const struct usb_device_id *id)
{ {
struct usb_device *dev = us->pusb_dev; struct usb_device *dev = us->pusb_dev;
struct usb_interface_descriptor *idesc = struct usb_interface_descriptor *idesc =
...@@ -500,6 +500,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id) ...@@ -500,6 +500,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
unusual_dev->useTransport; unusual_dev->useTransport;
us->flags = USB_US_ORIG_FLAGS(id->driver_info); us->flags = USB_US_ORIG_FLAGS(id->driver_info);
if (us->flags & US_FL_IGNORE_DEVICE) {
printk(KERN_INFO USB_STORAGE "device ignored\n");
return -ENODEV;
}
/* /*
* This flag is only needed when we're in high-speed, so let's * This flag is only needed when we're in high-speed, so let's
* disable it if we're in full-speed * disable it if we're in full-speed
...@@ -541,6 +546,8 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id) ...@@ -541,6 +546,8 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
msgs[msg], msgs[msg],
UTS_RELEASE); UTS_RELEASE);
} }
return 0;
} }
/* Get the transport settings */ /* Get the transport settings */
...@@ -969,7 +976,9 @@ static int storage_probe(struct usb_interface *intf, ...@@ -969,7 +976,9 @@ static int storage_probe(struct usb_interface *intf,
* of the match from the usb_device_id table, so we can find the * of the match from the usb_device_id table, so we can find the
* corresponding entry in the private table. * corresponding entry in the private table.
*/ */
get_device_info(us, id); result = get_device_info(us, id);
if (result)
goto BadDevice;
/* Get the transport, protocol, and pipe settings */ /* Get the transport, protocol, and pipe settings */
result = get_transport(us); result = get_transport(us);
......
...@@ -103,8 +103,7 @@ enum usb_interface_condition { ...@@ -103,8 +103,7 @@ enum usb_interface_condition {
* @condition: binding state of the interface: not bound, binding * @condition: binding state of the interface: not bound, binding
* (in probe()), bound to a driver, or unbinding (in disconnect()) * (in probe()), bound to a driver, or unbinding (in disconnect())
* @dev: driver model's view of this device * @dev: driver model's view of this device
* @usb_dev: if an interface is bound to the USB major, this will point * @class_dev: driver model's class view of this device.
* to the sysfs representation for that device.
* *
* USB device drivers attach to interfaces on a physical device. Each * USB device drivers attach to interfaces on a physical device. Each
* interface encapsulates a single high level function, such as feeding * interface encapsulates a single high level function, such as feeding
...@@ -144,7 +143,7 @@ struct usb_interface { ...@@ -144,7 +143,7 @@ struct usb_interface {
* bound to */ * bound to */
enum usb_interface_condition condition; /* state of binding */ enum usb_interface_condition condition; /* state of binding */
struct device dev; /* interface specific device info */ struct device dev; /* interface specific device info */
struct device *usb_dev; /* pointer to the usb class's device, if any */ struct class_device *class_dev;
}; };
#define to_usb_interface(d) container_of(d, struct usb_interface, dev) #define to_usb_interface(d) container_of(d, struct usb_interface, dev)
#define interface_to_usbdev(intf) \ #define interface_to_usbdev(intf) \
...@@ -361,7 +360,7 @@ struct usb_device { ...@@ -361,7 +360,7 @@ struct usb_device {
char *serial; /* iSerialNumber string, if present */ char *serial; /* iSerialNumber string, if present */
struct list_head filelist; struct list_head filelist;
struct device *usbfs_dev; struct class_device *class_dev;
struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
/* /*
......
...@@ -44,7 +44,9 @@ ...@@ -44,7 +44,9 @@
US_FLAG(NO_WP_DETECT, 0x00000200) \ US_FLAG(NO_WP_DETECT, 0x00000200) \
/* Don't check for write-protect */ \ /* Don't check for write-protect */ \
US_FLAG(MAX_SECTORS_64, 0x00000400) \ US_FLAG(MAX_SECTORS_64, 0x00000400) \
/* Sets max_sectors to 64 */ /* Sets max_sectors to 64 */ \
US_FLAG(IGNORE_DEVICE, 0x00000800) \
/* Don't claim device */
#define US_FLAG(name, value) US_FL_##name = value , #define US_FLAG(name, value) US_FL_##name = value ,
enum { US_DO_ALL_FLAGS }; enum { US_DO_ALL_FLAGS };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment