Commit 226c6dd3 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 6527d91e 5e5495dd
......@@ -2546,12 +2546,7 @@ Your cooperation is appreciated.
0 = /dev/usb/lp0 First USB printer
...
15 = /dev/usb/lp15 16th USB printer
16 = /dev/usb/mouse0 First USB mouse
...
31 = /dev/usb/mouse15 16th USB mouse
32 = /dev/usb/ez0 First USB firmware loader
...
47 = /dev/usb/ez15 16th USB firmware loader
32 = /dev/usb/mdc800 MDC800 USB camera
48 = /dev/usb/scanner0 First USB scanner
...
63 = /dev/usb/scanner15 16th USB scanner
......@@ -2559,6 +2554,22 @@ Your cooperation is appreciated.
65 = /dev/usb/usblcd USBLCD Interface (info@usblcd.de)
66 = /dev/usb/cpad0 Synaptics cPad (mouse/LCD)
96 = /dev/usb/hiddev0 1st USB HID device
...
111 = /dev/usb/hiddev15 16th USB HID device
112 = /dev/usb/auer0 1st auerswald ISDN device
...
127 = /dev/usb/auer15 16th auerswald ISDN device
128 = /dev/usb/brlvgr0 First Braille Voyager device
...
131 = /dev/usb/brlvgr3 Fourth Braille Voyager device
144 = /dev/usb/lcd USB LCD device
160 = /dev/usb/legousbtower0 1st USB Legotower device
...
175 = /dev/usb/legousbtower15 16th USB Legotower device
240 = /dev/usb/dabusb0 First daubusb device
...
243 = /dev/usb/dabusb3 Fourth dabusb device
181 char Conrad Electronic parallel port radio clocks
0 = /dev/pcfclock0 First Conrad radio clock
......
Revised: 2002-Feb-09.
Revised: 2004-Oct-21
This is the documentation of (hopefully) all possible error codes (and
their interpretation) that can be returned from usbcore.
Some of them are returned by the Host Controller Drivers (HCDs), which
device drivers only see through usbcore. As a rule, all the HCDs should
behave the same except for transfer speed dependent behaviors.
behave the same except for transfer speed dependent behaviors and the
way certain faults are reported.
**************************************************************************
......@@ -26,29 +27,35 @@ USB-specific:
of urb. (treat as a host controller bug.)
-EINVAL a) Invalid transfer type specified (or not supported)
b) Invalid interrupt interval (0<=n<256)
c) more than one interrupt packet requested
b) Invalid or unsupported periodic transfer interval
c) ISO: attempted to change transfer interval
d) ISO: number_of_packets is < 0
e) various other cases
-EAGAIN a) specified ISO start frame too early
b) (using ISO-ASAP) too much scheduled for the future
wait some time and try again.
-EFBIG too much ISO frames requested (currently uhci>900)
-EFBIG Host controller driver can't schedule that many ISO frames.
-EPIPE Specified endpoint is stalled. For non-control endpoints,
reset this status with usb_clear_halt().
-EMSGSIZE endpoint message size is zero, do interface/alternate setting
-EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable
in the current interface altsetting.
(b) ISO packet is biger than endpoint maxpacket
(c) requested data transfer size is invalid (negative)
-ENOSPC The host controller's bandwidth is already consumed and
this request would push it past its allowed limit.
-ENOSPC This request would overcommit the usb bandwidth reserved
for periodic transfers (interrupt, isochronous).
-ESHUTDOWN The host controller has been disabled due to some
-ESHUTDOWN The device or host controller has been disabled due to some
problem that could not be worked around.
-EPERM Submission failed because urb->reject was set.
-EHOSTUNREACH URB was rejected because the device is suspended.
**************************************************************************
* Error codes returned by in urb->status *
......@@ -71,14 +78,14 @@ one or more packets could finish before an error stops further endpoint I/O.
-EINPROGRESS URB still pending, no results yet
(That is, if drivers see this it's a bug.)
-EPROTO (*) a) bitstuff error
-EPROTO (*, **) a) bitstuff error
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
-EILSEQ (*) CRC mismatch
-EILSEQ (*, **) CRC mismatch
-EPIPE Endpoint stalled. For non-control endpoints,
-EPIPE (**) Endpoint stalled. For non-control endpoints,
reset this status with usb_clear_halt().
-ECOMM During an IN transfer, the host controller
......@@ -97,7 +104,7 @@ one or more packets could finish before an error stops further endpoint I/O.
specified buffer, and URB_SHORT_NOT_OK was set in
urb->transfer_flags.
-ETIMEDOUT transfer timed out, NAK
-ETIMEDOUT (**) transfer timed out, NAK
-ENODEV Device was removed. Often preceded by a burst of
other errors, since the hub driver does't detect
......@@ -110,13 +117,19 @@ one or more packets could finish before an error stops further endpoint I/O.
-ECONNRESET URB was asynchronously unlinked by usb_unlink_urb
-ESHUTDOWN The host controller has been disabled due to some
problem that could not be worked around.
-ESHUTDOWN The device or host controller has been disabled due
to some problem that could not be worked around,
such as a physical disconnect.
(*) Error codes like -EPROTO, -EILSEQ and -EOVERFLOW normally indicate
hardware problems such as bad devices (including firmware) or cables.
(**) This is also one of several codes that different kinds of host
controller use to to indicate a transfer has failed because of device
disconnect. In the interval before the hub driver starts disconnect
processing, devices may receive such fault reports for every request.
**************************************************************************
......
-------------------------------------------------------------------------
Readme for Linux device driver for the Texas Instruments SilverLink cable
and direct USB cable provided by some TI's handhelds.
-------------------------------------------------------------------------
Author: Romain Liévin & Julien Blache
......@@ -9,7 +10,8 @@ INTRODUCTION:
This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable
designed by TI for connecting their TI8x/9x calculators to a computer
(PC or Mac usually).
(PC or Mac usually). It has been extended to support the USB port offered by
some latest TI handhelds (TI84+ and TI89 Titanium).
If you need more information, please visit the 'SilverLink drivers' homepage
at the above URL.
......@@ -73,4 +75,4 @@ this driver but he better knows the Mac OS-X driver.
CREDITS:
The code is based on dabusb.c, printer.c and scanner.c !
The driver has been developed independently of Texas Instruments.
The driver has been developed independently of Texas Instruments Inc.
......@@ -8,26 +8,30 @@
Index
=====
1. Copyright
2. License
3. Overview
4. Supported devices
5. Module dependencies
6. Module loading
7. Module paramaters
8. Contact information
9. Credits
1. Copyright
2. Disclaimer
3. License
4. Overview
5. Supported devices
6. Module dependencies
7. Module loading
8. Module paramaters
9. Contact information
10. Credits
1. Copyright
============
Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
2. Disclaimer
=============
Winbond is a trademark of Winbond Electronics Corporation.
This driver is not sponsored or developed by Winbond.
This software is not sponsored or developed by Winbond.
2. License
3. License
==========
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -44,7 +48,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3. Overview
4. Overview
===========
This driver supports the video streaming capabilities of the devices mounting
Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips. OV681
......@@ -57,7 +61,7 @@ decoding, up-scaling and colour conversions. Once the driver is installed,
every time an application tries to open a recognized device, "w9968cf" checks
the presence of the "w9968cf-vpp" module and loads it automatically by default.
Please keep in mind that official kernels do NOT include the second module for
Please keep in mind that official kernels do not include the second module for
performance purposes. However it is always recommended to download and install
the latest and complete release of the driver, replacing the existing one, if
present: it will be still even possible not to load the "w9968cf-vpp" module at
......@@ -65,7 +69,7 @@ all, if you ever want to. Another important missing feature of the version in
the official Linux 2.4 kernels is the writeable /proc filesystem interface.
The latest and full-featured version of the W996[87]CF driver can be found at:
http://go.lamarinapunto.com/ . Please refer to the documentation included in
http://www.linux-projects.org. Please refer to the documentation included in
that package, if you are going to use it.
Up to 32 cameras can be handled at the same time. They can be connected and
......@@ -83,7 +87,7 @@ will be automatically loaded by default (provided that the kernel has been
compiled with the automatic module loading option).
4. Supported devices
5. Supported devices
====================
At the moment, known W996[87]CF and OV681 based devices are:
- Aroma Digi Pen VGA Dual Mode ADG-5000 (unknown image sensor)
......@@ -99,11 +103,9 @@ At the moment, known W996[87]CF and OV681 based devices are:
If you know any other W996[87]CF or OV681 based cameras, please contact me.
The list above does NOT imply that all those devices work with this driver: up
The list above does not imply that all those devices work with this driver: up
until now only webcams that have an image sensor supported by the "ovcamchip"
module work.
For a list of supported image sensors, please visit the author's homepage on
this module: http://alpha.dyndns.org/ov511/
module work. Kernel messages will always tell you whether this is case.
Possible external microcontrollers of those webcams are not supported: this
means that still images cannot be downloaded from the device memory.
......@@ -113,7 +115,7 @@ Furthermore, it's worth to note that I was only able to run tests on my
additional testing and full support, would be much appreciated.
5. Module dependencies
6. Module dependencies
======================
For it to work properly, the driver needs kernel support for Video4Linux, USB
and I2C, and the "ovcamchip" module for the image sensor. Make sure you are not
......@@ -157,7 +159,7 @@ And finally:
CONFIG_USB_W9968CF=m
6. Module loading
7. Module loading
=================
To use the driver, it is necessary to load the "w9968cf" module into memory
after every other module required.
......@@ -166,6 +168,7 @@ Loading can be done this way, from root:
[root@localhost home]# modprobe usbcore
[root@localhost home]# modprobe i2c-core
[root@localhost home]# modprobe videodev
[root@localhost home]# modprobe w9968cf
At this point the pertinent devices should be recognized: "dmesg" can be used
......@@ -181,7 +184,7 @@ explanation about them and which syntax to use, it is recommended to run the
[root@locahost home]# modinfo w9968cf
7. Module parameters
8. Module parameters
====================
Module parameters are listed below:
-------------------------------------------------------------------------------
......@@ -452,7 +455,7 @@ Default: 0
-------------------------------------------------------------------------------
8. Contact information
9. Contact information
======================
I may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
......@@ -461,7 +464,7 @@ My public 1024-bit key should be available at your keyserver; the fingerprint
is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
9. Credits
10. Credits
==========
The development would not have proceed much further without having looked at
the source code of other drivers and without the help of several persons; in
......
......@@ -2371,7 +2371,7 @@ USB SN9C10x DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
L: linux-usb-devel@lists.sourceforge.net
W: http://go.lamarinapunto.com
W: http://www.linux-projects.org
S: Maintained
USB SUBSYSTEM
......@@ -2399,7 +2399,7 @@ USB W996[87]CF DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
L: linux-usb-devel@lists.sourceforge.net
W: http://go.lamarinapunto.com
W: http://www.linux-projects.org
S: Maintained
USER-MODE LINUX
......
......@@ -7,7 +7,7 @@ menu "USB support"
# ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
config USB
tristate "Support for Host-side USB"
depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610 || ARCH_LH7A404 || PXA27x
depends on USB_ARCH_HAS_HCD
---help---
Universal Serial Bus (USB) is a specification for a serial bus
subsystem which offers higher speeds and more features than the
......
......@@ -3119,12 +3119,18 @@ static void prepmixch(struct consmixstate *state)
{
struct usb_device *dev = state->s->usbdev;
struct mixerchannel *ch;
unsigned char buf[2];
unsigned char *buf;
__s16 v1;
unsigned int v2, v3;
if (!state->nrmixch || state->nrmixch > SOUND_MIXER_NRDEVICES)
return;
buf = kmalloc(sizeof(*buf) * 2, GFP_KERNEL);
if (!buf) {
printk(KERN_ERR "prepmixch: out of memory\n") ;
return;
}
ch = &state->mixch[state->nrmixch-1];
switch (ch->selector) {
case 0: /* mixer unit request */
......@@ -3236,13 +3242,16 @@ static void prepmixch(struct consmixstate *state)
default:
goto err;
}
return;
freebuf:
kfree(buf);
return;
err:
printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n",
dev->devnum, state->ctrlif, ch->unitid, ch->chnum, ch->selector);
if (state->nrmixch)
state->nrmixch--;
goto freebuf;
}
......
......@@ -222,6 +222,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp);
/* forward reference to make our lives easier */
static struct usb_driver usblp_driver;
static DECLARE_MUTEX(usblp_sem); /* locks the existence of usblp's */
/*
* Functions for usblp control messages.
......@@ -343,7 +344,7 @@ static int usblp_open(struct inode *inode, struct file *file)
if (minor < 0)
return -ENODEV;
lock_kernel();
down (&usblp_sem);
retval = -ENODEV;
intf = usb_find_interface(&usblp_driver, minor);
......@@ -389,7 +390,7 @@ static int usblp_open(struct inode *inode, struct file *file)
}
}
out:
unlock_kernel();
up (&usblp_sem);
return retval;
}
......@@ -415,13 +416,13 @@ static int usblp_release(struct inode *inode, struct file *file)
{
struct usblp *usblp = file->private_data;
down (&usblp->sem);
down (&usblp_sem);
usblp->used = 0;
if (usblp->present) {
usblp_unlink_urbs(usblp);
up(&usblp->sem);
} else /* finish cleanup from disconnect */
usblp_cleanup (usblp);
up (&usblp_sem);
return 0;
}
......@@ -1149,8 +1150,8 @@ static void usblp_disconnect(struct usb_interface *intf)
BUG ();
}
down (&usblp_sem);
down (&usblp->sem);
lock_kernel();
usblp->present = 0;
usb_set_intfdata (intf, NULL);
......@@ -1159,12 +1160,11 @@ static void usblp_disconnect(struct usb_interface *intf)
usblp->writebuf, usblp->writeurb->transfer_dma);
usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
usblp->readbuf, usblp->readurb->transfer_dma);
up (&usblp->sem);
if (!usblp->used)
usblp_cleanup (usblp);
else /* cleanup later, on release */
up (&usblp->sem);
unlock_kernel();
up (&usblp_sem);
}
static struct usb_device_id usblp_ids [] = {
......
This diff is collapsed.
......@@ -823,9 +823,19 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
*/
int usb_get_status(struct usb_device *dev, int type, int target, void *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2,
HZ * USB_CTRL_GET_TIMEOUT);
int ret;
u16 *status = kmalloc(sizeof(*status), GFP_KERNEL);
if (!status)
return -ENOMEM;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, status,
sizeof(*status), HZ * USB_CTRL_GET_TIMEOUT);
*(u16 *)data = *status;
kfree(status);
return ret;
}
/**
......
......@@ -264,11 +264,10 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
max = usb_maxpacket (dev, pipe, is_out);
if (max <= 0) {
dbg ("%s: bogus endpoint %d-%s on usb-%s-%s (bad maxpacket %d)",
__FUNCTION__,
usb_pipeendpoint (pipe), is_out ? "OUT" : "IN",
dev->bus->bus_name, dev->devpath,
max);
dev_dbg(&dev->dev,
"bogus endpoint ep%d%s in %s (bad maxpacket %d)",
usb_pipeendpoint (pipe), is_out ? "out" : "in",
__FUNCTION__, max);
return -EMSGSIZE;
}
......
......@@ -550,9 +550,7 @@ static int usb_device_match (struct device *dev, struct device_driver *drv)
return 0;
intf = to_usb_interface(dev);
usb_drv = to_usb_driver(drv);
id = usb_drv->id_table;
id = usb_match_id (intf, usb_drv->id_table);
if (id)
......@@ -765,6 +763,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port)
if (dev->bus->op->allocate)
if (dev->bus->op->allocate(dev)) {
usb_bus_put(bus);
kfree(dev);
return NULL;
}
......
......@@ -2320,7 +2320,7 @@ eth_bind (struct usb_gadget *gadget)
} else if (gadget_is_lh7a40x(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
} else if (gadget_is_n9604(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x020a);
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
} else {
/* can't assume CDC works. don't want to default to
* anything less functional on CDC-capable hardware,
......
......@@ -250,7 +250,7 @@
#define DRIVER_DESC "File-backed Storage Gadget"
#define DRIVER_NAME "g_file_storage"
#define DRIVER_VERSION "31 August 2004"
#define DRIVER_VERSION "20 October 2004"
static const char longname[] = DRIVER_DESC;
static const char shortname[] = DRIVER_NAME;
......@@ -430,9 +430,9 @@ MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
/* Command Block Wrapper */
struct bulk_cb_wrap {
u32 Signature; // Contains 'USBC'
__le32 Signature; // Contains 'USBC'
u32 Tag; // Unique per command id
u32 DataTransferLength; // Size of the data
__le32 DataTransferLength; // Size of the data
u8 Flags; // Direction in bit 7
u8 Lun; // LUN (normally 0)
u8 Length; // Of the CDB, <= MAX_COMMAND_SIZE
......@@ -445,9 +445,9 @@ struct bulk_cb_wrap {
/* Command Status Wrapper */
struct bulk_cs_wrap {
u32 Signature; // Should = 'USBS'
__le32 Signature; // Should = 'USBS'
u32 Tag; // Same as original command
u32 Residue; // Amount not transferred
__le32 Residue; // Amount not transferred
u8 Status; // See below
};
......@@ -3717,30 +3717,30 @@ static int __init check_parameters(struct fsg_dev *fsg)
if (mod_data.release == 0xffff) { // Parameter wasn't set
if (gadget_is_net2280(fsg->gadget))
mod_data.release = __constant_cpu_to_le16(0x0301);
mod_data.release = 0x0301;
else if (gadget_is_dummy(fsg->gadget))
mod_data.release = __constant_cpu_to_le16(0x0302);
mod_data.release = 0x0302;
else if (gadget_is_pxa(fsg->gadget))
mod_data.release = __constant_cpu_to_le16(0x0303);
mod_data.release = 0x0303;
else if (gadget_is_sh(fsg->gadget))
mod_data.release = __constant_cpu_to_le16(0x0304);
mod_data.release = 0x0304;
/* The sa1100 controller is not supported */
else if (gadget_is_goku(fsg->gadget))
mod_data.release = __constant_cpu_to_le16(0x0306);
mod_data.release = 0x0306;
else if (gadget_is_mq11xx(fsg->gadget))
mod_data.release = __constant_cpu_to_le16(0x0307);
mod_data.release = 0x0307;
else if (gadget_is_omap(fsg->gadget))
mod_data.release = __constant_cpu_to_le16(0x0308);
mod_data.release = 0x0308;
else if (gadget_is_lh7a40x(fsg->gadget))
mod_data.release = __constant_cpu_to_le16 (0x0309);
mod_data.release = 0x0309;
else if (gadget_is_n9604(fsg->gadget))
mod_data.release = __constant_cpu_to_le16 (0x030a);
mod_data.release = 0x0310;
else {
WARN(fsg, "controller '%s' not recognized\n",
fsg->gadget->name);
mod_data.release = __constant_cpu_to_le16(0x0399);
mod_data.release = 0x0399;
}
}
......
This diff is collapsed.
......@@ -216,9 +216,9 @@ struct goku_ep {
struct list_head queue;
const struct usb_endpoint_descriptor *desc;
u32 *reg_fifo;
u32 *reg_mode;
u32 *reg_status;
u32 __iomem *reg_fifo;
u32 __iomem *reg_mode;
u32 __iomem *reg_status;
};
struct goku_request {
......@@ -253,7 +253,7 @@ struct goku_udc {
/* pci state used to access those endpoints */
struct pci_dev *pdev;
struct goku_udc_regs *regs;
struct goku_udc_regs __iomem *regs;
u32 int_enable;
/* statistics... */
......
......@@ -717,7 +717,7 @@ fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid)
dmacount |= (1 << DMA_DONE_INTERRUPT_ENABLE);
/* td->dmadesc = previously set by caller */
td->dmaaddr = cpu_to_le32p (&req->req.dma);
td->dmaaddr = cpu_to_le32 (req->req.dma);
/* 2280 may be polling VALID_BIT through ep->dma->dmadesc */
wmb ();
......@@ -1707,8 +1707,10 @@ show_queues (struct device *_dev, char *buf)
td = req->td;
t = scnprintf (next, size, "\t td %08x "
" count %08x buf %08x desc %08x\n",
req->td_dma, td->dmacount,
td->dmaaddr, td->dmadesc);
(u32) req->td_dma,
le32_to_cpu (td->dmacount),
le32_to_cpu (td->dmaaddr),
le32_to_cpu (td->dmadesc));
if (t <= 0 || t > size)
goto done;
size -= t;
......@@ -2845,6 +2847,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
dev->got_irq = 1;
/* DMA setup */
/* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */
dev->requests = pci_pool_create ("requests", pdev,
sizeof (struct net2280_dma),
0 /* no alignment requirements */,
......
......@@ -495,10 +495,10 @@ set_idx_reg (struct net2280_regs __iomem *regs, u32 index, u32 value)
* use struct net2280_dma_regs bitfields
*/
struct net2280_dma {
u32 dmacount;
u32 dmaaddr; /* the buffer */
u32 dmadesc; /* next dma descriptor */
u32 _reserved;
__le32 dmacount;
__le32 dmaaddr; /* the buffer */
__le32 dmadesc; /* next dma descriptor */
__le32 _reserved;
} __attribute__ ((aligned (16)));
/*-------------------------------------------------------------------------*/
......
This diff is collapsed.
......@@ -146,11 +146,14 @@ struct omap_ep {
u8 bmAttributes;
unsigned double_buf:1;
unsigned stopped:1;
unsigned ackwait:1;
unsigned fnf:1;
unsigned has_dma:1;
u8 ackwait;
u8 dma_channel;
u16 dma_counter;
int lch;
struct omap_udc *udc;
struct timer_list timer;
};
struct omap_udc {
......@@ -168,7 +171,6 @@ struct omap_udc {
unsigned ep0_set_config:1;
unsigned ep0_reset_config:1;
unsigned ep0_setup:1;
unsigned hmc:6;
struct completion *done;
};
......
......@@ -1189,7 +1189,7 @@ zero_bind (struct usb_gadget *gadget)
} else if (gadget_is_lh7a40x(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
} else if (gadget_is_n9604(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x020a);
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
} else {
/* gadget zero is so simple (for now, no altsettings) that
* it SHOULD NOT have problems with bulk-capable hardware.
......
# Host-side USB depends on having a host controller
# NOTE: dummy_hcd is always an option, but it's ignored here ...
# NOTE: SL-811 option should be board-specific ...
config USB_ARCH_HAS_HCD
boolean
default y if USB_ARCH_HAS_OHCI
default y if ARM # SL-811
default PCI
# many non-PCI hcds implement OHCI
config USB_ARCH_HAS_OHCI
boolean
default y if SA1111
default y if ARCH_OMAP
default y if ARCH_LH7A404
default y if PXA27x
default PCI
#
# USB Host Controller Drivers
#
......@@ -6,7 +24,7 @@ comment "USB Host Controller Drivers"
config USB_EHCI_HCD
tristate "EHCI HCD (USB 2.0) support"
depends on USB
depends on USB && PCI
---help---
The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
"high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
......@@ -51,8 +69,8 @@ config USB_EHCI_ROOT_HUB_TT
config USB_OHCI_HCD
tristate "OHCI HCD support"
depends on USB
select ISP1301_OMAP if MACH_OMAP_H2
depends on USB && USB_ARCH_HAS_OHCI
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
---help---
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
......@@ -68,7 +86,7 @@ config USB_OHCI_HCD
config USB_UHCI_HCD
tristate "UHCI HCD (most Intel and VIA) support"
depends on USB
depends on USB && PCI
---help---
The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
......
......@@ -185,7 +185,7 @@ dbg_sitd (const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
}
static int __attribute__((__unused__))
dbg_status_buf (char *buf, unsigned len, char *label, u32 status)
dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
{
return scnprintf (buf, len,
"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
......@@ -204,7 +204,7 @@ dbg_status_buf (char *buf, unsigned len, char *label, u32 status)
}
static int __attribute__((__unused__))
dbg_intr_buf (char *buf, unsigned len, char *label, u32 enable)
dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
{
return scnprintf (buf, len,
"%s%sintrenable %02x%s%s%s%s%s%s",
......@@ -221,7 +221,8 @@ dbg_intr_buf (char *buf, unsigned len, char *label, u32 enable)
static const char *const fls_strings [] =
{ "1024", "512", "256", "??" };
static int dbg_command_buf (char *buf, unsigned len, char *label, u32 command)
static int
dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
{
return scnprintf (buf, len,
"%s%scommand %06x %s=%d ithresh=%d%s%s%s%s period=%s%s %s",
......@@ -240,7 +241,7 @@ static int dbg_command_buf (char *buf, unsigned len, char *label, u32 command)
}
static int
dbg_port_buf (char *buf, unsigned len, char *label, int port, u32 status)
dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
{
char *sig;
......@@ -276,19 +277,19 @@ dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
{}
static inline int __attribute__((__unused__))
dbg_status_buf (char *buf, unsigned len, char *label, u32 status)
dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
{ return 0; }
static inline int __attribute__((__unused__))
dbg_command_buf (char *buf, unsigned len, char *label, u32 command)
dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
{ return 0; }
static inline int __attribute__((__unused__))
dbg_intr_buf (char *buf, unsigned len, char *label, u32 enable)
dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
{ return 0; }
static inline int __attribute__((__unused__))
dbg_port_buf (char *buf, unsigned len, char *label, int port, u32 status)
dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
{ return 0; }
#endif /* DEBUG */
......
......@@ -347,9 +347,18 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
#ifdef CONFIG_PCI
/* EHCI 0.96 and later may have "extended capabilities" */
if (hcd->self.controller->bus == &pci_bus_type)
if (hcd->self.controller->bus == &pci_bus_type) {
struct pci_dev *pdev = to_pci_dev(ehci->hcd.self.controller);
/* AMD8111 EHCI doesn't work, according to AMD errata */
if ((pdev->vendor == PCI_VENDOR_ID_AMD)
&& (pdev->device == 0x7463)) {
ehci_info (ehci, "ignoring AMD8111 (errata)\n");
return -EIO;
}
temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
else
} else
temp = 0;
while (temp && count--) {
u32 cap;
......@@ -362,10 +371,6 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
if (bios_handoff (ehci, temp, cap) != 0)
return -EOPNOTSUPP;
break;
case 0x0a: /* appendix C */
ehci_dbg (ehci, "debug registers, BAR %d offset %d\n",
(cap >> 29) & 0x07, (cap >> 16) & 0x0fff);
break;
case 0: /* illegal reserved capability */
ehci_warn (ehci, "illegal capability!\n");
cap = 0;
......@@ -857,6 +862,30 @@ static int ehci_urb_enqueue (
}
}
static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
/* if we need to use IAA and it's busy, defer */
if (qh->qh_state == QH_STATE_LINKED
&& ehci->reclaim
&& HCD_IS_RUNNING (ehci->hcd.state)) {
struct ehci_qh *last;
for (last = ehci->reclaim;
last->reclaim;
last = last->reclaim)
continue;
qh->qh_state = QH_STATE_UNLINK_WAIT;
last->reclaim = qh;
/* bypass IAA if the hc can't care */
} else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
end_unlink_async (ehci, NULL);
/* something else might have unlinked the qh by now */
if (qh->qh_state == QH_STATE_LINKED)
start_unlink_async (ehci, qh);
}
/* remove from hardware lists
* completions normally happen asynchronously
*/
......@@ -875,28 +904,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
qh = (struct ehci_qh *) urb->hcpriv;
if (!qh)
break;
/* if we need to use IAA and it's busy, defer */
if (qh->qh_state == QH_STATE_LINKED
&& ehci->reclaim
&& HCD_IS_RUNNING (ehci->hcd.state)
) {
struct ehci_qh *last;
for (last = ehci->reclaim;
last->reclaim;
last = last->reclaim)
continue;
qh->qh_state = QH_STATE_UNLINK_WAIT;
last->reclaim = qh;
/* bypass IAA if the hc can't care */
} else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
end_unlink_async (ehci, NULL);
/* something else might have unlinked the qh by now */
if (qh->qh_state == QH_STATE_LINKED)
start_unlink_async (ehci, qh);
unlink_async (ehci, qh);
break;
case PIPE_INTERRUPT:
......@@ -949,7 +957,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
int epnum;
unsigned long flags;
struct ehci_qh *qh;
struct ehci_qh *qh, *tmp;
/* ASSERT: any requests/urbs are being unlinked */
/* ASSERT: nobody can be submitting urbs for this any more */
......@@ -975,6 +983,16 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
if (!HCD_IS_RUNNING (ehci->hcd.state))
qh->qh_state = QH_STATE_IDLE;
switch (qh->qh_state) {
case QH_STATE_LINKED:
for (tmp = ehci->async->qh_next.qh;
tmp && tmp != qh;
tmp = tmp->qh_next.qh)
continue;
/* periodic qh self-unlinks on empty */
if (!tmp)
goto nogood;
unlink_async (ehci, qh);
/* FALL THROUGH */
case QH_STATE_UNLINK: /* wait for hw to finish? */
idle_timeout:
spin_unlock_irqrestore (&ehci->lock, flags);
......@@ -988,6 +1006,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
}
/* else FALL THROUGH */
default:
nogood:
/* caller was supposed to have unlinked any requests;
* that's not our job. just leak this memory.
*/
......
......@@ -353,8 +353,8 @@ static void intr_deschedule (
hcd_to_bus (&ehci->hcd)->bandwidth_allocated -=
(qh->usecs + qh->c_usecs) / qh->period;
dbg ("descheduled qh %p, period = %d frame = %d count = %d, urbs = %d",
qh, qh->period, frame,
ehci_dbg (ehci, "descheduled qh%d/%p frame=%d count=%d, urbs=%d\n",
qh->period, qh, frame,
atomic_read (&qh->kref.refcount), ehci->periodic_sched);
}
......@@ -486,13 +486,14 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
qh->hw_info2 &= ~__constant_cpu_to_le32(0xffff);
qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask;
} else
dbg ("reused previous qh %p schedule", qh);
ehci_dbg (ehci, "reused qh %p schedule\n", qh);
/* stuff into the periodic schedule */
qh->qh_state = QH_STATE_LINKED;
dbg ("scheduled qh %p usecs %d/%d period %d.0 starting %d.%d (gap %d)",
qh, qh->usecs, qh->c_usecs,
qh->period, frame, uframe, qh->gap_uf);
ehci_dbg(ehci,
"scheduled qh%d/%p usecs %d/%d starting %d.%d (gap %d)\n",
qh->period, qh, qh->usecs, qh->c_usecs,
frame, uframe, qh->gap_uf);
do {
if (unlikely (ehci->pshadow [frame].ptr != 0)) {
......
......@@ -154,6 +154,11 @@ static int power_switching = 0;
module_param (power_switching, bool, 0);
MODULE_PARM_DESC (power_switching, "true (not default) to switch port power");
/* Some boards leave IR set wrongly, since they fail BIOS/SMM handshakes */
static int no_handshake = 0;
module_param (no_handshake, bool, 0);
MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake");
/*-------------------------------------------------------------------------*/
/*
......@@ -426,7 +431,7 @@ static int ohci_init (struct ohci_hcd *ohci)
#ifndef IR_DISABLE
/* SMM owns the HC? not for long! */
if (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
if (!no_handshake && ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
/* this timeout is arbitrary. we make it long, so systems
......
......@@ -765,8 +765,12 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH);
/* Low-speed transfers get a different queue, and won't hog the bus */
if (urb->dev->speed == USB_SPEED_LOW)
/* Low-speed transfers get a different queue, and won't hog the bus.
* Also, some devices enumerate better without FSBR; the easiest way
* to do that is to put URBs on the low-speed queue while the device
* is in the DEFAULT state. */
if (urb->dev->speed == USB_SPEED_LOW ||
urb->dev->state == USB_STATE_DEFAULT)
skelqh = uhci->skel_ls_control_qh;
else {
skelqh = uhci->skel_fs_control_qh;
......
#
# USB Input driver configuration
#
comment "USB Human Interface Devices (HID)"
comment "USB Input Devices"
depends on USB
config USB_HID
......@@ -12,7 +12,8 @@ config USB_HID
mice, joysticks, graphic tablets, or any other HID based devices
to your computer via USB. You also need to select HID Input layer
support (below) if you want to use keyboards, mice, joysticks and
the like.
the like ... as well as Uninterruptible Power Supply (UPS) and
monitor control devices.
You can't use this driver and the HIDBP (Boot Protocol) keyboard
and mouse drivers at the same time. More information is available:
......@@ -24,7 +25,7 @@ config USB_HID
module will be called usbhid.
comment "Input core support is needed for USB HID input layer or HIDBP support"
depends on USB && INPUT=n
depends on USB_HID && INPUT=n
config USB_HIDINPUT
bool "HID input layer support"
......@@ -32,8 +33,7 @@ config USB_HIDINPUT
depends on INPUT && USB_HID
help
Say Y here if you want to use a USB keyboard, mouse or joystick,
or any other HID input device. You also need "Input core support",
(CONFIG_INPUT), which you select under "Input device support", above.
or any other HID input device.
If unsure, say Y.
......@@ -87,7 +87,6 @@ config USB_HIDDEV
This module supports these devices separately using a separate
event interface on /dev/usb/hiddevX (char 180:96 to 180:111).
This driver requires CONFIG_USB_HID.
If unsure, say Y.
......
......@@ -925,6 +925,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
case -ECONNRESET: /* unlink */
case -ENOENT:
case -ESHUTDOWN:
case -EPERM:
return;
case -ETIMEDOUT: /* NAK */
break;
......@@ -1833,6 +1834,30 @@ static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id
return 0;
}
static int hid_suspend(struct usb_interface *intf, u32 state)
{
struct hid_device *hid = usb_get_intfdata (intf);
usb_kill_urb(hid->urbin);
intf->dev.power.power_state = state;
dev_dbg(&intf->dev, "suspend\n");
return 0;
}
static int hid_resume(struct usb_interface *intf)
{
struct hid_device *hid = usb_get_intfdata (intf);
int status;
intf->dev.power.power_state = PM_SUSPEND_ON;
if (hid->open)
status = usb_submit_urb(hid->urbin, GFP_NOIO);
else
status = 0;
dev_dbg(&intf->dev, "resume status %d\n", status);
return status;
}
static struct usb_device_id hid_usb_ids [] = {
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
.bInterfaceClass = USB_INTERFACE_CLASS_HID },
......@@ -1846,6 +1871,8 @@ static struct usb_driver hid_driver = {
.name = "usbhid",
.probe = hid_probe,
.disconnect = hid_disconnect,
.suspend = hid_suspend,
.resume = hid_resume,
.id_table = hid_usb_ids,
};
......
......@@ -595,8 +595,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
if (file->f_flags & O_NONBLOCK) {
return -EBUSY;
}
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout (HZ / 2);
msleep_interruptible(500);
if (signal_pending (current)) {
return -EAGAIN;
......
......@@ -135,7 +135,7 @@ static const struct w9968cf_format w9968cf_formatlist[] = {
#define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \
"Dual Mode Camera Chip"
#define W9968CF_MODULE_VERSION "1:1.32-basic"
#define W9968CF_MODULE_VERSION "1:1.33-basic"
#define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia"
#define W9968CF_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define W9968CF_MODULE_LICENSE "GPL"
......
......@@ -121,6 +121,16 @@ config USB_CYTHERM
To compile this driver as a module, choose M here: the
module will be called cytherm.
config USB_PHIDGETKIT
tristate "USB PhidgetKit support"
depends on USB
help
Say Y here if you want to connect a PhidgetKit USB device from
Phidgets Inc.
To compile this driver as a module, choose M here: the
module will be called phidgetkit.
config USB_PHIDGETSERVO
tristate "USB PhidgetServo support"
depends on USB
......
......@@ -10,8 +10,9 @@ obj-$(CONFIG_USB_EMI62) += emi62.o
obj-$(CONFIG_USB_LCD) += usblcd.o
obj-$(CONFIG_USB_LED) += usbled.o
obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o
obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o
obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
obj-$(CONFIG_USB_RIO500) += rio500.o
obj-$(CONFIG_USB_TEST) += usbtest.o
obj-$(CONFIG_USB_TIGL) += tiglusb.o
obj-$(CONFIG_USB_USS720) += uss720.o
obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
This diff is collapsed.
......@@ -4,7 +4,7 @@
* Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
*
* Copyright (C) 2001-2004:
* Romain Lievin <roms@lpg.ticalc.org>
* Romain Lievin <roms@tilp.info>
* Julien BLACHE <jb@technologeek.org>
* under the terms of the GNU General Public License.
*
......@@ -14,7 +14,7 @@
* and the website at: http://lpg.ticalc.org/prj_usb/
* for more info.
*
* History :
* History:
* 1.0x, Romain & Julien: initial submit.
* 1.03, Greg Kroah: modifications.
* 1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
......@@ -22,6 +22,7 @@
* 1.06, Romain: synched with 2.5, version/firmware changed (confusing).
* 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument);
* timeout argument checked in ioctl + clean-up.
* 1.08, Romain: added support of USB port embedded on some TI's handhelds.
*/
#include <linux/module.h>
......@@ -41,7 +42,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "1.07"
#define DRIVER_VERSION "1.08"
#define DRIVER_AUTHOR "Romain Lievin <roms@tilp.info> & Julien Blache <jb@jblache.org>"
#define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver"
#define DRIVER_LICENSE "GPL"
......@@ -115,8 +116,7 @@ tiglusb_open (struct inode *inode, struct file *filp)
return -EBUSY;
}
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout (HZ / 2);
msleep_interruptible(500);
if (signal_pending (current)) {
return -EAGAIN;
......@@ -178,11 +178,11 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
if (!s->dev)
return -EIO;
buffer = kmalloc(BULK_RCV_MAX, GFP_KERNEL);
buffer = kmalloc (s->max_ps, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
bytes_to_read = (count >= BULK_RCV_MAX) ? BULK_RCV_MAX : count;
bytes_to_read = (count >= s->max_ps) ? s->max_ps : count;
pipe = usb_rcvbulkpipe (s->dev, 1);
result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read,
......@@ -235,11 +235,11 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
if (!s->dev)
return -EIO;
buffer = kmalloc(BULK_SND_MAX, GFP_KERNEL);
buffer = kmalloc (s->max_ps, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
bytes_to_write = (count >= BULK_SND_MAX) ? BULK_SND_MAX : count;
bytes_to_write = (count >= s->max_ps) ? s->max_ps : count;
if (copy_from_user (buffer, buf, bytes_to_write)) {
ret = -EFAULT;
goto out;
......@@ -309,6 +309,15 @@ tiglusb_ioctl (struct inode *inode, struct file *filp,
if (clear_pipes (s->dev))
ret = -EIO;
break;
case IOCTL_TIUSB_GET_MAXPS:
if (copy_to_user((int *) arg, &s->max_ps, sizeof(int)))
return -EFAULT;
break;
case IOCTL_TIUSB_GET_DEVID:
if (copy_to_user((int *) arg, &s->dev->descriptor.idProduct,
sizeof(int)))
return -EFAULT;
break;
default:
ret = -ENOTTY;
break;
......@@ -341,6 +350,9 @@ tiglusb_probe (struct usb_interface *intf,
int minor = -1;
int i, err = 0;
ptiglusb_t s;
struct usb_host_config *conf;
struct usb_host_interface *ifdata = NULL;
int max_ps;
dbg ("probing vendor id 0x%x, device id 0x%x",
dev->descriptor.idVendor, dev->descriptor.idProduct);
......@@ -355,19 +367,31 @@ tiglusb_probe (struct usb_interface *intf,
goto out;
}
if ((dev->descriptor.idProduct != 0xe001)
&& (dev->descriptor.idVendor != 0x451)) {
if (dev->descriptor.idVendor != 0x451) {
err = -ENODEV;
goto out;
}
// NOTE: it's already in this config, this shouldn't be needed.
// is this working around some hardware bug?
if (usb_reset_configuration (dev) < 0) {
err ("tiglusb_probe: reset_configuration failed");
err = -ENODEV;
goto out;
}
if ((dev->descriptor.idProduct != 0xe001) &&
(dev->descriptor.idProduct != 0xe004) &&
(dev->descriptor.idProduct != 0xe008)) {
err = -ENODEV;
goto out;
}
/*
* TI introduced some new handhelds with embedded USB port.
* Port advertises same config as SilverLink cable but with a
* different maximum packet size (64 rather than 32).
*/
conf = dev->actconfig;
ifdata = conf->interface[0]->cur_altsetting;
max_ps = ifdata->endpoint[0].desc.wMaxPacketSize;
info("max packet size of %d/%d bytes\n",
ifdata->endpoint[0].desc.wMaxPacketSize,
ifdata->endpoint[1].desc.wMaxPacketSize);
/*
* Find a tiglusb struct
......@@ -390,6 +414,7 @@ tiglusb_probe (struct usb_interface *intf,
down (&s->mutex);
s->remove_pending = 0;
s->dev = dev;
s->max_ps = max_ps;
up (&s->mutex);
dbg ("bound to interface");
......
......@@ -17,12 +17,6 @@
*/
#define MAXTIGL 16
/*
* Max. packetsize for IN and OUT pipes
*/
#define BULK_RCV_MAX 32
#define BULK_SND_MAX 32
/*
* The driver context...
*/
......@@ -42,6 +36,8 @@ typedef struct
driver_state_t state; /* started/stopped */
int opened; /* tru if open */
int remove_pending;
int max_ps; /* max packet size */
} tiglusb_t, *ptiglusb_t;
#endif
......@@ -246,7 +246,7 @@ struct kaweth_device
struct kaweth_ethernet_configuration configuration;
struct net_device_stats stats;
} __attribute__ ((packed));
};
/****************************************************************
......@@ -651,7 +651,7 @@ static void kaweth_usb_receive(struct urb *urb, struct pt_regs *regs)
****************************************************************/
static int kaweth_open(struct net_device *net)
{
struct kaweth_device *kaweth = (struct kaweth_device *)net->priv;
struct kaweth_device *kaweth = netdev_priv(net);
int res;
kaweth_dbg("Opening network device.");
......@@ -689,7 +689,7 @@ static int kaweth_open(struct net_device *net)
****************************************************************/
static int kaweth_close(struct net_device *net)
{
struct kaweth_device *kaweth = net->priv;
struct kaweth_device *kaweth = netdev_priv(net);
netif_stop_queue(net);
......@@ -729,7 +729,8 @@ static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs)
struct sk_buff *skb = kaweth->tx_skb;
if (unlikely(urb->status != 0))
kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);
if (urb->status != -ENOENT)
kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);
netif_wake_queue(kaweth->net);
dev_kfree_skb_irq(skb);
......@@ -740,7 +741,7 @@ static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs)
****************************************************************/
static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
{
struct kaweth_device *kaweth = net->priv;
struct kaweth_device *kaweth = netdev_priv(net);
__le16 *private_header;
int res;
......@@ -811,7 +812,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
****************************************************************/
static void kaweth_set_rx_mode(struct net_device *net)
{
struct kaweth_device *kaweth = net->priv;
struct kaweth_device *kaweth = netdev_priv(net);
__u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED |
KAWETH_PACKET_FILTER_BROADCAST |
......@@ -868,7 +869,8 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
****************************************************************/
static struct net_device_stats *kaweth_netdev_stats(struct net_device *dev)
{
return &((struct kaweth_device *)dev->priv)->stats;
struct kaweth_device *kaweth = netdev_priv(dev);
return &kaweth->stats;
}
/****************************************************************
......@@ -876,7 +878,7 @@ static struct net_device_stats *kaweth_netdev_stats(struct net_device *dev)
****************************************************************/
static void kaweth_tx_timeout(struct net_device *net)
{
struct kaweth_device *kaweth = net->priv;
struct kaweth_device *kaweth = netdev_priv(net);
kaweth_warn("%s: Tx timed out. Resetting.", net->name);
kaweth->stats.tx_errors++;
......@@ -911,12 +913,14 @@ static int kaweth_probe(
(int)dev->descriptor.bLength,
(int)dev->descriptor.bDescriptorType);
if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL)))
netdev = alloc_etherdev(sizeof(*kaweth));
if (!netdev)
return -ENOMEM;
memset(kaweth, 0, sizeof(struct kaweth_device));
kaweth = netdev_priv(netdev);
kaweth->dev = dev;
kaweth->net = netdev;
spin_lock_init(&kaweth->device_lock);
init_waitqueue_head(&kaweth->term_wait);
......@@ -941,9 +945,7 @@ static int kaweth_probe(
100,
2)) < 0) {
kaweth_err("Error downloading firmware (%d)", result);
free_page((unsigned long)kaweth->firmware_buf);
kfree(kaweth);
return -EIO;
goto err_fw;
}
if ((result = kaweth_download_firmware(kaweth,
......@@ -952,9 +954,7 @@ static int kaweth_probe(
100,
3)) < 0) {
kaweth_err("Error downloading firmware fix (%d)", result);
free_page((unsigned long)kaweth->firmware_buf);
kfree(kaweth);
return -EIO;
goto err_fw;
}
if ((result = kaweth_download_firmware(kaweth,
......@@ -963,9 +963,8 @@ static int kaweth_probe(
126,
2)) < 0) {
kaweth_err("Error downloading trigger code (%d)", result);
free_page((unsigned long)kaweth->firmware_buf);
kfree(kaweth);
return -EIO;
goto err_fw;
}
if ((result = kaweth_download_firmware(kaweth,
......@@ -974,23 +973,20 @@ static int kaweth_probe(
126,
3)) < 0) {
kaweth_err("Error downloading trigger code fix (%d)", result);
free_page((unsigned long)kaweth->firmware_buf);
kfree(kaweth);
return -EIO;
goto err_fw;
}
if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
kaweth_err("Error triggering firmware (%d)", result);
free_page((unsigned long)kaweth->firmware_buf);
kfree(kaweth);
return -EIO;
goto err_fw;
}
/* Device will now disappear for a moment... */
kaweth_info("Firmware loaded. I'll be back...");
err_fw:
free_page((unsigned long)kaweth->firmware_buf);
kfree(kaweth);
free_netdev(netdev);
return -EIO;
}
......@@ -998,8 +994,7 @@ static int kaweth_probe(
if(result < 0) {
kaweth_err("Error reading configuration (%d), no net device created", result);
kfree(kaweth);
return -EIO;
goto err_free_netdev;
}
kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask);
......@@ -1017,18 +1012,17 @@ static int kaweth_probe(
&bcast_addr,
sizeof(bcast_addr))) {
kaweth_err("Firmware not functioning properly, no net device created");
kfree(kaweth);
return -EIO;
goto err_free_netdev;
}
if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) {
kaweth_dbg("Error setting URB size");
goto err_no_netdev;
goto err_free_netdev;
}
if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) {
kaweth_err("Error setting SOFS wait");
goto err_no_netdev;
goto err_free_netdev;
}
result = kaweth_set_receive_filter(kaweth,
......@@ -1038,20 +1032,14 @@ static int kaweth_probe(
if(result < 0) {
kaweth_err("Error setting receive filter");
kfree(kaweth);
return -EIO;
goto err_free_netdev;
}
kaweth_dbg("Initializing net device.");
if (!(netdev = alloc_etherdev(0))) {
kfree(kaweth);
return -ENOMEM;
}
kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kaweth->tx_urb)
goto err_no_urb;
goto err_free_netdev;
kaweth->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kaweth->rx_urb)
goto err_only_tx;
......@@ -1072,26 +1060,23 @@ static int kaweth_probe(
if (!kaweth->rx_buf)
goto err_all_but_rxbuf;
kaweth->net = netdev;
memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr));
memcpy(kaweth->net->dev_addr,
&kaweth->configuration.hw_addr,
memcpy(netdev->broadcast, &bcast_addr, sizeof(bcast_addr));
memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr,
sizeof(kaweth->configuration.hw_addr));
kaweth->net->priv = kaweth;
kaweth->net->open = kaweth_open;
kaweth->net->stop = kaweth_close;
netdev->open = kaweth_open;
netdev->stop = kaweth_close;
kaweth->net->watchdog_timeo = KAWETH_TX_TIMEOUT;
kaweth->net->tx_timeout = kaweth_tx_timeout;
netdev->watchdog_timeo = KAWETH_TX_TIMEOUT;
netdev->tx_timeout = kaweth_tx_timeout;
kaweth->net->hard_start_xmit = kaweth_start_xmit;
kaweth->net->set_multicast_list = kaweth_set_rx_mode;
kaweth->net->get_stats = kaweth_netdev_stats;
kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size);
SET_ETHTOOL_OPS(kaweth->net, &ops);
netdev->hard_start_xmit = kaweth_start_xmit;
netdev->set_multicast_list = kaweth_set_rx_mode;
netdev->get_stats = kaweth_netdev_stats;
netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size);
SET_ETHTOOL_OPS(netdev, &ops);
memset(&kaweth->stats, 0, sizeof(kaweth->stats));
/* kaweth is zeroed as part of alloc_netdev */
INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth);
......@@ -1128,10 +1113,9 @@ static int kaweth_probe(
usb_free_urb(kaweth->rx_urb);
err_only_tx:
usb_free_urb(kaweth->tx_urb);
err_no_urb:
err_free_netdev:
free_netdev(netdev);
err_no_netdev:
kfree(kaweth);
return -EIO;
}
......@@ -1141,6 +1125,7 @@ static int kaweth_probe(
static void kaweth_disconnect(struct usb_interface *intf)
{
struct kaweth_device *kaweth = usb_get_intfdata(intf);
struct net_device *netdev;
kaweth_info("Unregistering");
......@@ -1149,40 +1134,23 @@ static void kaweth_disconnect(struct usb_interface *intf)
kaweth_warn("unregistering non-existant device");
return;
}
netdev = kaweth->net;
kaweth->removed = 1;
usb_kill_urb(kaweth->irq_urb);
usb_kill_urb(kaweth->rx_urb);
usb_kill_urb(kaweth->tx_urb);
/* we need to wait for the urb to be cancelled, if it is active */
spin_lock(&kaweth->device_lock);
if (usb_unlink_urb(kaweth->tx_urb) == -EINPROGRESS) {
spin_unlock(&kaweth->device_lock);
wait_event(kaweth->term_wait, kaweth->end);
} else {
spin_unlock(&kaweth->device_lock);
}
if(kaweth->net) {
if(kaweth->net->flags & IFF_UP) {
kaweth_dbg("Closing net device");
dev_close(kaweth->net);
}
kaweth_dbg("Unregistering net device");
unregister_netdev(kaweth->net);
free_netdev(kaweth->net);
}
kaweth_dbg("Unregistering net device");
unregister_netdev(netdev);
usb_free_urb(kaweth->rx_urb);
usb_free_urb(kaweth->tx_urb);
usb_free_urb(kaweth->irq_urb);
usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
kfree(kaweth);
free_netdev(netdev);
}
......
......@@ -567,7 +567,7 @@ static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 i
static void ax8817x_set_multicast(struct net_device *net)
{
struct usbnet *dev = (struct usbnet *) net->priv;
struct usbnet *dev = netdev_priv(net);
struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
u8 rx_ctl = 0x8c;
......@@ -610,7 +610,7 @@ static void ax8817x_set_multicast(struct net_device *net)
static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
{
struct usbnet *dev = netdev->priv;
struct usbnet *dev = netdev_priv(netdev);
u16 res;
u8 buf[1];
......@@ -623,7 +623,7 @@ static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
{
struct usbnet *dev = netdev->priv;
struct usbnet *dev = netdev_priv(netdev);
u16 res = val;
u8 buf[1];
......@@ -634,7 +634,7 @@ static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, i
static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = (struct usbnet *)net->priv;
struct usbnet *dev = netdev_priv(net);
u8 opt;
if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
......@@ -654,7 +654,7 @@ static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *woli
static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = (struct usbnet *)net->priv;
struct usbnet *dev = netdev_priv(net);
u8 opt = 0;
u8 buf[1];
......@@ -675,7 +675,7 @@ static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolin
static int ax8817x_get_eeprom(struct net_device *net,
struct ethtool_eeprom *eeprom, u8 *data)
{
struct usbnet *dev = (struct usbnet *)net->priv;
struct usbnet *dev = netdev_priv(net);
u16 *ebuf = (u16 *)data;
int i;
......@@ -704,14 +704,14 @@ static void ax8817x_get_drvinfo (struct net_device *net,
static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
{
struct usbnet *dev = (struct usbnet *)net->priv;
struct usbnet *dev = netdev_priv(net);
return mii_ethtool_gset(&dev->mii,cmd);
}
static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
{
struct usbnet *dev = (struct usbnet *)net->priv;
struct usbnet *dev = netdev_priv(net);
return mii_ethtool_sset(&dev->mii,cmd);
}
......@@ -2276,7 +2276,7 @@ static const struct driver_info zaurus_pxa_info = {
static int usbnet_change_mtu (struct net_device *net, int new_mtu)
{
struct usbnet *dev = (struct usbnet *) net->priv;
struct usbnet *dev = netdev_priv(net);
if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET)
return -EINVAL;
......@@ -2302,7 +2302,8 @@ static int usbnet_change_mtu (struct net_device *net, int new_mtu)
static struct net_device_stats *usbnet_get_stats (struct net_device *net)
{
return &((struct usbnet *) net->priv)->stats;
struct usbnet *dev = netdev_priv(net);
return &dev->stats;
}
/*-------------------------------------------------------------------------*/
......@@ -2569,7 +2570,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
static int usbnet_stop (struct net_device *net)
{
struct usbnet *dev = (struct usbnet *) net->priv;
struct usbnet *dev = netdev_priv(net);
int temp;
DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
DECLARE_WAITQUEUE (wait, current);
......@@ -2616,7 +2617,7 @@ static int usbnet_stop (struct net_device *net)
static int usbnet_open (struct net_device *net)
{
struct usbnet *dev = (struct usbnet *) net->priv;
struct usbnet *dev = netdev_priv(net);
int retval = 0;
struct driver_info *info = dev->driver_info;
......@@ -2666,7 +2667,7 @@ static int usbnet_open (struct net_device *net)
static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
{
struct usbnet *dev = net->priv;
struct usbnet *dev = netdev_priv(net);
strncpy (info->driver, driver_name, sizeof info->driver);
strncpy (info->version, DRIVER_VERSION, sizeof info->version);
......@@ -2677,7 +2678,7 @@ static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *
static u32 usbnet_get_link (struct net_device *net)
{
struct usbnet *dev = net->priv;
struct usbnet *dev = netdev_priv(net);
/* If a check_connect is defined, return it's results */
if (dev->driver_info->check_connect)
......@@ -2689,14 +2690,14 @@ static u32 usbnet_get_link (struct net_device *net)
static u32 usbnet_get_msglevel (struct net_device *net)
{
struct usbnet *dev = net->priv;
struct usbnet *dev = netdev_priv(net);
return dev->msg_level;
}
static void usbnet_set_msglevel (struct net_device *net, u32 level)
{
struct usbnet *dev = net->priv;
struct usbnet *dev = netdev_priv(net);
dev->msg_level = level;
}
......@@ -2705,7 +2706,7 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
{
#ifdef NEED_MII
{
struct usbnet *dev = (struct usbnet *)net->priv;
struct usbnet *dev = netdev_priv(net);
if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
......@@ -2817,7 +2818,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
static void usbnet_tx_timeout (struct net_device *net)
{
struct usbnet *dev = (struct usbnet *) net->priv;
struct usbnet *dev = netdev_priv(net);
unlink_urbs (dev, &dev->txq);
tasklet_schedule (&dev->bh);
......@@ -2829,7 +2830,7 @@ static void usbnet_tx_timeout (struct net_device *net)
static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
{
struct usbnet *dev = (struct usbnet *) net->priv;
struct usbnet *dev = netdev_priv(net);
int length;
int retval = NET_XMIT_SUCCESS;
struct urb *urb = NULL;
......@@ -3014,6 +3015,7 @@ static void usbnet_disconnect (struct usb_interface *intf)
{
struct usbnet *dev;
struct usb_device *xdev;
struct net_device *net;
dev = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL);
......@@ -3026,7 +3028,8 @@ static void usbnet_disconnect (struct usb_interface *intf)
xdev->bus->bus_name, xdev->devpath,
dev->driver_info->description);
unregister_netdev (dev->net);
net = dev->net;
unregister_netdev (net);
/* we don't hold rtnl here ... */
flush_scheduled_work ();
......@@ -3034,8 +3037,7 @@ static void usbnet_disconnect (struct usb_interface *intf)
if (dev->driver_info->unbind)
dev->driver_info->unbind (dev, intf);
free_netdev(dev->net);
kfree (dev);
free_netdev(net);
usb_put_dev (xdev);
}
......@@ -3069,12 +3071,13 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
status = -ENOMEM;
// set up our own records
if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) {
net = alloc_etherdev(sizeof(*dev));
if (!net) {
dbg ("can't kmalloc dev");
goto out;
}
memset (dev, 0, sizeof *dev);
dev = netdev_priv(net);
dev->udev = xdev;
dev->driver_info = info;
dev->msg_level = msg_level;
......@@ -3088,14 +3091,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
dev->delay.data = (unsigned long) dev;
init_timer (&dev->delay);
// set up network interface records
net = alloc_etherdev(0);
if (!net)
goto out1;
SET_MODULE_OWNER (net);
dev->net = net;
net->priv = dev;
strcpy (net->name, "usb%d");
memcpy (net->dev_addr, node_id, sizeof node_id);
......@@ -3144,8 +3141,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
SET_NETDEV_DEV(dev->net, &udev->dev);
status = register_netdev (dev->net);
SET_NETDEV_DEV(net, &udev->dev);
status = register_netdev (net);
if (status)
goto out3;
devinfo (dev, "register usbnet at usb-%s-%s, %s",
......@@ -3156,16 +3153,15 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
usb_set_intfdata (udev, dev);
// start as if the link is up
netif_device_attach (dev->net);
netif_device_attach (net);
return 0;
out3:
if (info->unbind)
info->unbind (dev, udev);
free_netdev(net);
out1:
kfree(dev);
free_netdev(net);
out:
usb_put_dev(xdev);
return status;
......@@ -3252,6 +3248,10 @@ static const struct usb_device_id products [] = {
// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
USB_DEVICE (0x6189, 0x182d),
.driver_info = (unsigned long) &ax8817x_info,
}, {
// corega FEther USB2-TX
USB_DEVICE (0x07aa, 0x0017),
.driver_info = (unsigned long) &ax8817x_info,
}, {
// Surecom EP-1427X-2
USB_DEVICE (0x1189, 0x0893),
......
......@@ -607,6 +607,7 @@ module_exit (belkin_sa_exit);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_VERSION( DRIVER_VERSION );
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
......
......@@ -502,6 +502,7 @@ module_exit(cyberjack_exit);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_VERSION( DRIVER_VERSION );
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
......
......@@ -90,6 +90,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },
{ USB_DEVICE(PHAROS_VENDOR_ID, PHAROS_PRODUCT_ID) },
{ } /* Terminating entry */
};
......@@ -1188,6 +1189,7 @@ module_init(pl2303_init);
module_exit(pl2303_exit);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
......
......@@ -50,3 +50,6 @@
#define SAMSUNG_VENDOR_ID 0x04e8
#define SAMSUNG_PRODUCT_ID 0x8001
/* Pharos / Microsoft GPS puck */
#define PHAROS_VENDOR_ID 0x067b
#define PHAROS_PRODUCT_ID 0xaaa0
......@@ -452,18 +452,12 @@ static void destroy_serial(struct kref *kref)
port = serial->port[i];
if (!port)
continue;
if (port->read_urb) {
usb_kill_urb(port->read_urb);
usb_free_urb(port->read_urb);
}
if (port->write_urb) {
usb_kill_urb(port->write_urb);
usb_free_urb(port->write_urb);
}
if (port->interrupt_in_urb) {
usb_kill_urb(port->interrupt_in_urb);
usb_free_urb(port->interrupt_in_urb);
}
usb_kill_urb(port->read_urb);
usb_free_urb(port->read_urb);
usb_kill_urb(port->write_urb);
usb_free_urb(port->write_urb);
usb_kill_urb(port->interrupt_in_urb);
usb_free_urb(port->interrupt_in_urb);
kfree(port->bulk_in_buffer);
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
......@@ -799,18 +793,12 @@ static void port_release(struct device *dev)
struct usb_serial_port *port = to_usb_serial_port(dev);
dbg ("%s - %s", __FUNCTION__, dev->bus_id);
if (port->read_urb) {
usb_kill_urb(port->read_urb);
usb_free_urb(port->read_urb);
}
if (port->write_urb) {
usb_kill_urb(port->write_urb);
usb_free_urb(port->write_urb);
}
if (port->interrupt_in_urb) {
usb_kill_urb(port->interrupt_in_urb);
usb_free_urb(port->interrupt_in_urb);
}
usb_kill_urb(port->read_urb);
usb_free_urb(port->read_urb);
usb_kill_urb(port->write_urb);
usb_free_urb(port->write_urb);
usb_kill_urb(port->interrupt_in_urb);
usb_free_urb(port->interrupt_in_urb);
kfree(port->bulk_in_buffer);
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
......
......@@ -381,10 +381,17 @@ static struct usb_serial_device_type clie_3_5_device = {
.read_bulk_callback = visor_read_bulk_callback,
};
struct visor_private {
spinlock_t lock;
int bytes_in;
int bytes_out;
int outstanding_urbs;
};
static int bytes_in;
static int bytes_out;
/* number of outstanding urbs to prevent userspace DoS from happening */
#define URB_UPPER_LIMIT 42
static int stats;
/******************************************************************************
* Handspring Visor specific driver functions
......@@ -392,6 +399,8 @@ static int bytes_out;
static int visor_open (struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
int result = 0;
dbg("%s - port %d", __FUNCTION__, port->number);
......@@ -402,8 +411,11 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
return -ENODEV;
}
bytes_in = 0;
bytes_out = 0;
spin_lock_irqsave(&priv->lock, flags);
priv->bytes_in = 0;
priv->bytes_out = 0;
priv->outstanding_urbs = 0;
spin_unlock_irqrestore(&priv->lock, flags);
/*
* Force low_latency on so that our tty_push actually forces the data
......@@ -441,6 +453,7 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
static void visor_close (struct usb_serial_port *port, struct file * filp)
{
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned char *transfer_buffer;
dbg("%s - port %d", __FUNCTION__, port->number);
......@@ -461,20 +474,32 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
kfree (transfer_buffer);
}
/* Uncomment the following line if you want to see some statistics in your syslog */
/* dev_info (&port->dev, "Bytes In = %d Bytes Out = %d\n", bytes_in, bytes_out); */
if (stats)
dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n",
priv->bytes_in, priv->bytes_out);
}
static int visor_write (struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct visor_private *priv = usb_get_serial_port_data(port);
struct usb_serial *serial = port->serial;
struct urb *urb;
unsigned char *buffer;
unsigned long flags;
int status;
dbg("%s - port %d", __FUNCTION__, port->number);
spin_lock_irqsave(&priv->lock, flags);
if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(&port->dev, "write limit hit\n");
return 0;
}
++priv->outstanding_urbs;
spin_unlock_irqrestore(&priv->lock, flags);
buffer = kmalloc (count, GFP_ATOMIC);
if (!buffer) {
dev_err(&port->dev, "out of memory\n");
......@@ -506,7 +531,10 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
count = status;
kfree (buffer);
} else {
bytes_out += count;
spin_lock_irqsave(&priv->lock, flags);
++priv->outstanding_urbs;
priv->bytes_out += count;
spin_unlock_irqrestore(&priv->lock, flags);
}
/* we are done with this urb, so let the host driver
......@@ -547,6 +575,8 @@ static int visor_chars_in_buffer (struct usb_serial_port *port)
static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
......@@ -557,6 +587,10 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
dbg("%s - nonzero write bulk status received: %d",
__FUNCTION__, urb->status);
spin_lock_irqsave(&priv->lock, flags);
--priv->outstanding_urbs;
spin_unlock_irqrestore(&priv->lock, flags);
schedule_work(&port->work);
}
......@@ -564,8 +598,10 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct tty_struct *tty;
struct visor_private *priv = usb_get_serial_port_data(port);
unsigned char *data = urb->transfer_buffer;
struct tty_struct *tty;
unsigned long flags;
int i;
int result;
......@@ -590,7 +626,9 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
}
tty_flip_buffer_push(tty);
}
bytes_in += urb->actual_length;
spin_lock_irqsave(&priv->lock, flags);
priv->bytes_in += urb->actual_length;
spin_unlock_irqrestore(&priv->lock, flags);
/* Continue trying to always read */
usb_fill_bulk_urb (port->read_urb, port->serial->dev,
......@@ -825,6 +863,22 @@ static int visor_calc_num_ports (struct usb_serial *serial)
return num_ports;
}
static int generic_startup(struct usb_serial *serial)
{
struct visor_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) {
priv = kmalloc (sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
memset (priv, 0x00, sizeof(*priv));
spin_lock_init(&priv->lock);
usb_set_serial_port_data(serial->port[i], priv);
}
return 0;
}
static int clie_3_5_startup (struct usb_serial *serial)
{
struct device *dev = &serial->dev->dev;
......@@ -864,7 +918,7 @@ static int clie_3_5_startup (struct usb_serial *serial)
return -EIO;
}
return 0;
return generic_startup(serial);
}
static int treo_attach (struct usb_serial *serial)
......@@ -903,7 +957,7 @@ static int treo_attach (struct usb_serial *serial)
COPY_PORT(serial->port[1], swap_port);
kfree(swap_port);
return 0;
return generic_startup(serial);
}
static int clie_5_attach (struct usb_serial *serial)
......@@ -924,7 +978,7 @@ static int clie_5_attach (struct usb_serial *serial)
/* port 0 now uses the modified endpoint Address */
serial->port[0]->bulk_out_endpointAddress = serial->port[1]->bulk_out_endpointAddress;
return 0;
return generic_startup(serial);
}
static void visor_shutdown (struct usb_serial *serial)
......@@ -1080,8 +1134,11 @@ MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(stats, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(stats, "Enables statistics or not");
module_param(vendor, ushort, 0);
MODULE_PARM_DESC(vendor, "User specified vendor ID");
module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified product ID");
......@@ -175,7 +175,7 @@ static int queuecommand(struct scsi_cmnd *srb,
US_DEBUGP("%s called\n", __FUNCTION__);
srb->host_scribble = (unsigned char *)us;
/* enqueue the command */
/* check for state-transition errors */
if (us->sm_state != US_STATE_IDLE || us->srb != NULL) {
printk(KERN_ERR USB_STORAGE "Error in %s: "
"state = %d, us->srb = %p\n",
......@@ -183,10 +183,17 @@ static int queuecommand(struct scsi_cmnd *srb,
return SCSI_MLQUEUE_HOST_BUSY;
}
/* fail the command if we are disconnecting */
if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
US_DEBUGP("Fail command during disconnect\n");
srb->result = DID_NO_CONNECT << 16;
done(srb);
return 0;
}
/* enqueue the command and wake up the control thread */
srb->scsi_done = done;
us->srb = srb;
/* wake up the process task */
up(&(us->sema));
return 0;
......
......@@ -193,6 +193,7 @@ static inline void proc_net_remove(const char *name)
#define proc_root_driver NULL
#define proc_net NULL
#define proc_bus NULL
#define proc_net_fops_create(name, mode, fops) ({ (void)(mode), NULL; })
#define proc_net_create(name, mode, info) ({ (void)(mode), NULL; })
......
......@@ -38,5 +38,7 @@
#define IOCTL_TIUSB_TIMEOUT _IOW('N', 0x20, int) /* set timeout */
#define IOCTL_TIUSB_RESET_DEVICE _IOW('N', 0x21, int) /* reset device */
#define IOCTL_TIUSB_RESET_PIPES _IOW('N', 0x22, int) /* reset both pipes*/
#define IOCTL_TIUSB_GET_MAXPS _IOR('N', 0x23, int) /* max packet size */
#define IOCTL_TIUSB_GET_DEVID _IOR('N', 0x24, int) /* get device type */
#endif /* TICABLE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment