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. ...
This commit is contained in:
commit
90eb29efd0
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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,
|
||||||
++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,
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -57,19 +57,23 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This controller is simple and PIO-only. It's used in many AT91-series
|
* This controller is simple and PIO-only. It's used in many AT91-series
|
||||||
* ARMv4T controllers, including the at91rm9200 (arm920T, with MMU),
|
* full speed USB controllers, including the at91rm9200 (arm920T, with MMU),
|
||||||
* at91sam9261 (arm926ejs, with MMU), and several no-mmu versions.
|
* at91sam926x (arm926ejs, with MMU), and several no-mmu versions.
|
||||||
*
|
*
|
||||||
* This driver expects the board has been wired with two GPIOs suppporting
|
* 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
|
* 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.
|
* provides software control over whether the host enumerates the device.
|
||||||
|
*
|
||||||
* The VBUS sensing helps during enumeration, and allows both USB clocks
|
* The VBUS sensing helps during enumeration, and allows both USB clocks
|
||||||
* (and the transceiver) to stay gated off until they're necessary, saving
|
* (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 driver_name [] = "at91_udc";
|
||||||
static const char ep0name[] = "ep0";
|
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
|
* There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE
|
||||||
* that shouldn't normally be changed.
|
* 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 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 */
|
/* pull OUT packet data from the endpoint's fifo */
|
||||||
static int read_fifo (struct at91_ep *ep, struct at91_request *req)
|
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_ep *ep = container_of(_ep, struct at91_ep, ep);
|
||||||
struct at91_udc *dev = ep->udc;
|
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.
|
* 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;
|
struct at91_request *req;
|
||||||
|
|
||||||
req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL);
|
req = kcalloc(1, sizeof (struct at91_request), gfp_flags);
|
||||||
if (!req)
|
if (!req)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -862,6 +874,7 @@ static void stop_activity(struct at91_udc *udc)
|
||||||
if (udc->gadget.speed == USB_SPEED_UNKNOWN)
|
if (udc->gadget.speed == USB_SPEED_UNKNOWN)
|
||||||
driver = NULL;
|
driver = NULL;
|
||||||
udc->gadget.speed = USB_SPEED_UNKNOWN;
|
udc->gadget.speed = USB_SPEED_UNKNOWN;
|
||||||
|
udc->suspended = 0;
|
||||||
|
|
||||||
for (i = 0; i < NUM_ENDPOINTS; i++) {
|
for (i = 0; i < NUM_ENDPOINTS; i++) {
|
||||||
struct at91_ep *ep = &udc->ep[i];
|
struct at91_ep *ep = &udc->ep[i];
|
||||||
|
@ -889,8 +902,8 @@ static void clk_off(struct at91_udc *udc)
|
||||||
return;
|
return;
|
||||||
udc->clocked = 0;
|
udc->clocked = 0;
|
||||||
udc->gadget.speed = USB_SPEED_UNKNOWN;
|
udc->gadget.speed = USB_SPEED_UNKNOWN;
|
||||||
clk_disable(udc->iclk);
|
|
||||||
clk_disable(udc->fclk);
|
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_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
|
||||||
at91_set_gpio_value(udc->board.pullup_pin, 0);
|
at91_set_gpio_value(udc->board.pullup_pin, 0);
|
||||||
clk_off(udc);
|
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) {
|
if (udc->wait_for_addr_ack) {
|
||||||
u32 tmp;
|
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_read(AT91_UDP_GLB_STAT);
|
||||||
tmp &= ~AT91_UDP_FADDEN;
|
tmp &= ~AT91_UDP_FADDEN;
|
||||||
if (udc->addr)
|
if (udc->addr)
|
||||||
|
@ -1361,9 +1372,10 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
|
||||||
u32 rescans = 5;
|
u32 rescans = 5;
|
||||||
|
|
||||||
while (rescans--) {
|
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)
|
if (!status)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1379,18 +1391,17 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
|
||||||
stop_activity(udc);
|
stop_activity(udc);
|
||||||
|
|
||||||
/* enable ep0 */
|
/* 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->gadget.speed = USB_SPEED_FULL;
|
||||||
udc->suspended = 0;
|
udc->suspended = 0;
|
||||||
at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
|
at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: this driver keeps clocks off unless the
|
* NOTE: this driver keeps clocks off unless the
|
||||||
* USB host is present. That saves power, and also
|
* USB host is present. That saves power, but for
|
||||||
* eliminates IRQs (reset, resume, suspend) that can
|
* boards that don't support VBUS detection, both
|
||||||
* otherwise flood from the controller. If your
|
* clocks need to be active most of the time.
|
||||||
* board doesn't support VBUS detection, suspend and
|
|
||||||
* resume irq logic may need more attention...
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* host initiated suspend (3+ms bus idle) */
|
/* 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 = {
|
static struct at91_udc controller = {
|
||||||
.gadget = {
|
.gadget = {
|
||||||
.ops = &at91_udc_ops,
|
.ops = &at91_udc_ops,
|
||||||
.ep0 = &controller.ep[0].ep,
|
.ep0 = &controller.ep[0].ep,
|
||||||
.name = driver_name,
|
.name = driver_name,
|
||||||
.dev = {
|
.dev = {
|
||||||
.bus_id = "gadget"
|
.bus_id = "gadget",
|
||||||
|
.release = nop_release,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.ep[0] = {
|
.ep[0] = {
|
||||||
|
@ -1468,7 +1485,8 @@ static struct at91_udc controller = {
|
||||||
},
|
},
|
||||||
.udc = &controller,
|
.udc = &controller,
|
||||||
.maxpacket = 8,
|
.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,
|
.int_mask = 1 << 0,
|
||||||
},
|
},
|
||||||
.ep[1] = {
|
.ep[1] = {
|
||||||
|
@ -1479,7 +1497,8 @@ static struct at91_udc controller = {
|
||||||
.udc = &controller,
|
.udc = &controller,
|
||||||
.is_pingpong = 1,
|
.is_pingpong = 1,
|
||||||
.maxpacket = 64,
|
.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,
|
.int_mask = 1 << 1,
|
||||||
},
|
},
|
||||||
.ep[2] = {
|
.ep[2] = {
|
||||||
|
@ -1490,7 +1509,8 @@ static struct at91_udc controller = {
|
||||||
.udc = &controller,
|
.udc = &controller,
|
||||||
.is_pingpong = 1,
|
.is_pingpong = 1,
|
||||||
.maxpacket = 64,
|
.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,
|
.int_mask = 1 << 2,
|
||||||
},
|
},
|
||||||
.ep[3] = {
|
.ep[3] = {
|
||||||
|
@ -1501,7 +1521,8 @@ static struct at91_udc controller = {
|
||||||
},
|
},
|
||||||
.udc = &controller,
|
.udc = &controller,
|
||||||
.maxpacket = 8,
|
.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,
|
.int_mask = 1 << 3,
|
||||||
},
|
},
|
||||||
.ep[4] = {
|
.ep[4] = {
|
||||||
|
@ -1512,7 +1533,8 @@ static struct at91_udc controller = {
|
||||||
.udc = &controller,
|
.udc = &controller,
|
||||||
.is_pingpong = 1,
|
.is_pingpong = 1,
|
||||||
.maxpacket = 256,
|
.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,
|
.int_mask = 1 << 4,
|
||||||
},
|
},
|
||||||
.ep[5] = {
|
.ep[5] = {
|
||||||
|
@ -1523,10 +1545,11 @@ static struct at91_udc controller = {
|
||||||
.udc = &controller,
|
.udc = &controller,
|
||||||
.is_pingpong = 1,
|
.is_pingpong = 1,
|
||||||
.maxpacket = 256,
|
.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,
|
.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)
|
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();
|
local_irq_disable();
|
||||||
udc->enabled = 0;
|
udc->enabled = 0;
|
||||||
|
at91_udp_write(AT91_UDP_IDR, ~0);
|
||||||
pullup(udc, 0);
|
pullup(udc, 0);
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
|
@ -1624,6 +1648,16 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
|
||||||
return -ENODEV;
|
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)) {
|
if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) {
|
||||||
DBG("someone's using UDC memory\n");
|
DBG("someone's using UDC memory\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
@ -1649,19 +1683,26 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto fail0;
|
goto fail0;
|
||||||
|
|
||||||
/* disable everything until there's a gadget driver and vbus */
|
/* don't do anything until we have both gadget driver and VBUS */
|
||||||
pullup(udc, 0);
|
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 */
|
/* request UDC and maybe VBUS irqs */
|
||||||
if (request_irq(AT91_ID_UDP, at91_udc_irq, IRQF_DISABLED, driver_name, udc)) {
|
udc->udp_irq = platform_get_irq(pdev, 0);
|
||||||
DBG("request irq %d failed\n", AT91_ID_UDP);
|
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;
|
retval = -EBUSY;
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
if (udc->board.vbus_pin > 0) {
|
if (udc->board.vbus_pin > 0) {
|
||||||
if (request_irq(udc->board.vbus_pin, at91_vbus_irq, IRQF_DISABLED, driver_name, udc)) {
|
if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
|
||||||
DBG("request vbus irq %d failed\n", udc->board.vbus_pin);
|
IRQF_DISABLED, driver_name, udc)) {
|
||||||
free_irq(AT91_ID_UDP, udc);
|
DBG("request vbus irq %d failed\n",
|
||||||
|
udc->board.vbus_pin);
|
||||||
|
free_irq(udc->udp_irq, udc);
|
||||||
retval = -EBUSY;
|
retval = -EBUSY;
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
|
@ -1670,6 +1711,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
|
||||||
udc->vbus = 1;
|
udc->vbus = 1;
|
||||||
}
|
}
|
||||||
dev_set_drvdata(dev, udc);
|
dev_set_drvdata(dev, udc);
|
||||||
|
device_init_wakeup(dev, 1);
|
||||||
create_debug_file(udc);
|
create_debug_file(udc);
|
||||||
|
|
||||||
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
|
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
|
||||||
|
@ -1678,14 +1720,14 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
|
||||||
fail1:
|
fail1:
|
||||||
device_unregister(&udc->gadget.dev);
|
device_unregister(&udc->gadget.dev);
|
||||||
fail0:
|
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);
|
DBG("%s probe failed, %d\n", driver_name, retval);
|
||||||
return 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");
|
DBG("remove\n");
|
||||||
|
|
||||||
|
@ -1694,10 +1736,11 @@ static int __devexit at91udc_remove(struct platform_device *dev)
|
||||||
if (udc->driver != 0)
|
if (udc->driver != 0)
|
||||||
usb_gadget_unregister_driver(udc->driver);
|
usb_gadget_unregister_driver(udc->driver);
|
||||||
|
|
||||||
|
device_init_wakeup(&pdev->dev, 0);
|
||||||
remove_debug_file(udc);
|
remove_debug_file(udc);
|
||||||
if (udc->board.vbus_pin > 0)
|
if (udc->board.vbus_pin > 0)
|
||||||
free_irq(udc->board.vbus_pin, udc);
|
free_irq(udc->board.vbus_pin, udc);
|
||||||
free_irq(AT91_ID_UDP, udc);
|
free_irq(udc->udp_irq, udc);
|
||||||
device_unregister(&udc->gadget.dev);
|
device_unregister(&udc->gadget.dev);
|
||||||
release_mem_region(AT91_BASE_UDP, SZ_16K);
|
release_mem_region(AT91_BASE_UDP, SZ_16K);
|
||||||
|
|
||||||
|
@ -1708,31 +1751,36 @@ static int __devexit at91udc_remove(struct platform_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#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);
|
||||||
|
|
||||||
/*
|
/* Unless we can act normally to the host (letting it wake us up
|
||||||
* The "safe" suspend transitions are opportunistic ... e.g. when
|
* whenever it has work for us) force disconnect. Wakeup requires
|
||||||
* the USB link is suspended (48MHz clock autogated off), or when
|
* PLLB for USB events (signaling for reset, wakeup, or incoming
|
||||||
* it's disconnected (programmatically gated off, elsewhere).
|
* tokens) and VBUS irqs (on systems which support them).
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
if (udc->vbus && !udc->suspended)
|
if ((!udc->suspended && udc->addr)
|
||||||
|
|| !wake
|
||||||
|
|| at91_suspend_entering_slow_clock()) {
|
||||||
pullup(udc, 0);
|
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;
|
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 */
|
/* maybe reconnect to host; if so, clocks on */
|
||||||
pullup(udc, 1);
|
pullup(udc, 1);
|
||||||
|
@ -1767,6 +1815,6 @@ static void __devexit udc_exit_module(void)
|
||||||
}
|
}
|
||||||
module_exit(udc_exit_module);
|
module_exit(udc_exit_module);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("AT91RM9200 udc driver");
|
MODULE_DESCRIPTION("AT91 udc driver");
|
||||||
MODULE_AUTHOR("Thomas Rathbone, David Brownell");
|
MODULE_AUTHOR("Thomas Rathbone, David Brownell");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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");
|
||||||
#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 @@
|
||||||
* 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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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 *);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 *
|
||||||
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 *
|
||||||
/* 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
|
||||||
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)
|
||||||
|
|
||||||
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 = {
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
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)
|
||||||
#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 = {
|
||||||
.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");
|
||||||
#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");
|
||||||
|| 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)
|
||||||
/* 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 };
|
||||||
* 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)
|
||||||
/* 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 @@
|
||||||
* 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 *);
|
||||||
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 = {
|
||||||
.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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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).
|
|
||||||
|
|
||||||
These cards feature a built-in OHCI-USB adapter and an
|
This driver also supports several PCMCIA cards which have a
|
||||||
internally-connected GSM modem. The USB bus is not
|
built-in OHCI-USB adapter and an internally-connected GSM modem.
|
||||||
accessible externally.
|
The USB bus on these cards 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
|
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
|
||||||
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
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
* 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_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 @@
|
||||||
/* 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 [] = {
|
||||||
{ 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 @@
|
||||||
|
|
||||||
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);
|
||||||
#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);
|
||||||
#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[] = {
|
||||||
{ 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[] = {
|
||||||
{ 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 = {
|
||||||
/* 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)
|
||||||
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)
|
||||||
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 @@ failed_1port_device_register:
|
||||||
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)
|
||||||
|
|
||||||
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 [] = {
|
||||||
{ 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 @@
|
||||||
/* 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,
|
||||||
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,
|
||||||
"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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
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,
|
||||||
* 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 {
|
||||||
* @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 {
|
||||||
* 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 {
|
||||||
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 @@
|
||||||
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 };
|
||||||
|
|
Loading…
Reference in New Issue