mirror of https://gitee.com/openkylin/linux.git
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
|
||||
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.
|
||||
|
||||
These cards feature a built-in OHCI-USB adapter and an
|
||||
internally-connected GSM modem. The USB bus is not
|
||||
accessible externally.
|
||||
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.
|
||||
|
||||
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
|
||||
|
|
|
@ -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_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 };
|
||||
|
|
Loading…
Reference in New Issue