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
would issue more ioctls to the device to communicate to it using
control, bulk, or other kinds of USB transfers. The IOCTLs are
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.
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
Documentation/usb/*, see the following:
Linux-USB project: http://www.linux-usb.org
mirrors at http://www.suse.cz/development/linux-usb/
and http://usb.in.tum.de/linux-usb/
mirrors at http://usb.in.tum.de/linux-usb/
and http://it.linux-usb.org
Linux USB Guide: http://linux-usb.sourceforge.net
Linux-USB device overview (working devices and drivers):
......
......@@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI
default y if ARCH_S3C2410
default y if PXA27x
default y if ARCH_EP93XX
default y if ARCH_AT91RM9200
default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261)
# PPC:
default y if STB03xxx
default y if PPC_MPC52xx
......
......@@ -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)
{
struct device *device;
struct usb_device *udev = NULL;
struct class_device *class_dev;
struct usb_device *dev = NULL;
down(&usb_device_class->sem);
list_for_each_entry(device, &usb_device_class->devices, node) {
if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
udev = device->platform_data;
list_for_each_entry(class_dev, &usb_device_class->children, node) {
if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
dev = class_dev->class_data;
break;
}
}
up(&usb_device_class->sem);
return udev;
return dev;
};
/*
......@@ -1580,16 +1580,16 @@ static void usbdev_add(struct usb_device *dev)
{
int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
dev->usbfs_dev = device_create(usb_device_class, &dev->dev,
MKDEV(USB_DEVICE_MAJOR, minor),
dev->class_dev = class_device_create(usb_device_class, NULL,
MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
"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)
{
device_unregister(dev->usbfs_dev);
class_device_unregister(dev->class_dev);
}
static int usbdev_notify(struct notifier_block *self, unsigned long action,
......
......@@ -194,13 +194,14 @@ int usb_register_dev(struct usb_interface *intf,
++temp;
else
temp = name;
intf->usb_dev = device_create(usb_class->class, &intf->dev,
MKDEV(USB_MAJOR, minor), "%s", temp);
if (IS_ERR(intf->usb_dev)) {
intf->class_dev = class_device_create(usb_class->class, NULL,
MKDEV(USB_MAJOR, minor),
&intf->dev, "%s", temp);
if (IS_ERR(intf->class_dev)) {
spin_lock (&minor_lock);
usb_minors[intf->minor] = NULL;
spin_unlock (&minor_lock);
retval = PTR_ERR(intf->usb_dev);
retval = PTR_ERR(intf->class_dev);
}
exit:
return retval;
......@@ -241,8 +242,8 @@ void usb_deregister_dev(struct usb_interface *intf,
spin_unlock (&minor_lock);
snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
intf->usb_dev = NULL;
class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
intf->class_dev = NULL;
intf->minor = -1;
destroy_usb_class();
}
......
......@@ -207,7 +207,7 @@ config USB_AT91
config USB_GADGET_DUMMY_HCD
boolean "Dummy HCD (DEVELOPMENT)"
depends on USB && EXPERIMENTAL
depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
select USB_GADGET_DUALSPEED
help
This host controller driver emulates USB, looping all data transfer
......
......@@ -57,19 +57,23 @@
/*
* This controller is simple and PIO-only. It's used in many AT91-series
* ARMv4T controllers, including the at91rm9200 (arm920T, with MMU),
* at91sam9261 (arm926ejs, with MMU), and several no-mmu versions.
* full speed USB controllers, including the at91rm9200 (arm920T, with MMU),
* at91sam926x (arm926ejs, with MMU), and several no-mmu versions.
*
* This driver expects the board has been wired with two GPIOs suppporting
* a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the
* testing hasn't covered such cases.) The pullup is most important; it
* testing hasn't covered such cases.)
*
* The pullup is most important (so it's integrated on sam926x parts). It
* provides software control over whether the host enumerates the device.
*
* The VBUS sensing helps during enumeration, and allows both USB clocks
* (and the transceiver) to stay gated off until they're necessary, saving
* power. During USB suspend, the 48 MHz clock is gated off.
* power. During USB suspend, the 48 MHz clock is gated off in hardware;
* it may also be gated off by software during some Linux sleep states.
*/
#define DRIVER_VERSION "8 March 2005"
#define DRIVER_VERSION "3 May 2006"
static const char driver_name [] = "at91_udc";
static const char ep0name[] = "ep0";
......@@ -316,9 +320,15 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status)
*
* There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE
* that shouldn't normally be changed.
*
* NOTE at91sam9260 docs mention synch between UDPCK and MCK clock domains,
* implying a need to wait for one write to complete (test relevant bits)
* before starting the next write. This shouldn't be an issue given how
* infrequently we write, except maybe for write-then-read idioms.
*/
#define SET_FX (AT91_UDP_TXPKTRDY)
#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP \
| AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
/* pull OUT packet data from the endpoint's fifo */
static int read_fifo (struct at91_ep *ep, struct at91_request *req)
......@@ -472,7 +482,8 @@ static void nuke(struct at91_ep *ep, int status)
/*-------------------------------------------------------------------------*/
static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
static int at91_ep_enable(struct usb_ep *_ep,
const struct usb_endpoint_descriptor *desc)
{
struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
struct at91_udc *dev = ep->udc;
......@@ -582,11 +593,12 @@ static int at91_ep_disable (struct usb_ep * _ep)
* interesting for request or buffer allocation.
*/
static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags)
static struct usb_request *
at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags)
{
struct at91_request *req;
req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL);
req = kcalloc(1, sizeof (struct at91_request), gfp_flags);
if (!req)
return NULL;
......@@ -862,6 +874,7 @@ static void stop_activity(struct at91_udc *udc)
if (udc->gadget.speed == USB_SPEED_UNKNOWN)
driver = NULL;
udc->gadget.speed = USB_SPEED_UNKNOWN;
udc->suspended = 0;
for (i = 0; i < NUM_ENDPOINTS; i++) {
struct at91_ep *ep = &udc->ep[i];
......@@ -889,8 +902,8 @@ static void clk_off(struct at91_udc *udc)
return;
udc->clocked = 0;
udc->gadget.speed = USB_SPEED_UNKNOWN;
clk_disable(udc->iclk);
clk_disable(udc->fclk);
clk_disable(udc->iclk);
}
/*
......@@ -911,9 +924,6 @@ static void pullup(struct at91_udc *udc, int is_on)
at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_set_gpio_value(udc->board.pullup_pin, 0);
clk_off(udc);
// REVISIT: with transceiver disabled, will D- float
// so that a host would falsely detect a device?
}
}
......@@ -1290,7 +1300,8 @@ static void handle_ep0(struct at91_udc *udc)
if (udc->wait_for_addr_ack) {
u32 tmp;
at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr);
at91_udp_write(AT91_UDP_FADDR,
AT91_UDP_FEN | udc->addr);
tmp = at91_udp_read(AT91_UDP_GLB_STAT);
tmp &= ~AT91_UDP_FADDEN;
if (udc->addr)
......@@ -1361,9 +1372,10 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
u32 rescans = 5;
while (rescans--) {
u32 status = at91_udp_read(AT91_UDP_ISR);
u32 status;
status &= at91_udp_read(AT91_UDP_IMR);
status = at91_udp_read(AT91_UDP_ISR)
& at91_udp_read(AT91_UDP_IMR);
if (!status)
break;
......@@ -1379,18 +1391,17 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
stop_activity(udc);
/* enable ep0 */
at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
at91_udp_write(AT91_UDP_CSR(0),
AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
udc->gadget.speed = USB_SPEED_FULL;
udc->suspended = 0;
at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
/*
* NOTE: this driver keeps clocks off unless the
* USB host is present. That saves power, and also
* eliminates IRQs (reset, resume, suspend) that can
* otherwise flood from the controller. If your
* board doesn't support VBUS detection, suspend and
* resume irq logic may need more attention...
* USB host is present. That saves power, but for
* boards that don't support VBUS detection, both
* clocks need to be active most of the time.
*/
/* host initiated suspend (3+ms bus idle) */
......@@ -1452,13 +1463,19 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
/*-------------------------------------------------------------------------*/
static void nop_release(struct device *dev)
{
/* nothing to free */
}
static struct at91_udc controller = {
.gadget = {
.ops = &at91_udc_ops,
.ep0 = &controller.ep[0].ep,
.name = driver_name,
.dev = {
.bus_id = "gadget"
.ops = &at91_udc_ops,
.ep0 = &controller.ep[0].ep,
.name = driver_name,
.dev = {
.bus_id = "gadget",
.release = nop_release,
}
},
.ep[0] = {
......@@ -1468,7 +1485,8 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(0)),
.int_mask = 1 << 0,
},
.ep[1] = {
......@@ -1479,7 +1497,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(1)),
.int_mask = 1 << 1,
},
.ep[2] = {
......@@ -1490,7 +1509,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 64,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(2)),
.int_mask = 1 << 2,
},
.ep[3] = {
......@@ -1501,7 +1521,8 @@ static struct at91_udc controller = {
},
.udc = &controller,
.maxpacket = 8,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(3)),
.int_mask = 1 << 3,
},
.ep[4] = {
......@@ -1512,7 +1533,8 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(4)),
.int_mask = 1 << 4,
},
.ep[5] = {
......@@ -1523,10 +1545,11 @@ static struct at91_udc controller = {
.udc = &controller,
.is_pingpong = 1,
.maxpacket = 256,
.creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)),
.creg = (void __iomem *)(AT91_VA_BASE_UDP
+ AT91_UDP_CSR(5)),
.int_mask = 1 << 5,
},
/* ep6 and ep7 are also reserved */
/* ep6 and ep7 are also reserved (custom silicon might use them) */
};
static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r)
......@@ -1593,6 +1616,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
local_irq_disable();
udc->enabled = 0;
at91_udp_write(AT91_UDP_IDR, ~0);
pullup(udc, 0);
local_irq_enable();
......@@ -1624,6 +1648,16 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
return -ENODEV;
}
if (pdev->num_resources != 2) {
DBG("invalid num_resources");
return -ENODEV;
}
if ((pdev->resource[0].flags != IORESOURCE_MEM)
|| (pdev->resource[1].flags != IORESOURCE_IRQ)) {
DBG("invalid resource type");
return -ENODEV;
}
if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) {
DBG("someone's using UDC memory\n");
return -EBUSY;
......@@ -1649,19 +1683,26 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
if (retval < 0)
goto fail0;
/* disable everything until there's a gadget driver and vbus */
pullup(udc, 0);
/* don't do anything until we have both gadget driver and VBUS */
clk_enable(udc->iclk);
at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_udp_write(AT91_UDP_IDR, 0xffffffff);
clk_disable(udc->iclk);
/* request UDC and maybe VBUS irqs */
if (request_irq(AT91_ID_UDP, at91_udc_irq, IRQF_DISABLED, driver_name, udc)) {
DBG("request irq %d failed\n", AT91_ID_UDP);
udc->udp_irq = platform_get_irq(pdev, 0);
if (request_irq(udc->udp_irq, at91_udc_irq,
IRQF_DISABLED, driver_name, udc)) {
DBG("request irq %d failed\n", udc->udp_irq);
retval = -EBUSY;
goto fail1;
}
if (udc->board.vbus_pin > 0) {
if (request_irq(udc->board.vbus_pin, at91_vbus_irq, IRQF_DISABLED, driver_name, udc)) {
DBG("request vbus irq %d failed\n", udc->board.vbus_pin);
free_irq(AT91_ID_UDP, udc);
if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
IRQF_DISABLED, driver_name, udc)) {
DBG("request vbus irq %d failed\n",
udc->board.vbus_pin);
free_irq(udc->udp_irq, udc);
retval = -EBUSY;
goto fail1;
}
......@@ -1670,6 +1711,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
udc->vbus = 1;
}
dev_set_drvdata(dev, udc);
device_init_wakeup(dev, 1);
create_debug_file(udc);
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
......@@ -1678,14 +1720,14 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
fail1:
device_unregister(&udc->gadget.dev);
fail0:
release_mem_region(AT91_VA_BASE_UDP, SZ_16K);
release_mem_region(AT91_BASE_UDP, SZ_16K);
DBG("%s probe failed, %d\n", driver_name, retval);
return retval;
}
static int __devexit at91udc_remove(struct platform_device *dev)
static int __devexit at91udc_remove(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(dev);
struct at91_udc *udc = platform_get_drvdata(pdev);
DBG("remove\n");
......@@ -1694,10 +1736,11 @@ static int __devexit at91udc_remove(struct platform_device *dev)
if (udc->driver != 0)
usb_gadget_unregister_driver(udc->driver);
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
if (udc->board.vbus_pin > 0)
free_irq(udc->board.vbus_pin, udc);
free_irq(AT91_ID_UDP, udc);
free_irq(udc->udp_irq, udc);
device_unregister(&udc->gadget.dev);
release_mem_region(AT91_BASE_UDP, SZ_16K);
......@@ -1708,31 +1751,36 @@ static int __devexit at91udc_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM
static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg)
static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
{
struct at91_udc *udc = platform_get_drvdata(dev);
struct at91_udc *udc = platform_get_drvdata(pdev);
int wake = udc->driver && device_may_wakeup(&pdev->dev);
/*
* The "safe" suspend transitions are opportunistic ... e.g. when
* the USB link is suspended (48MHz clock autogated off), or when
* it's disconnected (programmatically gated off, elsewhere).
* Then we can suspend, and the chip can enter slow clock mode.
*
* The problem case is some component (user mode?) suspending this
* device while it's active, with the 48 MHz clock in use. There
* are two basic approaches: (a) veto suspend levels involving slow
* clock mode, (b) disconnect, so 48 MHz will no longer be in use
* and we can enter slow clock mode. This uses (b) for now, since
* it's simplest until AT91 PM exists and supports the other option.
/* Unless we can act normally to the host (letting it wake us up
* whenever it has work for us) force disconnect. Wakeup requires
* PLLB for USB events (signaling for reset, wakeup, or incoming
* tokens) and VBUS irqs (on systems which support them).
*/
if (udc->vbus && !udc->suspended)
if ((!udc->suspended && udc->addr)
|| !wake
|| at91_suspend_entering_slow_clock()) {
pullup(udc, 0);
disable_irq_wake(udc->udp_irq);
} else
enable_irq_wake(udc->udp_irq);
if (udc->board.vbus_pin > 0) {
if (wake)
enable_irq_wake(udc->board.vbus_pin);
else
disable_irq_wake(udc->board.vbus_pin);
}
return 0;
}
static int at91udc_resume(struct platform_device *dev)
static int at91udc_resume(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(dev);
struct at91_udc *udc = platform_get_drvdata(pdev);
/* maybe reconnect to host; if so, clocks on */
pullup(udc, 1);
......@@ -1748,7 +1796,7 @@ static struct platform_driver at91_udc = {
.remove = __devexit_p(at91udc_remove),
.shutdown = at91udc_shutdown,
.suspend = at91udc_suspend,
.resume = at91udc_resume,
.resume = at91udc_resume,
.driver = {
.name = (char *) driver_name,
.owner = THIS_MODULE,
......@@ -1767,6 +1815,6 @@ static void __devexit udc_exit_module(void)
}
module_exit(udc_exit_module);
MODULE_DESCRIPTION("AT91RM9200 udc driver");
MODULE_DESCRIPTION("AT91 udc driver");
MODULE_AUTHOR("Thomas Rathbone, David Brownell");
MODULE_LICENSE("GPL");
......@@ -141,6 +141,7 @@ struct at91_udc {
struct clk *iclk, *fclk;
struct platform_device *pdev;
struct proc_dir_entry *pde;
int udp_irq;
};
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)
if (!dum->driver)
return -ESHUTDOWN;
spin_lock_irqsave (&dum->lock, flags);
local_irq_save (flags);
spin_lock (&dum->lock);
list_for_each_entry (req, &ep->queue, queue) {
if (&req->req == _req) {
list_del_init (&req->queue);
......@@ -618,7 +619,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
break;
}
}
spin_unlock_irqrestore (&dum->lock, flags);
spin_unlock (&dum->lock);
if (retval == 0) {
dev_dbg (udc_dev(dum),
......@@ -626,6 +627,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
req, _ep->name, _req->length, _req->buf);
_req->complete (_ep, _req);
}
local_irq_restore (flags);
return retval;
}
......
......@@ -892,7 +892,7 @@ MODULE_LICENSE ("GPL");
#define PCI_DRIVER ehci_pci_driver
#endif
#ifdef CONFIG_PPC_83xx
#ifdef CONFIG_MPC834x
#include "ehci-fsl.c"
#define PLATFORM_DRIVER ehci_fsl_driver
#endif
......
......@@ -4,7 +4,7 @@
* Copyright (C) 2004 SAN People (Pty) Ltd.
* 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 ohci-omap.c
......@@ -19,12 +19,13 @@
#include <asm/hardware.h>
#include <asm/arch/board.h>
#ifndef CONFIG_ARCH_AT91RM9200
#error "CONFIG_ARCH_AT91RM9200 must be defined."
#ifndef CONFIG_ARCH_AT91
#error "CONFIG_ARCH_AT91 must be defined."
#endif
/* interface and function clocks */
static struct clk *iclk, *fclk;
static int clocked;
extern int usb_disabled(void);
......@@ -35,13 +36,14 @@ static void at91_start_hc(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
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.
*/
clk_enable(iclk);
clk_enable(fclk);
clocked = 1;
/*
* The USB host controller must remain in reset.
......@@ -54,7 +56,7 @@ static void at91_stop_hc(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
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.
......@@ -66,6 +68,7 @@ static void at91_stop_hc(struct platform_device *pdev)
*/
clk_disable(fclk);
clk_disable(iclk);
clocked = 0;
}
......@@ -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()
*
* Allocates basic resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it
* 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;
struct usb_hcd *hcd = NULL;
......@@ -95,12 +99,13 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *
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");
return -ENODEV;
}
hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200");
hcd = usb_create_hcd(driver, &pdev->dev, "at91");
if (!hcd)
return -ENOMEM;
hcd->rsrc_start = pdev->resource[0].start;
......@@ -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 */
/**
* 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
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_at91_probe(), first invoking
* 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);
at91_stop_hc(pdev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
disable_irq_wake(hcd->irq);
clk_put(fclk);
clk_put(iclk);
......@@ -178,19 +185,21 @@ static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pde
static int __devinit
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 usb_device *root = hcd->self.root_hub;
int ret;
if ((ret = ohci_init(ohci)) < 0)
return ret;
root->maxchild = board->ports;
if ((ret = ohci_run(ohci)) < 0) {
err("can't start %s", hcd->self.bus_name);
ohci_stop(hcd);
return ret;
}
// hcd->self.root_hub->maxchild = board->ports;
return 0;
}
......@@ -198,7 +207,7 @@ ohci_at91_start (struct usb_hcd *hcd)
static const struct hc_driver ohci_at91_hc_driver = {
.description = hcd_name,
.product_desc = "AT91RM9200 OHCI",
.product_desc = "AT91 OHCI",
.hcd_priv_size = sizeof(struct ohci_hcd),
/*
......@@ -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
/* REVISIT suspend/resume look "too" simple here */
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)
{
clk_disable(fclk);
clk_disable(iclk);
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(iclk);
clocked = 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)
{
clk_enable(iclk);
clk_enable(fclk);
if (!clocked) {
clk_enable(iclk);
clk_enable(fclk);
}
return 0;
}
......@@ -275,7 +305,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *dev)
#define ohci_hcd_at91_drv_resume NULL
#endif
MODULE_ALIAS("at91rm9200-ohci");
MODULE_ALIAS("at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
......@@ -283,7 +313,7 @@ static struct platform_driver ohci_hcd_at91_driver = {
.suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume,
.driver = {
.name = "at91rm9200-ohci",
.name = "at91_ohci",
.owner = THIS_MODULE,
},
};
......
......@@ -913,7 +913,7 @@ MODULE_LICENSE ("GPL");
#include "ohci-ppc-soc.c"
#endif
#ifdef CONFIG_ARCH_AT91RM9200
#if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)
#include "ohci-at91.c"
#endif
......@@ -927,6 +927,7 @@ MODULE_LICENSE ("GPL");
|| defined (CONFIG_SOC_AU1X00) \
|| defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
|| defined (CONFIG_ARCH_AT91RM9200) \
|| defined (CONFIG_ARCH_AT91SAM9261) \
)
#error "missing bus glue for ohci-hcd"
#endif
......@@ -943,7 +943,9 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
/* We received a short packet */
if (urb->transfer_flags & URB_SHORT_NOT_OK)
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;
}
......
......@@ -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
* and we have to take this into account for an accurate repeat
* behaviour.
* (HZ / 20) == 50 ms and works well for me.
*/
#define FILTER_TIME (HZ / 20)
#define FILTER_TIME 60 /* msec */
struct ati_remote {
struct input_dev *idev;
......@@ -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. */
if ((ati_remote->old_data[0] == data[1]) &&
(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++;
} else {
ati_remote->repeat_count = 0;
......
......@@ -12,8 +12,13 @@
* the single I/O ports of the device.
*
* Supported vendors: AK Modul-Bus Computer GmbH
* Supported devices: CY7C63001A-PC (to be continued...)
* Supported functions: Read/Write Ports (to be continued...)
* (Firmware "Port-Chip")
*
* Supported devices: CY7C63001A-PC
* CY7C63001C-PXC
* CY7C63001C-SXC
*
* Supported functions: Read/Write Ports
*
*
* This program is free software; you can redistribute it and/or
......
......@@ -175,6 +175,8 @@ static inline struct sk_buff *pull_skb(rtl8150_t *);
static void rtl8150_disconnect(struct usb_interface *intf);
static int rtl8150_probe(struct usb_interface *intf,
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";
......@@ -183,6 +185,8 @@ static struct usb_driver rtl8150_driver = {
.probe = rtl8150_probe,
.disconnect = rtl8150_disconnect,
.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)
usb_fill_control_urb(dev->ctrl_urb, dev->udev,
usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
&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);
else
} else
set_bit(RX_REG_SET, &dev->flags);
return ret;
......@@ -416,6 +422,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
struct sk_buff *skb;
struct net_device *netdev;
u16 rx_stat;
int status;
dev = urb->context;
if (!dev)
......@@ -465,7 +472,10 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
goon:
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
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);
goto resched;
} else {
......@@ -481,6 +491,7 @@ static void rx_fixup(unsigned long data)
{
rtl8150_t *dev;
struct sk_buff *skb;
int status;
dev = (rtl8150_t *)data;
......@@ -499,10 +510,13 @@ static void rx_fixup(unsigned long data)
usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
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);
goto tlsched;
} else {
} else {
clear_bit(RX_URB_FAIL, &dev->flags);
}
......@@ -574,12 +588,43 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs)
resubmit:
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",
dev->udev->bus->bus_name,
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)
usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
skb->data, count, write_bulk_callback, dev);
if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
warn("failed tx_urb %d\n", res);
dev->stats.tx_errors++;
netif_start_queue(netdev);
/* Can we get/handle EPIPE here? */
if (res == -ENODEV)
netif_device_detach(dev->netdev);
else {
warn("failed tx_urb %d\n", res);
dev->stats.tx_errors++;
netif_start_queue(netdev);
}
} else {
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
......@@ -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),
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);
return res;
}
usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
dev->intr_buff, INTBUFSIZE, intr_callback,
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);
netif_start_queue(netdev);
usb_kill_urb(dev->rx_urb);
return res;
}
enable_net_traffic(dev);
set_carrier(netdev);
netif_start_queue(netdev);
return res;
}
......
......@@ -62,15 +62,6 @@ config USB_SERIAL_AIRPRIME
To compile this driver as a module, choose M here: the
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
tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)"
depends on USB_SERIAL && EXPERIMENTAL
......@@ -502,15 +493,18 @@ config USB_SERIAL_XIRCOM
module will be called keyspan_pda.
config USB_SERIAL_OPTION
tristate "USB driver for GSM modems"
tristate "USB driver for GSM and CDMA modems"
depends on USB_SERIAL
help
Say Y here if you have an "Option" GSM PCMCIA card
(or an OEM version: branded Huawei, Audiovox, or Novatel).
Say Y here if you have a GSM or CDMA modem that's connected to USB.
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
internally-connected GSM modem. The USB bus is not
accessible externally.
Supported devices include (some of?) those made by:
Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or
Anydata.
To compile this driver as a module, choose M here: the
module will be called option.
......
......@@ -12,7 +12,6 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o
usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y)
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_BELKIN) += belkin_sa.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 [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_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_2102_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
......
......@@ -182,6 +182,10 @@
/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
#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).
* All of these devices use FTDI's vendor ID (0x0403).
......
......@@ -250,6 +250,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU 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, 0x5F01) }, /* Samsung NEXiO USB Sync */
{ USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
......
......@@ -9,40 +9,14 @@
Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
History:
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
History: see the git log.
Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
This driver exists because the "normal" serial driver doesn't work too well
with GSM modems. Issues:
- 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
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);
#define OPTION_VENDOR_ID 0x0AF0
#define HUAWEI_VENDOR_ID 0x12D1
#define AUDIOVOX_VENDOR_ID 0x0F3D
#define SIERRAWIRELESS_VENDOR_ID 0x1199
#define NOVATELWIRELESS_VENDOR_ID 0x1410
#define ANYDATA_VENDOR_ID 0x16d5
#define OPTION_PRODUCT_OLD 0x5000
#define OPTION_PRODUCT_FUSION 0x6000
......@@ -106,8 +80,8 @@ static int option_send_setup(struct usb_serial_port *port);
#define OPTION_PRODUCT_COBRA2 0x6600
#define HUAWEI_PRODUCT_E600 0x1001
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802
#define NOVATELWIRELESS_PRODUCT_U740 0x1400
#define ANYDATA_PRODUCT_ID 0x6501
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
......@@ -117,8 +91,8 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ 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(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */
};
......@@ -131,10 +105,7 @@ static struct usb_device_id option_ids1[] = {
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ } /* Terminating entry */
};
static struct usb_device_id option_ids3[] = {
{ USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */
};
......@@ -151,37 +122,11 @@ static struct usb_driver option_driver = {
/* The card has three separate interfaces, which the serial driver
* 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 = {
.driver = {
.owner = THIS_MODULE,
.name = "option",
.name = "option1",
},
.description = "GSM modem (1-port)",
.id_table = option_ids1,
......@@ -245,9 +190,6 @@ static int __init option_init(void)
retval = usb_serial_register(&option_1port_device);
if (retval)
goto failed_1port_device_register;
retval = usb_serial_register(&option_3port_device);
if (retval)
goto failed_3port_device_register;
retval = usb_register(&option_driver);
if (retval)
goto failed_driver_register;
......@@ -257,8 +199,6 @@ static int __init option_init(void)
return 0;
failed_driver_register:
usb_serial_deregister (&option_3port_device);
failed_3port_device_register:
usb_serial_deregister (&option_1port_device);
failed_1port_device_register:
return retval;
......@@ -267,7 +207,6 @@ static int __init option_init(void)
static void __exit option_exit(void)
{
usb_deregister (&option_driver);
usb_serial_deregister (&option_3port_device);
usb_serial_deregister (&option_1port_device);
}
......@@ -656,7 +595,6 @@ static void option_setup_urbs(struct usb_serial *serial)
dbg("%s", __FUNCTION__);
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
portdata = usb_get_serial_port_data(port);
......
......@@ -81,6 +81,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
{ USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) },
{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
{ } /* Terminating entry */
};
......
......@@ -89,3 +89,7 @@
/* DATAPILOT Universal-2 Phone Cable */
#define DATAPILOT_U2_VENDOR_ID 0x0731
#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,
US_SC_DEVICE, US_PR_DEVICE, NULL,
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
* Einar Th. Einarsson <einarthered@gmail.com> */
UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100,
......@@ -627,18 +634,6 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
"Digital Camera EX-20 DSC",
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>
* Some versions of this device need the SubClass and Protocol overrides
* while others don't.
......@@ -1106,7 +1101,15 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
"Optio S/S4",
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. */
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
UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
"ATI",
......
......@@ -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 */
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_interface_descriptor *idesc =
......@@ -500,6 +500,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
unusual_dev->useTransport;
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
* 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)
msgs[msg],
UTS_RELEASE);
}
return 0;
}
/* Get the transport settings */
......@@ -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
* 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 */
result = get_transport(us);
......
......@@ -103,8 +103,7 @@ enum usb_interface_condition {
* @condition: binding state of the interface: not bound, binding
* (in probe()), bound to a driver, or unbinding (in disconnect())
* @dev: driver model's view of this device
* @usb_dev: if an interface is bound to the USB major, this will point
* to the sysfs representation for that device.
* @class_dev: driver model's class view of this device.
*
* USB device drivers attach to interfaces on a physical device. Each
* interface encapsulates a single high level function, such as feeding
......@@ -144,7 +143,7 @@ struct usb_interface {
* bound to */
enum usb_interface_condition condition; /* state of binding */
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 interface_to_usbdev(intf) \
......@@ -361,7 +360,7 @@ struct usb_device {
char *serial; /* iSerialNumber string, if present */
struct list_head filelist;
struct device *usbfs_dev;
struct class_device *class_dev;
struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
/*
......
......@@ -44,7 +44,9 @@
US_FLAG(NO_WP_DETECT, 0x00000200) \
/* Don't check for write-protect */ \
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 ,
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