Commit 5e5495dd authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.6

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